Indexing.cpp revision 9af20d8187384b841a6244ab81c8a57b010d72d0
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;
222838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    llvm::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
256dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
257dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis                          SrcMgr::CharacteristicKind FileType, FileID PrevFID) {
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
2704e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  virtual void InclusionDirective(SourceLocation HashLoc,
2714e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                  const Token &IncludeTok,
2724e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                  StringRef FileName,
2734e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                  bool IsAngled,
274da313592441db36cf4b06be97c4bcc238ee6fa9cArgyrios Kyrtzidis                                  CharSourceRange FilenameRange,
2754e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                  const FileEntry *File,
2764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                  StringRef SearchPath,
277f8afcffe6a0213760b64c211812b1750e1e1e967Argyrios Kyrtzidis                                  StringRef RelativePath,
278f8afcffe6a0213760b64c211812b1750e1e1e967Argyrios Kyrtzidis                                  const Module *Imported) {
2794e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    bool isImport = (IncludeTok.is(tok::identifier) &&
2804e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis            IncludeTok.getIdentifierInfo()->getPPKeywordID() == tok::pp_import);
2818d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis    IndexCtx.ppIncludedFile(HashLoc, FileName, File, isImport, IsAngled,
2828d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis                            Imported);
2834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
2844e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
2854e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// MacroDefined - This hook is called whenever a macro definition is seen.
286c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis  virtual void MacroDefined(const Token &Id, const MacroDirective *MD) {
2874e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
2884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
2894e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// MacroUndefined - This hook is called whenever a macro #undef is seen.
2904e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// MI is released immediately following this callback.
291c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis  virtual void MacroUndefined(const Token &MacroNameTok,
292c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis                              const MacroDirective *MD) {
2934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
2944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
2954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// MacroExpands - This is called by when a macro invocation is found.
296c515978bd3a703aa733f846a0094ffa84d149074Argyrios Kyrtzidis  virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
297dd08a0c178329ec16cb9e494e6880f3991708b93Argyrios Kyrtzidis                            SourceRange Range, const MacroArgs *Args) {
2984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
299838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
3004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// SourceRangeSkipped - This hook is called when a source range is skipped.
3014e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// \param Range The SourceRange that was skipped. The range begins at the
3024e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// #if/#else directive and ends after the #endif/#else directive.
3034e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  virtual void SourceRangeSkipped(SourceRange Range) {
3044e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
3054e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
3064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
3084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// IndexingConsumer
3094e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
3104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3114e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisclass IndexingConsumer : public ASTConsumer {
3124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext &IndexCtx;
313838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  TUSkipBodyControl *SKCtrl;
3144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidispublic:
316838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  IndexingConsumer(IndexingContext &indexCtx, TUSkipBodyControl *skCtrl)
317838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    : IndexCtx(indexCtx), SKCtrl(skCtrl) { }
3184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // ASTConsumer Implementation
3204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  virtual void Initialize(ASTContext &Context) {
3224e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.setASTContext(Context);
3236ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis    IndexCtx.startedTranslationUnit();
3244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
3254e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3264e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  virtual void HandleTranslationUnit(ASTContext &Ctx) {
327838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (SKCtrl)
328838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      SKCtrl->finished();
3294e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
3304e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
33188c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis  virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
3324e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.indexDeclGroupRef(DG);
33388c2596edc8eb475e20f6033de1ea01669695a0cArgyrios Kyrtzidis    return !IndexCtx.shouldAbort();
3344e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
3354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3364e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// \brief Handle the specified top-level declaration that occurred inside
3374e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// and ObjC container.
3384e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
3394e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    // They will be handled after the interface is seen first.
3404e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.addTUDeclInObjCContainer(D);
3414e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
3424e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3434e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// \brief This is called by the AST reader when deserializing things.
3444e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// The default implementation forwards to HandleTopLevelDecl but we don't
3454e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  /// care about them when indexing, so have an empty definition.
3464e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  virtual void HandleInterestingDecl(DeclGroupRef D) {}
3476d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis
3486d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis  virtual void HandleTagDeclDefinition(TagDecl *D) {
34958d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis    if (!IndexCtx.shouldIndexImplicitTemplateInsts())
35058d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      return;
35158d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis
3526d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis    if (IndexCtx.isTemplateImplicitInstantiation(D))
3536d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis      IndexCtx.indexDecl(D);
3546d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis  }
3556d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis
3566d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis  virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {
35758d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis    if (!IndexCtx.shouldIndexImplicitTemplateInsts())
35858d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      return;
35958d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis
3606d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis    IndexCtx.indexDecl(D);
3616d968363877388f0a0268711d59367907b465ae1Argyrios Kyrtzidis  }
362838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
363838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  virtual bool shouldSkipFunctionBody(Decl *D) {
364838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (!SKCtrl) {
365838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      // Always skip bodies.
366838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return true;
367838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    }
368838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
369838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    const SourceManager &SM = IndexCtx.getASTContext().getSourceManager();
370838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    SourceLocation Loc = D->getLocation();
371838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (Loc.isMacroID())
372838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return false;
373838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (SM.isInSystemHeader(Loc))
374838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return true; // always skip bodies from system headers.
375838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
376838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    FileID FID;
377838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    unsigned Offset;
378838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    llvm::tie(FID, Offset) = SM.getDecomposedLoc(Loc);
379838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    // Don't skip bodies from main files; this may be revisited.
380838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (SM.getMainFileID() == FID)
381838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return false;
382838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    const FileEntry *FE = SM.getFileEntryForID(FID);
383838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (!FE)
384838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      return false;
385838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
386838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    return SKCtrl->isParsed(Loc, FID, FE);
387838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  }
3884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
3894e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3904e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
391b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis// CaptureDiagnosticConsumer
3924e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
3934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisclass CaptureDiagnosticConsumer : public DiagnosticConsumer {
3954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  SmallVector<StoredDiagnostic, 4> Errors;
3964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidispublic:
3974e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
3984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
3994e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                const Diagnostic &Info) {
4004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    if (level >= DiagnosticsEngine::Error)
4014e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      Errors.push_back(StoredDiagnostic(level, Info));
4024e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
4034e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
4044e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
4054e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
4064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// IndexingFrontendAction
4074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
4084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
4094e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisclass IndexingFrontendAction : public ASTFrontendAction {
4104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext IndexCtx;
411996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  CXTranslationUnit CXTU;
4124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
413838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  SessionSkipBodyData *SKData;
414838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  OwningPtr<TUSkipBodyControl> SKCtrl;
415838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
4164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidispublic:
4174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingFrontendAction(CXClientData clientData,
4184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                         IndexerCallbacks &indexCallbacks,
4194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                         unsigned indexOptions,
420838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis                         CXTranslationUnit cxTU,
421838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis                         SessionSkipBodyData *skData)
422996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis    : IndexCtx(clientData, indexCallbacks, indexOptions, cxTU),
423838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      CXTU(cxTU), SKData(skData) { }
4244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
4254e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
4264e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                         StringRef InFile) {
4273da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
4283da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis
4293da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    if (!PPOpts.ImplicitPCHInclude.empty()) {
4303da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis      IndexCtx.importedPCH(
4313da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis                        CI.getFileManager().getFile(PPOpts.ImplicitPCHInclude));
4323da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    }
4333fe97781ad5f31dbfd9348c9488b93a7c01d7818Argyrios Kyrtzidis
4344e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexCtx.setASTContext(CI.getASTContext());
4354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    Preprocessor &PP = CI.getPreprocessor();
4364e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    PP.addPPCallbacks(new IndexPPCallbacks(PP, IndexCtx));
4377fe90f3bfa6bd7f779ecfd4ba201a296a3a1c8cbArgyrios Kyrtzidis    IndexCtx.setPreprocessor(PP);
438838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
439838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    if (SKData) {
440838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      PPConditionalDirectiveRecord *
441838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis        PPRec = new PPConditionalDirectiveRecord(PP.getSourceManager());
442838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      PP.addPPCallbacks(PPRec);
443838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      SKCtrl.reset(new TUSkipBodyControl(*SKData, *PPRec, PP));
444838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    }
445838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
446838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    return new IndexingConsumer(IndexCtx, SKCtrl.get());
4474e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
4484e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
449996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  virtual void EndSourceFileAction() {
450996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis    indexDiagnostics(CXTU, IndexCtx);
451996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  }
452996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis
45358d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis  virtual TranslationUnitKind getTranslationUnitKind() {
45458d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis    if (IndexCtx.shouldIndexImplicitTemplateInsts())
45558d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      return TU_Complete;
45658d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis    else
45758d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis      return TU_Prefix;
45858d2dbea680a75de266c5eff77cc15c323cfd48aArgyrios Kyrtzidis  }
4594e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  virtual bool hasCodeCompletionSupport() const { return false; }
4604e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
4614e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
4624e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
46321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis// clang_indexSourceFileUnit Implementation
4644e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
4654e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
466838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidisstruct IndexSessionData {
467838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  CXIndex CIdx;
468838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  OwningPtr<SessionSkipBodyData> SkipBodyData;
469838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
470838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  explicit IndexSessionData(CXIndex cIdx)
471838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    : CIdx(cIdx), SkipBodyData(new SessionSkipBodyData) {}
472838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis};
473838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
47421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstruct IndexSourceFileInfo {
4752957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  CXIndexAction idxAction;
4764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  CXClientData client_data;
4774e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexerCallbacks *index_callbacks;
4784e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned index_callbacks_size;
4794e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned index_options;
4804e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const char *source_filename;
4814e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const char *const *command_line_args;
4824e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  int num_command_line_args;
4834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  struct CXUnsavedFile *unsaved_files;
4844e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned num_unsaved_files;
4854e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  CXTranslationUnit *out_TU;
4864e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned TU_options;
4874e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  int result;
4884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
4894e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
4904e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisstruct MemBufferOwner {
4914e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  SmallVector<const llvm::MemoryBuffer *, 8> Buffers;
4924e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
4934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  ~MemBufferOwner() {
4944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    for (SmallVectorImpl<const llvm::MemoryBuffer *>::iterator
4954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis           I = Buffers.begin(), E = Buffers.end(); I != E; ++I)
4964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      delete *I;
4974e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
4984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis};
4994e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} // anonymous namespace
5014e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
50221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstatic void clang_indexSourceFile_Impl(void *UserData) {
50321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexSourceFileInfo *ITUI =
50421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    static_cast<IndexSourceFileInfo*>(UserData);
505838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  CXIndexAction cxIdxAction = ITUI->idxAction;
5064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  CXClientData client_data = ITUI->client_data;
5074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
5084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned index_callbacks_size = ITUI->index_callbacks_size;
5094e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned index_options = ITUI->index_options;
5104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const char *source_filename = ITUI->source_filename;
5114e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  const char * const *command_line_args = ITUI->command_line_args;
5124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  int num_command_line_args = ITUI->num_command_line_args;
5134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  struct CXUnsavedFile *unsaved_files = ITUI->unsaved_files;
5144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned num_unsaved_files = ITUI->num_unsaved_files;
5154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  CXTranslationUnit *out_TU  = ITUI->out_TU;
5164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned TU_options = ITUI->TU_options;
5174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  ITUI->result = 1; // init as error.
5184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (out_TU)
5204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    *out_TU = 0;
5214e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  bool requestedToGetTU = (out_TU != 0);
5224e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
523838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  if (!cxIdxAction)
5244e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
5254e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (!client_index_callbacks || index_callbacks_size == 0)
5264e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
5274e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5284e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexerCallbacks CB;
5294e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  memset(&CB, 0, sizeof(CB));
5304e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  unsigned ClientCBSize = index_callbacks_size < sizeof(CB)
5314e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                  ? index_callbacks_size : sizeof(CB);
5324e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  memcpy(&CB, client_index_callbacks, ClientCBSize);
5334e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
534838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  IndexSessionData *IdxSession = static_cast<IndexSessionData *>(cxIdxAction);
535838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  CIndexer *CXXIdx = static_cast<CIndexer *>(IdxSession->CIdx);
5364e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
537fdc1795acc9d5d73a767cc7d43ad1546e93adbbaArgyrios Kyrtzidis  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
53881b5ac39a97cde1a54b8d0eb7105290c40eb84d7Argyrios Kyrtzidis    setThreadBackgroundPriority();
539fdc1795acc9d5d73a767cc7d43ad1546e93adbbaArgyrios Kyrtzidis
540c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis  bool CaptureDiagnostics = !Logger::isLoggingEnabled();
541c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis
542c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis  CaptureDiagnosticConsumer *CaptureDiag = 0;
543c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis  if (CaptureDiagnostics)
544c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis    CaptureDiag = new CaptureDiagnosticConsumer();
5454e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5464e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Configure the diagnostics.
547c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<DiagnosticsEngine>
54802c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor    Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions,
54902c23ebf41ae2f70da0ba7337e05c51fbfe35f7fDouglas Gregor                                              CaptureDiag,
550cc2b653c319599f502425d2c3de29865d47bb9e4Douglas Gregor                                              /*ShouldOwnClient=*/true));
5514e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5524e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this function.
5534e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
5544e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
5554e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    DiagCleanup(Diags.getPtr());
5564e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5571e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith  OwningPtr<std::vector<const char *> >
5584e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    Args(new std::vector<const char*>());
5594e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5604e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
5614e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
5624e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    ArgsCleanup(Args.get());
5634e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5644e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  Args->insert(Args->end(), command_line_args,
5654e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis               command_line_args + num_command_line_args);
5664e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5674e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // The 'source_filename' argument is optional.  If the caller does not
5684e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // specify it then it is assumed that the source file is specified
5694e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // in the actual argument list.
5704e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Put the source file after command_line_args otherwise if '-x' flag is
5714e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // present it will be unused.
5724e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (source_filename)
5734e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    Args->push_back(source_filename);
5744e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
575c93dc7889644293e318e19d82830ea2acc45b678Dylan Noblesmith  IntrusiveRefCntPtr<CompilerInvocation>
5764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    CInvok(createInvocationFromCommandLine(*Args, Diags));
5774e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5784e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (!CInvok)
5794e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
5804e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5814e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this function.
5824e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<CompilerInvocation,
5834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    llvm::CrashRecoveryContextReleaseRefCleanup<CompilerInvocation> >
5844e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    CInvokCleanup(CInvok.getPtr());
5854e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5864e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (CInvok->getFrontendOpts().Inputs.empty())
5874e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
5884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5891e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith  OwningPtr<MemBufferOwner> BufOwner(new MemBufferOwner());
5904e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5914e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
5924e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<MemBufferOwner>
5934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    BufOwnerCleanup(BufOwner.get());
5944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
5954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  for (unsigned I = 0; I != num_unsaved_files; ++I) {
5964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
5974e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    const llvm::MemoryBuffer *Buffer
5984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
5994e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    CInvok->getPreprocessorOpts().addRemappedFile(unsaved_files[I].Filename, Buffer);
6004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    BufOwner->Buffers.push_back(Buffer);
6014e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
6024e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6034e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Since libclang is primarily used by batch tools dealing with
6044e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // (often very broken) source code, where spell-checking can have a
6054e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // significant negative impact on performance (particularly when
6064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // precompiled headers are involved), we disable it.
607d3b74d9ca4f239a7a90ad193378c494306c57352Ted Kremenek  CInvok->getLangOpts()->SpellChecking = false;
6084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
609b49a29f7e4413a7a014a2b28c5c25fe54e005cf3Argyrios Kyrtzidis  if (index_options & CXIndexOpt_SuppressWarnings)
610b49a29f7e4413a7a014a2b28c5c25fe54e005cf3Argyrios Kyrtzidis    CInvok->getDiagnosticOpts().IgnoreWarnings = true;
611b49a29f7e4413a7a014a2b28c5c25fe54e005cf3Argyrios Kyrtzidis
612991bf49f68e8caeb900dd9738712b861073363d9Argyrios Kyrtzidis  ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags,
613c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis                                  CaptureDiagnostics,
614ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                  /*UserFilesAreVolatile=*/true);
615fdc1795acc9d5d73a767cc7d43ad1546e93adbbaArgyrios Kyrtzidis  OwningPtr<CXTUOwner> CXTU(new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
6164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
6184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<CXTUOwner>
6194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    CXTUCleanup(CXTU.get());
6204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
621838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  // Enable the skip-parsed-bodies optimization only for C++; this may be
622838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  // revisited.
623838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  bool SkipBodies = (index_options & CXIndexOpt_SkipParsedBodiesInSession) &&
624838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis      CInvok->getLangOpts()->CPlusPlus;
625838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  if (SkipBodies)
626838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    CInvok->getFrontendOpts().SkipFunctionBodies = true;
627838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis
6281e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith  OwningPtr<IndexingFrontendAction> IndexAction;
6294e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexAction.reset(new IndexingFrontendAction(client_data, CB,
630838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis                                               index_options, CXTU->getTU(),
631838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis                              SkipBodies ? IdxSession->SkipBodyData.get() : 0));
6324e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6334e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
6344e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<IndexingFrontendAction>
6354e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    IndexActionCleanup(IndexAction.get());
6364e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6376f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  bool Persistent = requestedToGetTU;
6386f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  bool OnlyLocalDecls = false;
6396f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  bool PrecompilePreamble = false;
6406f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  bool CacheCodeCompletionResults = false;
6416f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
642bef35c91b594f66216f4aab303b71a6c5ab7abcfArgyrios Kyrtzidis  PPOpts.AllowPCHWithCompilerErrors = true;
6436f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis
6446f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  if (requestedToGetTU) {
6456f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    OnlyLocalDecls = CXXIdx->getOnlyLocalDecls();
6466f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    PrecompilePreamble = TU_options & CXTranslationUnit_PrecompiledPreamble;
6476f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    // FIXME: Add a flag for modules.
6486f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis    CacheCodeCompletionResults
6496f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis      = TU_options & CXTranslationUnit_CacheCompletionResults;
6506f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis  }
6516f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis
65253d6ded0edb70b04430cdaf7d02602799b4d4b07Argyrios Kyrtzidis  if (TU_options & CXTranslationUnit_DetailedPreprocessingRecord) {
65353d6ded0edb70b04430cdaf7d02602799b4d4b07Argyrios Kyrtzidis    PPOpts.DetailedRecord = true;
65453d6ded0edb70b04430cdaf7d02602799b4d4b07Argyrios Kyrtzidis  }
6553fe97781ad5f31dbfd9348c9488b93a7c01d7818Argyrios Kyrtzidis
65693cd6e8e17a40ee6fe1f17ab74d841e1f4fe9351Argyrios Kyrtzidis  if (!requestedToGetTU && !CInvok->getLangOpts()->Modules)
65793cd6e8e17a40ee6fe1f17ab74d841e1f4fe9351Argyrios Kyrtzidis    PPOpts.DetailedRecord = false;
65893cd6e8e17a40ee6fe1f17ab74d841e1f4fe9351Argyrios Kyrtzidis
659e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  DiagnosticErrorTrap DiagTrap(*Diags);
660e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.getPtr(), Diags,
6614e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                                       IndexAction.get(),
6626f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                                       Unit,
6636f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                                       Persistent,
6643791814b2c5efb3986ec4dd40c75c9d28f325222Argyrios Kyrtzidis                                                CXXIdx->getClangResourcesPath(),
6656f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                                       OnlyLocalDecls,
666c58b75628c3860775fc3914aa6d08e84de82233fArgyrios Kyrtzidis                                                       CaptureDiagnostics,
6676f3ce979a7748fd117e6473d6272b16d643b6262Argyrios Kyrtzidis                                                       PrecompilePreamble,
668ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                                    CacheCodeCompletionResults,
669ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                 /*IncludeBriefCommentsInCodeCompletion=*/false,
670ff398965a5abfaf5bc47bc022876f56a28e5b9a7Argyrios Kyrtzidis                                                 /*UserFilesAreVolatile=*/true);
671e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())
672e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis    printDiagsToStderr(Unit);
673e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis
674e722ed6f5464232e23be52f4976312ef526fae99Argyrios Kyrtzidis  if (!Success)
6754e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
6764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6774e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (out_TU)
6784e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    *out_TU = CXTU->takeTU();
6794e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6804e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  ITUI->result = 0; // success.
6814e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
6824e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
6834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
68421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis// clang_indexTranslationUnit Implementation
68521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
68621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
68721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisnamespace {
68821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
68921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstruct IndexTranslationUnitInfo {
6902957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  CXIndexAction idxAction;
69121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  CXClientData client_data;
69221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexerCallbacks *index_callbacks;
69321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  unsigned index_callbacks_size;
69421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  unsigned index_options;
6952957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  CXTranslationUnit TU;
69621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  int result;
69721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis};
69821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
69921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis} // anonymous namespace
70021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
70121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstatic void indexPreprocessingRecord(ASTUnit &Unit, IndexingContext &IdxCtx) {
70221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  Preprocessor &PP = Unit.getPreprocessor();
70321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (!PP.getPreprocessingRecord())
70421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return;
70521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
70621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  // FIXME: Only deserialize inclusion directives.
70721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
70821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  PreprocessingRecord::iterator I, E;
709632dcc92f60ab7f806a89c5bca3a0951763a9219Argyrios Kyrtzidis  llvm::tie(I, E) = Unit.getLocalPreprocessingEntities();
71021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
71162288edde26ff4af9fc079c979a0e1bdc577ce9dArgyrios Kyrtzidis  bool isModuleFile = Unit.isModuleFile();
71221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  for (; I != E; ++I) {
71321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    PreprocessedEntity *PPE = *I;
71421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
71521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
7168d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis      SourceLocation Loc = ID->getSourceRange().getBegin();
7178d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis      // Modules have synthetic main files as input, give an invalid location
7188d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis      // if the location points to such a file.
7198d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis      if (isModuleFile && Unit.isInMainFileID(Loc))
7208d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis        Loc = SourceLocation();
7218d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis      IdxCtx.ppIncludedFile(Loc, ID->getFileName(),
7228d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis                            ID->getFile(),
7238d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis                            ID->getKind() == InclusionDirective::Import,
7248d7a24e94b58676e57fd3f47353cbdbc59917d81Argyrios Kyrtzidis                            !ID->wasInQuotes(), ID->importedModule());
72521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    }
72621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  }
72721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis}
72821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
72995c579cae01118eadd311d445ff7f491d0011fb0Argyrios Kyrtzidisstatic bool topLevelDeclVisitor(void *context, const Decl *D) {
7302093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  IndexingContext &IdxCtx = *static_cast<IndexingContext*>(context);
7312093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  IdxCtx.indexTopLevelDecl(D);
7322093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  if (IdxCtx.shouldAbort())
7332093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis    return false;
7342093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis  return true;
7352093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidis}
73621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
7372093e0bc4e436b1b2791d5423fb3274dd37231b8Argyrios Kyrtzidisstatic void indexTranslationUnit(ASTUnit &Unit, IndexingContext &IdxCtx) {
73895c579cae01118eadd311d445ff7f491d0011fb0Argyrios Kyrtzidis  Unit.visitLocalTopLevelDecls(&IdxCtx, topLevelDeclVisitor);
73921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis}
74021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
74121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstatic void indexDiagnostics(CXTranslationUnit TU, IndexingContext &IdxCtx) {
742996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  if (!IdxCtx.hasDiagnosticCallback())
743996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis    return;
744996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis
745996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  CXDiagnosticSetImpl *DiagSet = cxdiag::lazyCreateDiags(TU);
746996e6e564af7483e2d5e0b70df5fdb9f79ec4b5aArgyrios Kyrtzidis  IdxCtx.handleDiagnosticSet(DiagSet);
74721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis}
74821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
74921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidisstatic void clang_indexTranslationUnit_Impl(void *UserData) {
75021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexTranslationUnitInfo *ITUI =
75121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    static_cast<IndexTranslationUnitInfo*>(UserData);
75221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  CXTranslationUnit TU = ITUI->TU;
75321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  CXClientData client_data = ITUI->client_data;
75421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexerCallbacks *client_index_callbacks = ITUI->index_callbacks;
75521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  unsigned index_callbacks_size = ITUI->index_callbacks_size;
75621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  unsigned index_options = ITUI->index_options;
75721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  ITUI->result = 1; // init as error.
75821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
75921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (!TU)
76021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return;
76121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (!client_index_callbacks || index_callbacks_size == 0)
76221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return;
76321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
7648c718e7d87018919b5b84b0d545fe477b2d532d1Dmitri Gribenko  CIndexer *CXXIdx = TU->CIdx;
765fdc1795acc9d5d73a767cc7d43ad1546e93adbbaArgyrios Kyrtzidis  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
76681b5ac39a97cde1a54b8d0eb7105290c40eb84d7Argyrios Kyrtzidis    setThreadBackgroundPriority();
767fdc1795acc9d5d73a767cc7d43ad1546e93adbbaArgyrios Kyrtzidis
76821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexerCallbacks CB;
76921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  memset(&CB, 0, sizeof(CB));
77021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  unsigned ClientCBSize = index_callbacks_size < sizeof(CB)
77121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis                                  ? index_callbacks_size : sizeof(CB);
77221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  memcpy(&CB, client_index_callbacks, ClientCBSize);
77321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
7741e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith  OwningPtr<IndexingContext> IndexCtx;
77521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexCtx.reset(new IndexingContext(client_data, CB, index_options, TU));
77621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
77721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
77821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<IndexingContext>
77921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    IndexCtxCleanup(IndexCtx.get());
78021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
7811e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith  OwningPtr<IndexingConsumer> IndexConsumer;
782838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  IndexConsumer.reset(new IndexingConsumer(*IndexCtx, 0));
78321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
78421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  // Recover resources if we crash before exiting this method.
78521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  llvm::CrashRecoveryContextCleanupRegistrar<IndexingConsumer>
78621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    IndexConsumerCleanup(IndexConsumer.get());
78721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
7885694feb5ccd6eb862cb600b55753cecc13794471Dmitri Gribenko  ASTUnit *Unit = cxtu::getASTUnit(TU);
78921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (!Unit)
79021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return;
79121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
792162884d7063646224d1b0759b6568aaf1d8935b6Argyrios Kyrtzidis  ASTUnit::ConcurrencyCheck Check(*Unit);
793162884d7063646224d1b0759b6568aaf1d8935b6Argyrios Kyrtzidis
7943da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis  if (const FileEntry *PCHFile = Unit->getPCHFile())
7953da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis    IndexCtx->importedPCH(PCHFile);
7963da76bfbd24b2747ceb72d1918bbbe3123dac841Argyrios Kyrtzidis
79721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  FileManager &FileMgr = Unit->getFileManager();
79821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
79921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (Unit->getOriginalSourceFileName().empty())
80021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    IndexCtx->enteredMainFile(0);
80121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  else
80221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    IndexCtx->enteredMainFile(FileMgr.getFile(Unit->getOriginalSourceFileName()));
80321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
80421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  IndexConsumer->Initialize(Unit->getASTContext());
80521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
80621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  indexPreprocessingRecord(*Unit, *IndexCtx);
80721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  indexTranslationUnit(*Unit, *IndexCtx);
80821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  indexDiagnostics(TU, *IndexCtx);
80921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
81021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  ITUI->result = 0;
81121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis}
81221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
81321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
8144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis// libclang public APIs.
8154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis//===----------------------------------------------------------------------===//
8164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
8174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisextern "C" {
8184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
8196ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidisint clang_index_isEntityObjCContainerKind(CXIdxEntityKind K) {
8206ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis  return CXIdxEntity_ObjCClass <= K && K <= CXIdxEntity_ObjCCategory;
821dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis}
822dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
8236ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidisconst CXIdxObjCContainerDeclInfo *
8246ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidisclang_index_getObjCContainerDeclInfo(const CXIdxDeclInfo *DInfo) {
8256ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis  if (!DInfo)
8266ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis    return 0;
8276ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis
828c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
829c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (const ObjCContainerDeclInfo *
830c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis        ContInfo = dyn_cast<ObjCContainerDeclInfo>(DI))
831c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis    return &ContInfo->ObjCContDeclInfo;
832dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
833dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis  return 0;
834dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis}
835dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
8366ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidisconst CXIdxObjCInterfaceDeclInfo *
8376ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidisclang_index_getObjCInterfaceDeclInfo(const CXIdxDeclInfo *DInfo) {
838c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (!DInfo)
8396ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis    return 0;
840dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
841c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
842c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (const ObjCInterfaceDeclInfo *
843c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis        InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI))
844c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis    return &InterInfo->ObjCInterDeclInfo;
845dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
846dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis  return 0;
847dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis}
848dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
849c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidisconst CXIdxObjCCategoryDeclInfo *
850c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidisclang_index_getObjCCategoryDeclInfo(const CXIdxDeclInfo *DInfo){
851c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (!DInfo)
8526ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis    return 0;
853dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
854c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
855c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (const ObjCCategoryDeclInfo *
856c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis        CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
857c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis    return &CatInfo->ObjCCatDeclInfo;
858dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
859dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis  return 0;
860dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis}
861dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis
862c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidisconst CXIdxObjCProtocolRefListInfo *
863c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidisclang_index_getObjCProtocolRefListInfo(const CXIdxDeclInfo *DInfo) {
864c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (!DInfo)
8656ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis    return 0;
8666ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis
867c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
868c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis
869c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (const ObjCInterfaceDeclInfo *
870c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis        InterInfo = dyn_cast<ObjCInterfaceDeclInfo>(DI))
871c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis    return InterInfo->ObjCInterDeclInfo.protocols;
872c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis
873c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  if (const ObjCProtocolDeclInfo *
874c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis        ProtInfo = dyn_cast<ObjCProtocolDeclInfo>(DI))
875c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis    return &ProtInfo->ObjCProtoRefListInfo;
876c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis
877c10a4c8baff3164bee9b7fc293679a5a5a90eb74Argyrios Kyrtzidis  if (const ObjCCategoryDeclInfo *CatInfo = dyn_cast<ObjCCategoryDeclInfo>(DI))
878c10a4c8baff3164bee9b7fc293679a5a5a90eb74Argyrios Kyrtzidis    return CatInfo->ObjCCatDeclInfo.protocols;
879c10a4c8baff3164bee9b7fc293679a5a5a90eb74Argyrios Kyrtzidis
880c71d55469e7d5f7b376a30620617a175a9442da9Argyrios Kyrtzidis  return 0;
8816ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis}
8826ec43adc39006a7fce94188956d0239bd54c0363Argyrios Kyrtzidis
883792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidisconst CXIdxObjCPropertyDeclInfo *
884792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidisclang_index_getObjCPropertyDeclInfo(const CXIdxDeclInfo *DInfo) {
885792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis  if (!DInfo)
886792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis    return 0;
887792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis
888792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
889792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis  if (const ObjCPropertyDeclInfo *PropInfo = dyn_cast<ObjCPropertyDeclInfo>(DI))
890792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis    return &PropInfo->ObjCPropDeclInfo;
891792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis
892792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis  return 0;
893792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis}
894792db266f3d2f12a7a16bf37d90074f54bca1e6fArgyrios Kyrtzidis
895b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidisconst CXIdxIBOutletCollectionAttrInfo *
896b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidisclang_index_getIBOutletCollectionAttrInfo(const CXIdxAttrInfo *AInfo) {
897b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis  if (!AInfo)
898b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis    return 0;
899b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis
900b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis  const AttrInfo *DI = static_cast<const AttrInfo *>(AInfo);
901b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis  if (const IBOutletCollectionInfo *
902b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis        IBInfo = dyn_cast<IBOutletCollectionInfo>(DI))
903b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis    return &IBInfo->IBCollInfo;
904b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis
905b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis  return 0;
906b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis}
907b395c63b473bf1b3783bff371a993332e8c4c5e3Argyrios Kyrtzidis
9082957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisconst CXIdxCXXClassDeclInfo *
9092957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisclang_index_getCXXClassDeclInfo(const CXIdxDeclInfo *DInfo) {
9102957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (!DInfo)
9112957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis    return 0;
9122957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9132957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  const DeclInfo *DI = static_cast<const DeclInfo *>(DInfo);
9142957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (const CXXClassDeclInfo *ClassInfo = dyn_cast<CXXClassDeclInfo>(DI))
9152957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis    return &ClassInfo->CXXClassInfo;
9162957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9172957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  return 0;
9182957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9192957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9202957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios KyrtzidisCXIdxClientContainer
9212957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisclang_index_getClientContainer(const CXIdxContainerInfo *info) {
9222957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (!info)
9232957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis    return 0;
9243267e11b4bf4eb844cabf57e58ae9de8f37b5c9aBenjamin Kramer  const ContainerInfo *Container = static_cast<const ContainerInfo *>(info);
9252957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  return Container->IndexCtx->getClientContainerForDC(Container->DC);
9262957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9272957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9282957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisvoid clang_index_setClientContainer(const CXIdxContainerInfo *info,
9292957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                                    CXIdxClientContainer client) {
9302957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (!info)
9312957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis    return;
9323267e11b4bf4eb844cabf57e58ae9de8f37b5c9aBenjamin Kramer  const ContainerInfo *Container = static_cast<const ContainerInfo *>(info);
9332957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  Container->IndexCtx->addContainerInMap(Container->DC, client);
9342957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9352957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9362957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios KyrtzidisCXIdxClientEntity clang_index_getClientEntity(const CXIdxEntityInfo *info) {
9372957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (!info)
9382957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis    return 0;
9393267e11b4bf4eb844cabf57e58ae9de8f37b5c9aBenjamin Kramer  const EntityInfo *Entity = static_cast<const EntityInfo *>(info);
9402957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  return Entity->IndexCtx->getClientEntity(Entity->Dcl);
9412957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9422957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9432957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisvoid clang_index_setClientEntity(const CXIdxEntityInfo *info,
9442957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                                 CXIdxClientEntity client) {
9452957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  if (!info)
9462957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis    return;
9473267e11b4bf4eb844cabf57e58ae9de8f37b5c9aBenjamin Kramer  const EntityInfo *Entity = static_cast<const EntityInfo *>(info);
9482957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  Entity->IndexCtx->setClientEntity(Entity->Dcl, client);
9492957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9502957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9512957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios KyrtzidisCXIndexAction clang_IndexAction_create(CXIndex CIdx) {
952838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  return new IndexSessionData(CIdx);
9532957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9542957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9552957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisvoid clang_IndexAction_dispose(CXIndexAction idxAction) {
956838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis  if (idxAction)
957838eb7e8652e451d93494a4e583e4d11809bcb4aArgyrios Kyrtzidis    delete static_cast<IndexSessionData *>(idxAction);
9582957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis}
9592957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9602957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisint clang_indexSourceFile(CXIndexAction idxAction,
9612957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          CXClientData client_data,
9622957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          IndexerCallbacks *index_callbacks,
9632957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          unsigned index_callbacks_size,
9642957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          unsigned index_options,
9652957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          const char *source_filename,
9662957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          const char * const *command_line_args,
9672957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          int num_command_line_args,
9682957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          struct CXUnsavedFile *unsaved_files,
9692957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          unsigned num_unsaved_files,
9702957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          CXTranslationUnit *out_TU,
9712957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                          unsigned TU_options) {
972c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  LOG_FUNC_SECTION {
973c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis    *Log << source_filename << ": ";
974c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis    for (int i = 0; i != num_command_line_args; ++i)
975c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis      *Log << command_line_args[i] << " ";
976c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  }
9772957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis
9782957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  IndexSourceFileInfo ITUI = { idxAction, client_data, index_callbacks,
9792957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                               index_callbacks_size, index_options,
9802957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                               source_filename, command_line_args,
9812957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                               num_command_line_args, unsaved_files,
9822957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                               num_unsaved_files, out_TU, TU_options, 0 };
9834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
984e7de9b4a1f4a15620ab15bc8159018df7d54080aArgyrios Kyrtzidis  if (getenv("LIBCLANG_NOTHREADS")) {
98521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    clang_indexSourceFile_Impl(&ITUI);
9864e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return ITUI.result;
9874e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
9884e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
9894e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  llvm::CrashRecoveryContext CRC;
9904e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
99121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (!RunSafely(CRC, clang_indexSourceFile_Impl, &ITUI)) {
99221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    fprintf(stderr, "libclang: crash detected during indexing source file: {\n");
9934e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
9944e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "  'command_line_args' : [");
9954e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    for (int i = 0; i != num_command_line_args; ++i) {
9964e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      if (i)
9974e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        fprintf(stderr, ", ");
9984e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      fprintf(stderr, "'%s'", command_line_args[i]);
9994e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    }
10004e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "],\n");
10014e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "  'unsaved_files' : [");
10024e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    for (unsigned i = 0; i != num_unsaved_files; ++i) {
10034e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      if (i)
10044e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis        fprintf(stderr, ", ");
10054e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
10064e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis              unsaved_files[i].Length);
10074e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    }
10084e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "],\n");
10094e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "  'options' : %d,\n", TU_options);
10104e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    fprintf(stderr, "}\n");
10114e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10124e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return 1;
10134e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
10144e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    if (out_TU)
10154e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      PrintLibclangResourceUsage(*out_TU);
10164e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  }
10174e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10184e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  return ITUI.result;
10194e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
10204e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10212957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidisint clang_indexTranslationUnit(CXIndexAction idxAction,
102221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis                               CXClientData client_data,
102321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis                               IndexerCallbacks *index_callbacks,
102421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis                               unsigned index_callbacks_size,
10252957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                               unsigned index_options,
10262957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                               CXTranslationUnit TU) {
1027c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  LOG_FUNC_SECTION {
1028c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis    *Log << TU;
1029c6f5c6a58d34833d1fe458a518d5f59462926c7bArgyrios Kyrtzidis  }
103021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
10312957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis  IndexTranslationUnitInfo ITUI = { idxAction, client_data, index_callbacks,
10322957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                                    index_callbacks_size, index_options, TU,
10332957e6f8c4c2e58a4b9cb639949fea801970fe36Argyrios Kyrtzidis                                    0 };
103421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
103521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (getenv("LIBCLANG_NOTHREADS")) {
103621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    clang_indexTranslationUnit_Impl(&ITUI);
103721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return ITUI.result;
103821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  }
103921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
104021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  llvm::CrashRecoveryContext CRC;
104121ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
104221ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  if (!RunSafely(CRC, clang_indexTranslationUnit_Impl, &ITUI)) {
104321ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    fprintf(stderr, "libclang: crash detected during indexing TU\n");
104421ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
104521ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis    return 1;
104621ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  }
104721ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
104821ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis  return ITUI.result;
104921ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis}
105021ee5707e6e59d982d2f2ae28e079c7ff46dc519Argyrios Kyrtzidis
10514e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidisvoid clang_indexLoc_getFileLocation(CXIdxLoc location,
1052dd93c596cd95e1b96031ff47efe0a5095ff3d7f1Argyrios Kyrtzidis                                    CXIdxClientFile *indexFile,
10534e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                    CXFile *file,
10544e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                    unsigned *line,
10554e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                    unsigned *column,
10564e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis                                    unsigned *offset) {
10574e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (indexFile) *indexFile = 0;
10584e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (file)   *file = 0;
10594e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (line)   *line = 0;
10604e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (column) *column = 0;
10614e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (offset) *offset = 0;
10624e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10634e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
10644e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (!location.ptr_data[0] || Loc.isInvalid())
10654e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return;
10664e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10674e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext &IndexCtx =
10684e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      *static_cast<IndexingContext*>(location.ptr_data[0]);
10694e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexCtx.translateLoc(Loc, indexFile, file, line, column, offset);
10704e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
10714e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10724e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios KyrtzidisCXSourceLocation clang_indexLoc_getCXSourceLocation(CXIdxLoc location) {
10734e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data);
10744e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  if (!location.ptr_data[0] || Loc.isInvalid())
10754e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis    return clang_getNullLocation();
10764e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10774e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  IndexingContext &IndexCtx =
10784e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis      *static_cast<IndexingContext*>(location.ptr_data[0]);
10794e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis  return cxloc::translateSourceLocation(IndexCtx.getASTContext(), Loc);
10804e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis}
10814e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
10824e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis} // end: extern "C"
10834e7064fa7e344e8f87a5b8457e96dfdd252c4a9eArgyrios Kyrtzidis
1084