xref: /minix3/external/bsd/llvm/dist/clang/tools/libclang/CIndex.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the main API hooks in the Clang-C Source Indexing
11f4a2713aSLionel Sambuc // library.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc 
15f4a2713aSLionel Sambuc #include "CIndexer.h"
16f4a2713aSLionel Sambuc #include "CIndexDiagnostic.h"
17f4a2713aSLionel Sambuc #include "CLog.h"
18f4a2713aSLionel Sambuc #include "CXCursor.h"
19f4a2713aSLionel Sambuc #include "CXSourceLocation.h"
20f4a2713aSLionel Sambuc #include "CXString.h"
21f4a2713aSLionel Sambuc #include "CXTranslationUnit.h"
22f4a2713aSLionel Sambuc #include "CXType.h"
23f4a2713aSLionel Sambuc #include "CursorVisitor.h"
24f4a2713aSLionel Sambuc #include "clang/AST/Attr.h"
25*0a6a1f1dSLionel Sambuc #include "clang/AST/Mangle.h"
26f4a2713aSLionel Sambuc #include "clang/AST/StmtVisitor.h"
27f4a2713aSLionel Sambuc #include "clang/Basic/Diagnostic.h"
28*0a6a1f1dSLionel Sambuc #include "clang/Basic/DiagnosticCategories.h"
29*0a6a1f1dSLionel Sambuc #include "clang/Basic/DiagnosticIDs.h"
30*0a6a1f1dSLionel Sambuc #include "clang/Basic/TargetInfo.h"
31f4a2713aSLionel Sambuc #include "clang/Basic/Version.h"
32f4a2713aSLionel Sambuc #include "clang/Frontend/ASTUnit.h"
33f4a2713aSLionel Sambuc #include "clang/Frontend/CompilerInstance.h"
34f4a2713aSLionel Sambuc #include "clang/Frontend/FrontendDiagnostic.h"
35f4a2713aSLionel Sambuc #include "clang/Index/CommentToXML.h"
36f4a2713aSLionel Sambuc #include "clang/Lex/HeaderSearch.h"
37f4a2713aSLionel Sambuc #include "clang/Lex/Lexer.h"
38f4a2713aSLionel Sambuc #include "clang/Lex/PreprocessingRecord.h"
39f4a2713aSLionel Sambuc #include "clang/Lex/Preprocessor.h"
40*0a6a1f1dSLionel Sambuc #include "clang/Serialization/SerializationDiagnostic.h"
41f4a2713aSLionel Sambuc #include "llvm/ADT/Optional.h"
42f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
43f4a2713aSLionel Sambuc #include "llvm/ADT/StringSwitch.h"
44*0a6a1f1dSLionel Sambuc #include "llvm/Config/llvm-config.h"
45*0a6a1f1dSLionel Sambuc #include "llvm/IR/DataLayout.h"
46*0a6a1f1dSLionel Sambuc #include "llvm/IR/Mangler.h"
47f4a2713aSLionel Sambuc #include "llvm/Support/Compiler.h"
48f4a2713aSLionel Sambuc #include "llvm/Support/CrashRecoveryContext.h"
49f4a2713aSLionel Sambuc #include "llvm/Support/Format.h"
50*0a6a1f1dSLionel Sambuc #include "llvm/Support/ManagedStatic.h"
51f4a2713aSLionel Sambuc #include "llvm/Support/MemoryBuffer.h"
52f4a2713aSLionel Sambuc #include "llvm/Support/Mutex.h"
53f4a2713aSLionel Sambuc #include "llvm/Support/Program.h"
54f4a2713aSLionel Sambuc #include "llvm/Support/SaveAndRestore.h"
55f4a2713aSLionel Sambuc #include "llvm/Support/Signals.h"
56f4a2713aSLionel Sambuc #include "llvm/Support/Threading.h"
57f4a2713aSLionel Sambuc #include "llvm/Support/Timer.h"
58f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
59f4a2713aSLionel Sambuc 
60*0a6a1f1dSLionel Sambuc #if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61*0a6a1f1dSLionel Sambuc #define USE_DARWIN_THREADS
62*0a6a1f1dSLionel Sambuc #endif
63*0a6a1f1dSLionel Sambuc 
64*0a6a1f1dSLionel Sambuc #ifdef USE_DARWIN_THREADS
65f4a2713aSLionel Sambuc #include <pthread.h>
66f4a2713aSLionel Sambuc #endif
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc using namespace clang;
69f4a2713aSLionel Sambuc using namespace clang::cxcursor;
70f4a2713aSLionel Sambuc using namespace clang::cxtu;
71f4a2713aSLionel Sambuc using namespace clang::cxindex;
72f4a2713aSLionel Sambuc 
MakeCXTranslationUnit(CIndexer * CIdx,ASTUnit * AU)73f4a2713aSLionel Sambuc CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
74f4a2713aSLionel Sambuc   if (!AU)
75*0a6a1f1dSLionel Sambuc     return nullptr;
76*0a6a1f1dSLionel Sambuc   assert(CIdx);
77f4a2713aSLionel Sambuc   CXTranslationUnit D = new CXTranslationUnitImpl();
78f4a2713aSLionel Sambuc   D->CIdx = CIdx;
79f4a2713aSLionel Sambuc   D->TheASTUnit = AU;
80f4a2713aSLionel Sambuc   D->StringPool = new cxstring::CXStringPool();
81*0a6a1f1dSLionel Sambuc   D->Diagnostics = nullptr;
82f4a2713aSLionel Sambuc   D->OverridenCursorsPool = createOverridenCXCursorsPool();
83*0a6a1f1dSLionel Sambuc   D->CommentToXML = nullptr;
84f4a2713aSLionel Sambuc   return D;
85f4a2713aSLionel Sambuc }
86f4a2713aSLionel Sambuc 
isASTReadError(ASTUnit * AU)87*0a6a1f1dSLionel Sambuc bool cxtu::isASTReadError(ASTUnit *AU) {
88*0a6a1f1dSLionel Sambuc   for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
89*0a6a1f1dSLionel Sambuc                                      DEnd = AU->stored_diag_end();
90*0a6a1f1dSLionel Sambuc        D != DEnd; ++D) {
91*0a6a1f1dSLionel Sambuc     if (D->getLevel() >= DiagnosticsEngine::Error &&
92*0a6a1f1dSLionel Sambuc         DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
93*0a6a1f1dSLionel Sambuc             diag::DiagCat_AST_Deserialization_Issue)
94*0a6a1f1dSLionel Sambuc       return true;
95*0a6a1f1dSLionel Sambuc   }
96*0a6a1f1dSLionel Sambuc   return false;
97*0a6a1f1dSLionel Sambuc }
98*0a6a1f1dSLionel Sambuc 
~CXTUOwner()99f4a2713aSLionel Sambuc cxtu::CXTUOwner::~CXTUOwner() {
100f4a2713aSLionel Sambuc   if (TU)
101f4a2713aSLionel Sambuc     clang_disposeTranslationUnit(TU);
102f4a2713aSLionel Sambuc }
103f4a2713aSLionel Sambuc 
104f4a2713aSLionel Sambuc /// \brief Compare two source ranges to determine their relative position in
105f4a2713aSLionel Sambuc /// the translation unit.
RangeCompare(SourceManager & SM,SourceRange R1,SourceRange R2)106f4a2713aSLionel Sambuc static RangeComparisonResult RangeCompare(SourceManager &SM,
107f4a2713aSLionel Sambuc                                           SourceRange R1,
108f4a2713aSLionel Sambuc                                           SourceRange R2) {
109f4a2713aSLionel Sambuc   assert(R1.isValid() && "First range is invalid?");
110f4a2713aSLionel Sambuc   assert(R2.isValid() && "Second range is invalid?");
111f4a2713aSLionel Sambuc   if (R1.getEnd() != R2.getBegin() &&
112f4a2713aSLionel Sambuc       SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
113f4a2713aSLionel Sambuc     return RangeBefore;
114f4a2713aSLionel Sambuc   if (R2.getEnd() != R1.getBegin() &&
115f4a2713aSLionel Sambuc       SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
116f4a2713aSLionel Sambuc     return RangeAfter;
117f4a2713aSLionel Sambuc   return RangeOverlap;
118f4a2713aSLionel Sambuc }
119f4a2713aSLionel Sambuc 
120f4a2713aSLionel Sambuc /// \brief Determine if a source location falls within, before, or after a
121f4a2713aSLionel Sambuc ///   a given source range.
LocationCompare(SourceManager & SM,SourceLocation L,SourceRange R)122f4a2713aSLionel Sambuc static RangeComparisonResult LocationCompare(SourceManager &SM,
123f4a2713aSLionel Sambuc                                              SourceLocation L, SourceRange R) {
124f4a2713aSLionel Sambuc   assert(R.isValid() && "First range is invalid?");
125f4a2713aSLionel Sambuc   assert(L.isValid() && "Second range is invalid?");
126f4a2713aSLionel Sambuc   if (L == R.getBegin() || L == R.getEnd())
127f4a2713aSLionel Sambuc     return RangeOverlap;
128f4a2713aSLionel Sambuc   if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
129f4a2713aSLionel Sambuc     return RangeBefore;
130f4a2713aSLionel Sambuc   if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
131f4a2713aSLionel Sambuc     return RangeAfter;
132f4a2713aSLionel Sambuc   return RangeOverlap;
133f4a2713aSLionel Sambuc }
134f4a2713aSLionel Sambuc 
135f4a2713aSLionel Sambuc /// \brief Translate a Clang source range into a CIndex source range.
136f4a2713aSLionel Sambuc ///
137f4a2713aSLionel Sambuc /// Clang internally represents ranges where the end location points to the
138f4a2713aSLionel Sambuc /// start of the token at the end. However, for external clients it is more
139f4a2713aSLionel Sambuc /// useful to have a CXSourceRange be a proper half-open interval. This routine
140f4a2713aSLionel Sambuc /// does the appropriate translation.
translateSourceRange(const SourceManager & SM,const LangOptions & LangOpts,const CharSourceRange & R)141f4a2713aSLionel Sambuc CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
142f4a2713aSLionel Sambuc                                           const LangOptions &LangOpts,
143f4a2713aSLionel Sambuc                                           const CharSourceRange &R) {
144f4a2713aSLionel Sambuc   // We want the last character in this location, so we will adjust the
145f4a2713aSLionel Sambuc   // location accordingly.
146f4a2713aSLionel Sambuc   SourceLocation EndLoc = R.getEnd();
147f4a2713aSLionel Sambuc   if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
148f4a2713aSLionel Sambuc     EndLoc = SM.getExpansionRange(EndLoc).second;
149f4a2713aSLionel Sambuc   if (R.isTokenRange() && !EndLoc.isInvalid()) {
150f4a2713aSLionel Sambuc     unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
151f4a2713aSLionel Sambuc                                                 SM, LangOpts);
152f4a2713aSLionel Sambuc     EndLoc = EndLoc.getLocWithOffset(Length);
153f4a2713aSLionel Sambuc   }
154f4a2713aSLionel Sambuc 
155f4a2713aSLionel Sambuc   CXSourceRange Result = {
156f4a2713aSLionel Sambuc     { &SM, &LangOpts },
157f4a2713aSLionel Sambuc     R.getBegin().getRawEncoding(),
158f4a2713aSLionel Sambuc     EndLoc.getRawEncoding()
159f4a2713aSLionel Sambuc   };
160f4a2713aSLionel Sambuc   return Result;
161f4a2713aSLionel Sambuc }
162f4a2713aSLionel Sambuc 
163f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
164f4a2713aSLionel Sambuc // Cursor visitor.
165f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
166f4a2713aSLionel Sambuc 
167f4a2713aSLionel Sambuc static SourceRange getRawCursorExtent(CXCursor C);
168f4a2713aSLionel Sambuc static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
169f4a2713aSLionel Sambuc 
170f4a2713aSLionel Sambuc 
CompareRegionOfInterest(SourceRange R)171f4a2713aSLionel Sambuc RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
172f4a2713aSLionel Sambuc   return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
173f4a2713aSLionel Sambuc }
174f4a2713aSLionel Sambuc 
175f4a2713aSLionel Sambuc /// \brief Visit the given cursor and, if requested by the visitor,
176f4a2713aSLionel Sambuc /// its children.
177f4a2713aSLionel Sambuc ///
178f4a2713aSLionel Sambuc /// \param Cursor the cursor to visit.
179f4a2713aSLionel Sambuc ///
180f4a2713aSLionel Sambuc /// \param CheckedRegionOfInterest if true, then the caller already checked
181f4a2713aSLionel Sambuc /// that this cursor is within the region of interest.
182f4a2713aSLionel Sambuc ///
183f4a2713aSLionel Sambuc /// \returns true if the visitation should be aborted, false if it
184f4a2713aSLionel Sambuc /// should continue.
Visit(CXCursor Cursor,bool CheckedRegionOfInterest)185f4a2713aSLionel Sambuc bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
186f4a2713aSLionel Sambuc   if (clang_isInvalid(Cursor.kind))
187f4a2713aSLionel Sambuc     return false;
188f4a2713aSLionel Sambuc 
189f4a2713aSLionel Sambuc   if (clang_isDeclaration(Cursor.kind)) {
190f4a2713aSLionel Sambuc     const Decl *D = getCursorDecl(Cursor);
191f4a2713aSLionel Sambuc     if (!D) {
192f4a2713aSLionel Sambuc       assert(0 && "Invalid declaration cursor");
193f4a2713aSLionel Sambuc       return true; // abort.
194f4a2713aSLionel Sambuc     }
195f4a2713aSLionel Sambuc 
196f4a2713aSLionel Sambuc     // Ignore implicit declarations, unless it's an objc method because
197f4a2713aSLionel Sambuc     // currently we should report implicit methods for properties when indexing.
198f4a2713aSLionel Sambuc     if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
199f4a2713aSLionel Sambuc       return false;
200f4a2713aSLionel Sambuc   }
201f4a2713aSLionel Sambuc 
202f4a2713aSLionel Sambuc   // If we have a range of interest, and this cursor doesn't intersect with it,
203f4a2713aSLionel Sambuc   // we're done.
204f4a2713aSLionel Sambuc   if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
205f4a2713aSLionel Sambuc     SourceRange Range = getRawCursorExtent(Cursor);
206f4a2713aSLionel Sambuc     if (Range.isInvalid() || CompareRegionOfInterest(Range))
207f4a2713aSLionel Sambuc       return false;
208f4a2713aSLionel Sambuc   }
209f4a2713aSLionel Sambuc 
210f4a2713aSLionel Sambuc   switch (Visitor(Cursor, Parent, ClientData)) {
211f4a2713aSLionel Sambuc   case CXChildVisit_Break:
212f4a2713aSLionel Sambuc     return true;
213f4a2713aSLionel Sambuc 
214f4a2713aSLionel Sambuc   case CXChildVisit_Continue:
215f4a2713aSLionel Sambuc     return false;
216f4a2713aSLionel Sambuc 
217f4a2713aSLionel Sambuc   case CXChildVisit_Recurse: {
218f4a2713aSLionel Sambuc     bool ret = VisitChildren(Cursor);
219f4a2713aSLionel Sambuc     if (PostChildrenVisitor)
220f4a2713aSLionel Sambuc       if (PostChildrenVisitor(Cursor, ClientData))
221f4a2713aSLionel Sambuc         return true;
222f4a2713aSLionel Sambuc     return ret;
223f4a2713aSLionel Sambuc   }
224f4a2713aSLionel Sambuc   }
225f4a2713aSLionel Sambuc 
226f4a2713aSLionel Sambuc   llvm_unreachable("Invalid CXChildVisitResult!");
227f4a2713aSLionel Sambuc }
228f4a2713aSLionel Sambuc 
visitPreprocessedEntitiesInRange(SourceRange R,PreprocessingRecord & PPRec,CursorVisitor & Visitor)229f4a2713aSLionel Sambuc static bool visitPreprocessedEntitiesInRange(SourceRange R,
230f4a2713aSLionel Sambuc                                              PreprocessingRecord &PPRec,
231f4a2713aSLionel Sambuc                                              CursorVisitor &Visitor) {
232f4a2713aSLionel Sambuc   SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
233f4a2713aSLionel Sambuc   FileID FID;
234f4a2713aSLionel Sambuc 
235f4a2713aSLionel Sambuc   if (!Visitor.shouldVisitIncludedEntities()) {
236f4a2713aSLionel Sambuc     // If the begin/end of the range lie in the same FileID, do the optimization
237f4a2713aSLionel Sambuc     // where we skip preprocessed entities that do not come from the same FileID.
238f4a2713aSLionel Sambuc     FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
239f4a2713aSLionel Sambuc     if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
240f4a2713aSLionel Sambuc       FID = FileID();
241f4a2713aSLionel Sambuc   }
242f4a2713aSLionel Sambuc 
243f4a2713aSLionel Sambuc   std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
244f4a2713aSLionel Sambuc     Entities = PPRec.getPreprocessedEntitiesInRange(R);
245f4a2713aSLionel Sambuc   return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
246f4a2713aSLionel Sambuc                                            PPRec, FID);
247f4a2713aSLionel Sambuc }
248f4a2713aSLionel Sambuc 
visitFileRegion()249f4a2713aSLionel Sambuc bool CursorVisitor::visitFileRegion() {
250f4a2713aSLionel Sambuc   if (RegionOfInterest.isInvalid())
251f4a2713aSLionel Sambuc     return false;
252f4a2713aSLionel Sambuc 
253f4a2713aSLionel Sambuc   ASTUnit *Unit = cxtu::getASTUnit(TU);
254f4a2713aSLionel Sambuc   SourceManager &SM = Unit->getSourceManager();
255f4a2713aSLionel Sambuc 
256f4a2713aSLionel Sambuc   std::pair<FileID, unsigned>
257f4a2713aSLionel Sambuc     Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258f4a2713aSLionel Sambuc     End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259f4a2713aSLionel Sambuc 
260f4a2713aSLionel Sambuc   if (End.first != Begin.first) {
261f4a2713aSLionel Sambuc     // If the end does not reside in the same file, try to recover by
262f4a2713aSLionel Sambuc     // picking the end of the file of begin location.
263f4a2713aSLionel Sambuc     End.first = Begin.first;
264f4a2713aSLionel Sambuc     End.second = SM.getFileIDSize(Begin.first);
265f4a2713aSLionel Sambuc   }
266f4a2713aSLionel Sambuc 
267f4a2713aSLionel Sambuc   assert(Begin.first == End.first);
268f4a2713aSLionel Sambuc   if (Begin.second > End.second)
269f4a2713aSLionel Sambuc     return false;
270f4a2713aSLionel Sambuc 
271f4a2713aSLionel Sambuc   FileID File = Begin.first;
272f4a2713aSLionel Sambuc   unsigned Offset = Begin.second;
273f4a2713aSLionel Sambuc   unsigned Length = End.second - Begin.second;
274f4a2713aSLionel Sambuc 
275f4a2713aSLionel Sambuc   if (!VisitDeclsOnly && !VisitPreprocessorLast)
276f4a2713aSLionel Sambuc     if (visitPreprocessedEntitiesInRegion())
277f4a2713aSLionel Sambuc       return true; // visitation break.
278f4a2713aSLionel Sambuc 
279f4a2713aSLionel Sambuc   if (visitDeclsFromFileRegion(File, Offset, Length))
280f4a2713aSLionel Sambuc     return true; // visitation break.
281f4a2713aSLionel Sambuc 
282f4a2713aSLionel Sambuc   if (!VisitDeclsOnly && VisitPreprocessorLast)
283f4a2713aSLionel Sambuc     return visitPreprocessedEntitiesInRegion();
284f4a2713aSLionel Sambuc 
285f4a2713aSLionel Sambuc   return false;
286f4a2713aSLionel Sambuc }
287f4a2713aSLionel Sambuc 
isInLexicalContext(Decl * D,DeclContext * DC)288f4a2713aSLionel Sambuc static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289f4a2713aSLionel Sambuc   if (!DC)
290f4a2713aSLionel Sambuc     return false;
291f4a2713aSLionel Sambuc 
292f4a2713aSLionel Sambuc   for (DeclContext *DeclDC = D->getLexicalDeclContext();
293f4a2713aSLionel Sambuc          DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294f4a2713aSLionel Sambuc     if (DeclDC == DC)
295f4a2713aSLionel Sambuc       return true;
296f4a2713aSLionel Sambuc   }
297f4a2713aSLionel Sambuc   return false;
298f4a2713aSLionel Sambuc }
299f4a2713aSLionel Sambuc 
visitDeclsFromFileRegion(FileID File,unsigned Offset,unsigned Length)300f4a2713aSLionel Sambuc bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
301f4a2713aSLionel Sambuc                                              unsigned Offset, unsigned Length) {
302f4a2713aSLionel Sambuc   ASTUnit *Unit = cxtu::getASTUnit(TU);
303f4a2713aSLionel Sambuc   SourceManager &SM = Unit->getSourceManager();
304f4a2713aSLionel Sambuc   SourceRange Range = RegionOfInterest;
305f4a2713aSLionel Sambuc 
306f4a2713aSLionel Sambuc   SmallVector<Decl *, 16> Decls;
307f4a2713aSLionel Sambuc   Unit->findFileRegionDecls(File, Offset, Length, Decls);
308f4a2713aSLionel Sambuc 
309f4a2713aSLionel Sambuc   // If we didn't find any file level decls for the file, try looking at the
310f4a2713aSLionel Sambuc   // file that it was included from.
311f4a2713aSLionel Sambuc   while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312f4a2713aSLionel Sambuc     bool Invalid = false;
313f4a2713aSLionel Sambuc     const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314f4a2713aSLionel Sambuc     if (Invalid)
315f4a2713aSLionel Sambuc       return false;
316f4a2713aSLionel Sambuc 
317f4a2713aSLionel Sambuc     SourceLocation Outer;
318f4a2713aSLionel Sambuc     if (SLEntry.isFile())
319f4a2713aSLionel Sambuc       Outer = SLEntry.getFile().getIncludeLoc();
320f4a2713aSLionel Sambuc     else
321f4a2713aSLionel Sambuc       Outer = SLEntry.getExpansion().getExpansionLocStart();
322f4a2713aSLionel Sambuc     if (Outer.isInvalid())
323f4a2713aSLionel Sambuc       return false;
324f4a2713aSLionel Sambuc 
325*0a6a1f1dSLionel Sambuc     std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
326f4a2713aSLionel Sambuc     Length = 0;
327f4a2713aSLionel Sambuc     Unit->findFileRegionDecls(File, Offset, Length, Decls);
328f4a2713aSLionel Sambuc   }
329f4a2713aSLionel Sambuc 
330f4a2713aSLionel Sambuc   assert(!Decls.empty());
331f4a2713aSLionel Sambuc 
332f4a2713aSLionel Sambuc   bool VisitedAtLeastOnce = false;
333*0a6a1f1dSLionel Sambuc   DeclContext *CurDC = nullptr;
334f4a2713aSLionel Sambuc   SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335f4a2713aSLionel Sambuc   for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
336f4a2713aSLionel Sambuc     Decl *D = *DIt;
337f4a2713aSLionel Sambuc     if (D->getSourceRange().isInvalid())
338f4a2713aSLionel Sambuc       continue;
339f4a2713aSLionel Sambuc 
340f4a2713aSLionel Sambuc     if (isInLexicalContext(D, CurDC))
341f4a2713aSLionel Sambuc       continue;
342f4a2713aSLionel Sambuc 
343f4a2713aSLionel Sambuc     CurDC = dyn_cast<DeclContext>(D);
344f4a2713aSLionel Sambuc 
345f4a2713aSLionel Sambuc     if (TagDecl *TD = dyn_cast<TagDecl>(D))
346f4a2713aSLionel Sambuc       if (!TD->isFreeStanding())
347f4a2713aSLionel Sambuc         continue;
348f4a2713aSLionel Sambuc 
349f4a2713aSLionel Sambuc     RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350f4a2713aSLionel Sambuc     if (CompRes == RangeBefore)
351f4a2713aSLionel Sambuc       continue;
352f4a2713aSLionel Sambuc     if (CompRes == RangeAfter)
353f4a2713aSLionel Sambuc       break;
354f4a2713aSLionel Sambuc 
355f4a2713aSLionel Sambuc     assert(CompRes == RangeOverlap);
356f4a2713aSLionel Sambuc     VisitedAtLeastOnce = true;
357f4a2713aSLionel Sambuc 
358f4a2713aSLionel Sambuc     if (isa<ObjCContainerDecl>(D)) {
359f4a2713aSLionel Sambuc       FileDI_current = &DIt;
360f4a2713aSLionel Sambuc       FileDE_current = DE;
361f4a2713aSLionel Sambuc     } else {
362*0a6a1f1dSLionel Sambuc       FileDI_current = nullptr;
363f4a2713aSLionel Sambuc     }
364f4a2713aSLionel Sambuc 
365f4a2713aSLionel Sambuc     if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
366f4a2713aSLionel Sambuc       return true; // visitation break.
367f4a2713aSLionel Sambuc   }
368f4a2713aSLionel Sambuc 
369f4a2713aSLionel Sambuc   if (VisitedAtLeastOnce)
370f4a2713aSLionel Sambuc     return false;
371f4a2713aSLionel Sambuc 
372f4a2713aSLionel Sambuc   // No Decls overlapped with the range. Move up the lexical context until there
373f4a2713aSLionel Sambuc   // is a context that contains the range or we reach the translation unit
374f4a2713aSLionel Sambuc   // level.
375f4a2713aSLionel Sambuc   DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376f4a2713aSLionel Sambuc                                          : (*(DIt-1))->getLexicalDeclContext();
377f4a2713aSLionel Sambuc 
378f4a2713aSLionel Sambuc   while (DC && !DC->isTranslationUnit()) {
379f4a2713aSLionel Sambuc     Decl *D = cast<Decl>(DC);
380f4a2713aSLionel Sambuc     SourceRange CurDeclRange = D->getSourceRange();
381f4a2713aSLionel Sambuc     if (CurDeclRange.isInvalid())
382f4a2713aSLionel Sambuc       break;
383f4a2713aSLionel Sambuc 
384f4a2713aSLionel Sambuc     if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
385f4a2713aSLionel Sambuc       if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386f4a2713aSLionel Sambuc         return true; // visitation break.
387f4a2713aSLionel Sambuc     }
388f4a2713aSLionel Sambuc 
389f4a2713aSLionel Sambuc     DC = D->getLexicalDeclContext();
390f4a2713aSLionel Sambuc   }
391f4a2713aSLionel Sambuc 
392f4a2713aSLionel Sambuc   return false;
393f4a2713aSLionel Sambuc }
394f4a2713aSLionel Sambuc 
visitPreprocessedEntitiesInRegion()395f4a2713aSLionel Sambuc bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396f4a2713aSLionel Sambuc   if (!AU->getPreprocessor().getPreprocessingRecord())
397f4a2713aSLionel Sambuc     return false;
398f4a2713aSLionel Sambuc 
399f4a2713aSLionel Sambuc   PreprocessingRecord &PPRec
400f4a2713aSLionel Sambuc     = *AU->getPreprocessor().getPreprocessingRecord();
401f4a2713aSLionel Sambuc   SourceManager &SM = AU->getSourceManager();
402f4a2713aSLionel Sambuc 
403f4a2713aSLionel Sambuc   if (RegionOfInterest.isValid()) {
404f4a2713aSLionel Sambuc     SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405f4a2713aSLionel Sambuc     SourceLocation B = MappedRange.getBegin();
406f4a2713aSLionel Sambuc     SourceLocation E = MappedRange.getEnd();
407f4a2713aSLionel Sambuc 
408f4a2713aSLionel Sambuc     if (AU->isInPreambleFileID(B)) {
409f4a2713aSLionel Sambuc       if (SM.isLoadedSourceLocation(E))
410f4a2713aSLionel Sambuc         return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411f4a2713aSLionel Sambuc                                                  PPRec, *this);
412f4a2713aSLionel Sambuc 
413f4a2713aSLionel Sambuc       // Beginning of range lies in the preamble but it also extends beyond
414f4a2713aSLionel Sambuc       // it into the main file. Split the range into 2 parts, one covering
415f4a2713aSLionel Sambuc       // the preamble and another covering the main file. This allows subsequent
416f4a2713aSLionel Sambuc       // calls to visitPreprocessedEntitiesInRange to accept a source range that
417f4a2713aSLionel Sambuc       // lies in the same FileID, allowing it to skip preprocessed entities that
418f4a2713aSLionel Sambuc       // do not come from the same FileID.
419f4a2713aSLionel Sambuc       bool breaked =
420f4a2713aSLionel Sambuc         visitPreprocessedEntitiesInRange(
421f4a2713aSLionel Sambuc                                    SourceRange(B, AU->getEndOfPreambleFileID()),
422f4a2713aSLionel Sambuc                                           PPRec, *this);
423f4a2713aSLionel Sambuc       if (breaked) return true;
424f4a2713aSLionel Sambuc       return visitPreprocessedEntitiesInRange(
425f4a2713aSLionel Sambuc                                     SourceRange(AU->getStartOfMainFileID(), E),
426f4a2713aSLionel Sambuc                                         PPRec, *this);
427f4a2713aSLionel Sambuc     }
428f4a2713aSLionel Sambuc 
429f4a2713aSLionel Sambuc     return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430f4a2713aSLionel Sambuc   }
431f4a2713aSLionel Sambuc 
432f4a2713aSLionel Sambuc   bool OnlyLocalDecls
433f4a2713aSLionel Sambuc     = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434f4a2713aSLionel Sambuc 
435f4a2713aSLionel Sambuc   if (OnlyLocalDecls)
436f4a2713aSLionel Sambuc     return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437f4a2713aSLionel Sambuc                                      PPRec);
438f4a2713aSLionel Sambuc 
439f4a2713aSLionel Sambuc   return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440f4a2713aSLionel Sambuc }
441f4a2713aSLionel Sambuc 
442f4a2713aSLionel Sambuc template<typename InputIterator>
visitPreprocessedEntities(InputIterator First,InputIterator Last,PreprocessingRecord & PPRec,FileID FID)443f4a2713aSLionel Sambuc bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444f4a2713aSLionel Sambuc                                               InputIterator Last,
445f4a2713aSLionel Sambuc                                               PreprocessingRecord &PPRec,
446f4a2713aSLionel Sambuc                                               FileID FID) {
447f4a2713aSLionel Sambuc   for (; First != Last; ++First) {
448f4a2713aSLionel Sambuc     if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449f4a2713aSLionel Sambuc       continue;
450f4a2713aSLionel Sambuc 
451f4a2713aSLionel Sambuc     PreprocessedEntity *PPE = *First;
452f4a2713aSLionel Sambuc     if (!PPE)
453f4a2713aSLionel Sambuc       continue;
454f4a2713aSLionel Sambuc 
455f4a2713aSLionel Sambuc     if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456f4a2713aSLionel Sambuc       if (Visit(MakeMacroExpansionCursor(ME, TU)))
457f4a2713aSLionel Sambuc         return true;
458f4a2713aSLionel Sambuc 
459f4a2713aSLionel Sambuc       continue;
460f4a2713aSLionel Sambuc     }
461f4a2713aSLionel Sambuc 
462f4a2713aSLionel Sambuc     if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
463f4a2713aSLionel Sambuc       if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464f4a2713aSLionel Sambuc         return true;
465f4a2713aSLionel Sambuc 
466f4a2713aSLionel Sambuc       continue;
467f4a2713aSLionel Sambuc     }
468f4a2713aSLionel Sambuc 
469f4a2713aSLionel Sambuc     if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470f4a2713aSLionel Sambuc       if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471f4a2713aSLionel Sambuc         return true;
472f4a2713aSLionel Sambuc 
473f4a2713aSLionel Sambuc       continue;
474f4a2713aSLionel Sambuc     }
475f4a2713aSLionel Sambuc   }
476f4a2713aSLionel Sambuc 
477f4a2713aSLionel Sambuc   return false;
478f4a2713aSLionel Sambuc }
479f4a2713aSLionel Sambuc 
480f4a2713aSLionel Sambuc /// \brief Visit the children of the given cursor.
481f4a2713aSLionel Sambuc ///
482f4a2713aSLionel Sambuc /// \returns true if the visitation should be aborted, false if it
483f4a2713aSLionel Sambuc /// should continue.
VisitChildren(CXCursor Cursor)484f4a2713aSLionel Sambuc bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485f4a2713aSLionel Sambuc   if (clang_isReference(Cursor.kind) &&
486f4a2713aSLionel Sambuc       Cursor.kind != CXCursor_CXXBaseSpecifier) {
487f4a2713aSLionel Sambuc     // By definition, references have no children.
488f4a2713aSLionel Sambuc     return false;
489f4a2713aSLionel Sambuc   }
490f4a2713aSLionel Sambuc 
491f4a2713aSLionel Sambuc   // Set the Parent field to Cursor, then back to its old value once we're
492f4a2713aSLionel Sambuc   // done.
493f4a2713aSLionel Sambuc   SetParentRAII SetParent(Parent, StmtParent, Cursor);
494f4a2713aSLionel Sambuc 
495f4a2713aSLionel Sambuc   if (clang_isDeclaration(Cursor.kind)) {
496f4a2713aSLionel Sambuc     Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
497f4a2713aSLionel Sambuc     if (!D)
498f4a2713aSLionel Sambuc       return false;
499f4a2713aSLionel Sambuc 
500f4a2713aSLionel Sambuc     return VisitAttributes(D) || Visit(D);
501f4a2713aSLionel Sambuc   }
502f4a2713aSLionel Sambuc 
503f4a2713aSLionel Sambuc   if (clang_isStatement(Cursor.kind)) {
504f4a2713aSLionel Sambuc     if (const Stmt *S = getCursorStmt(Cursor))
505f4a2713aSLionel Sambuc       return Visit(S);
506f4a2713aSLionel Sambuc 
507f4a2713aSLionel Sambuc     return false;
508f4a2713aSLionel Sambuc   }
509f4a2713aSLionel Sambuc 
510f4a2713aSLionel Sambuc   if (clang_isExpression(Cursor.kind)) {
511f4a2713aSLionel Sambuc     if (const Expr *E = getCursorExpr(Cursor))
512f4a2713aSLionel Sambuc       return Visit(E);
513f4a2713aSLionel Sambuc 
514f4a2713aSLionel Sambuc     return false;
515f4a2713aSLionel Sambuc   }
516f4a2713aSLionel Sambuc 
517f4a2713aSLionel Sambuc   if (clang_isTranslationUnit(Cursor.kind)) {
518f4a2713aSLionel Sambuc     CXTranslationUnit TU = getCursorTU(Cursor);
519f4a2713aSLionel Sambuc     ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
520f4a2713aSLionel Sambuc 
521f4a2713aSLionel Sambuc     int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522f4a2713aSLionel Sambuc     for (unsigned I = 0; I != 2; ++I) {
523f4a2713aSLionel Sambuc       if (VisitOrder[I]) {
524f4a2713aSLionel Sambuc         if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525f4a2713aSLionel Sambuc             RegionOfInterest.isInvalid()) {
526f4a2713aSLionel Sambuc           for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527f4a2713aSLionel Sambuc                                         TLEnd = CXXUnit->top_level_end();
528f4a2713aSLionel Sambuc                TL != TLEnd; ++TL) {
529f4a2713aSLionel Sambuc             if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
530f4a2713aSLionel Sambuc               return true;
531f4a2713aSLionel Sambuc           }
532f4a2713aSLionel Sambuc         } else if (VisitDeclContext(
533f4a2713aSLionel Sambuc                                 CXXUnit->getASTContext().getTranslationUnitDecl()))
534f4a2713aSLionel Sambuc           return true;
535f4a2713aSLionel Sambuc         continue;
536f4a2713aSLionel Sambuc       }
537f4a2713aSLionel Sambuc 
538f4a2713aSLionel Sambuc       // Walk the preprocessing record.
539f4a2713aSLionel Sambuc       if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540f4a2713aSLionel Sambuc         visitPreprocessedEntitiesInRegion();
541f4a2713aSLionel Sambuc     }
542f4a2713aSLionel Sambuc 
543f4a2713aSLionel Sambuc     return false;
544f4a2713aSLionel Sambuc   }
545f4a2713aSLionel Sambuc 
546f4a2713aSLionel Sambuc   if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
547f4a2713aSLionel Sambuc     if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
548f4a2713aSLionel Sambuc       if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549f4a2713aSLionel Sambuc         return Visit(BaseTSInfo->getTypeLoc());
550f4a2713aSLionel Sambuc       }
551f4a2713aSLionel Sambuc     }
552f4a2713aSLionel Sambuc   }
553f4a2713aSLionel Sambuc 
554f4a2713aSLionel Sambuc   if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
555f4a2713aSLionel Sambuc     const IBOutletCollectionAttr *A =
556f4a2713aSLionel Sambuc       cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
557f4a2713aSLionel Sambuc     if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
558f4a2713aSLionel Sambuc       return Visit(cxcursor::MakeCursorObjCClassRef(
559f4a2713aSLionel Sambuc           ObjT->getInterface(),
560f4a2713aSLionel Sambuc           A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
561f4a2713aSLionel Sambuc   }
562f4a2713aSLionel Sambuc 
563f4a2713aSLionel Sambuc   // If pointing inside a macro definition, check if the token is an identifier
564f4a2713aSLionel Sambuc   // that was ever defined as a macro. In such a case, create a "pseudo" macro
565f4a2713aSLionel Sambuc   // expansion cursor for that token.
566f4a2713aSLionel Sambuc   SourceLocation BeginLoc = RegionOfInterest.getBegin();
567f4a2713aSLionel Sambuc   if (Cursor.kind == CXCursor_MacroDefinition &&
568f4a2713aSLionel Sambuc       BeginLoc == RegionOfInterest.getEnd()) {
569f4a2713aSLionel Sambuc     SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
570f4a2713aSLionel Sambuc     const MacroInfo *MI =
571f4a2713aSLionel Sambuc         getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
572f4a2713aSLionel Sambuc     if (MacroDefinition *MacroDef =
573f4a2713aSLionel Sambuc           checkForMacroInMacroDefinition(MI, Loc, TU))
574f4a2713aSLionel Sambuc       return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575f4a2713aSLionel Sambuc   }
576f4a2713aSLionel Sambuc 
577f4a2713aSLionel Sambuc   // Nothing to visit at the moment.
578f4a2713aSLionel Sambuc   return false;
579f4a2713aSLionel Sambuc }
580f4a2713aSLionel Sambuc 
VisitBlockDecl(BlockDecl * B)581f4a2713aSLionel Sambuc bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582f4a2713aSLionel Sambuc   if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583f4a2713aSLionel Sambuc     if (Visit(TSInfo->getTypeLoc()))
584f4a2713aSLionel Sambuc         return true;
585f4a2713aSLionel Sambuc 
586f4a2713aSLionel Sambuc   if (Stmt *Body = B->getBody())
587f4a2713aSLionel Sambuc     return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588f4a2713aSLionel Sambuc 
589f4a2713aSLionel Sambuc   return false;
590f4a2713aSLionel Sambuc }
591f4a2713aSLionel Sambuc 
shouldVisitCursor(CXCursor Cursor)592f4a2713aSLionel Sambuc Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
593f4a2713aSLionel Sambuc   if (RegionOfInterest.isValid()) {
594f4a2713aSLionel Sambuc     SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595f4a2713aSLionel Sambuc     if (Range.isInvalid())
596f4a2713aSLionel Sambuc       return None;
597f4a2713aSLionel Sambuc 
598f4a2713aSLionel Sambuc     switch (CompareRegionOfInterest(Range)) {
599f4a2713aSLionel Sambuc     case RangeBefore:
600f4a2713aSLionel Sambuc       // This declaration comes before the region of interest; skip it.
601f4a2713aSLionel Sambuc       return None;
602f4a2713aSLionel Sambuc 
603f4a2713aSLionel Sambuc     case RangeAfter:
604f4a2713aSLionel Sambuc       // This declaration comes after the region of interest; we're done.
605f4a2713aSLionel Sambuc       return false;
606f4a2713aSLionel Sambuc 
607f4a2713aSLionel Sambuc     case RangeOverlap:
608f4a2713aSLionel Sambuc       // This declaration overlaps the region of interest; visit it.
609f4a2713aSLionel Sambuc       break;
610f4a2713aSLionel Sambuc     }
611f4a2713aSLionel Sambuc   }
612f4a2713aSLionel Sambuc   return true;
613f4a2713aSLionel Sambuc }
614f4a2713aSLionel Sambuc 
VisitDeclContext(DeclContext * DC)615f4a2713aSLionel Sambuc bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616f4a2713aSLionel Sambuc   DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617f4a2713aSLionel Sambuc 
618f4a2713aSLionel Sambuc   // FIXME: Eventually remove.  This part of a hack to support proper
619f4a2713aSLionel Sambuc   // iteration over all Decls contained lexically within an ObjC container.
620f4a2713aSLionel Sambuc   SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621f4a2713aSLionel Sambuc   SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622f4a2713aSLionel Sambuc 
623f4a2713aSLionel Sambuc   for ( ; I != E; ++I) {
624f4a2713aSLionel Sambuc     Decl *D = *I;
625f4a2713aSLionel Sambuc     if (D->getLexicalDeclContext() != DC)
626f4a2713aSLionel Sambuc       continue;
627f4a2713aSLionel Sambuc     CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628f4a2713aSLionel Sambuc 
629f4a2713aSLionel Sambuc     // Ignore synthesized ivars here, otherwise if we have something like:
630f4a2713aSLionel Sambuc     //   @synthesize prop = _prop;
631f4a2713aSLionel Sambuc     // and '_prop' is not declared, we will encounter a '_prop' ivar before
632f4a2713aSLionel Sambuc     // encountering the 'prop' synthesize declaration and we will think that
633f4a2713aSLionel Sambuc     // we passed the region-of-interest.
634f4a2713aSLionel Sambuc     if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635f4a2713aSLionel Sambuc       if (ivarD->getSynthesize())
636f4a2713aSLionel Sambuc         continue;
637f4a2713aSLionel Sambuc     }
638f4a2713aSLionel Sambuc 
639f4a2713aSLionel Sambuc     // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640f4a2713aSLionel Sambuc     // declarations is a mismatch with the compiler semantics.
641f4a2713aSLionel Sambuc     if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642f4a2713aSLionel Sambuc       ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643f4a2713aSLionel Sambuc       if (!ID->isThisDeclarationADefinition())
644f4a2713aSLionel Sambuc         Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645f4a2713aSLionel Sambuc 
646f4a2713aSLionel Sambuc     } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647f4a2713aSLionel Sambuc       ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648f4a2713aSLionel Sambuc       if (!PD->isThisDeclarationADefinition())
649f4a2713aSLionel Sambuc         Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650f4a2713aSLionel Sambuc     }
651f4a2713aSLionel Sambuc 
652f4a2713aSLionel Sambuc     const Optional<bool> &V = shouldVisitCursor(Cursor);
653f4a2713aSLionel Sambuc     if (!V.hasValue())
654f4a2713aSLionel Sambuc       continue;
655f4a2713aSLionel Sambuc     if (!V.getValue())
656f4a2713aSLionel Sambuc       return false;
657f4a2713aSLionel Sambuc     if (Visit(Cursor, true))
658f4a2713aSLionel Sambuc       return true;
659f4a2713aSLionel Sambuc   }
660f4a2713aSLionel Sambuc   return false;
661f4a2713aSLionel Sambuc }
662f4a2713aSLionel Sambuc 
VisitTranslationUnitDecl(TranslationUnitDecl * D)663f4a2713aSLionel Sambuc bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664f4a2713aSLionel Sambuc   llvm_unreachable("Translation units are visited directly by Visit()");
665f4a2713aSLionel Sambuc }
666f4a2713aSLionel Sambuc 
VisitTypeAliasDecl(TypeAliasDecl * D)667f4a2713aSLionel Sambuc bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668f4a2713aSLionel Sambuc   if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669f4a2713aSLionel Sambuc     return Visit(TSInfo->getTypeLoc());
670f4a2713aSLionel Sambuc 
671f4a2713aSLionel Sambuc   return false;
672f4a2713aSLionel Sambuc }
673f4a2713aSLionel Sambuc 
VisitTypedefDecl(TypedefDecl * D)674f4a2713aSLionel Sambuc bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675f4a2713aSLionel Sambuc   if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676f4a2713aSLionel Sambuc     return Visit(TSInfo->getTypeLoc());
677f4a2713aSLionel Sambuc 
678f4a2713aSLionel Sambuc   return false;
679f4a2713aSLionel Sambuc }
680f4a2713aSLionel Sambuc 
VisitTagDecl(TagDecl * D)681f4a2713aSLionel Sambuc bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682f4a2713aSLionel Sambuc   return VisitDeclContext(D);
683f4a2713aSLionel Sambuc }
684f4a2713aSLionel Sambuc 
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)685f4a2713aSLionel Sambuc bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686f4a2713aSLionel Sambuc                                           ClassTemplateSpecializationDecl *D) {
687f4a2713aSLionel Sambuc   bool ShouldVisitBody = false;
688f4a2713aSLionel Sambuc   switch (D->getSpecializationKind()) {
689f4a2713aSLionel Sambuc   case TSK_Undeclared:
690f4a2713aSLionel Sambuc   case TSK_ImplicitInstantiation:
691f4a2713aSLionel Sambuc     // Nothing to visit
692f4a2713aSLionel Sambuc     return false;
693f4a2713aSLionel Sambuc 
694f4a2713aSLionel Sambuc   case TSK_ExplicitInstantiationDeclaration:
695f4a2713aSLionel Sambuc   case TSK_ExplicitInstantiationDefinition:
696f4a2713aSLionel Sambuc     break;
697f4a2713aSLionel Sambuc 
698f4a2713aSLionel Sambuc   case TSK_ExplicitSpecialization:
699f4a2713aSLionel Sambuc     ShouldVisitBody = true;
700f4a2713aSLionel Sambuc     break;
701f4a2713aSLionel Sambuc   }
702f4a2713aSLionel Sambuc 
703f4a2713aSLionel Sambuc   // Visit the template arguments used in the specialization.
704f4a2713aSLionel Sambuc   if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705f4a2713aSLionel Sambuc     TypeLoc TL = SpecType->getTypeLoc();
706f4a2713aSLionel Sambuc     if (TemplateSpecializationTypeLoc TSTLoc =
707f4a2713aSLionel Sambuc             TL.getAs<TemplateSpecializationTypeLoc>()) {
708f4a2713aSLionel Sambuc       for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709f4a2713aSLionel Sambuc         if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
710f4a2713aSLionel Sambuc           return true;
711f4a2713aSLionel Sambuc     }
712f4a2713aSLionel Sambuc   }
713f4a2713aSLionel Sambuc 
714f4a2713aSLionel Sambuc   if (ShouldVisitBody && VisitCXXRecordDecl(D))
715f4a2713aSLionel Sambuc     return true;
716f4a2713aSLionel Sambuc 
717f4a2713aSLionel Sambuc   return false;
718f4a2713aSLionel Sambuc }
719f4a2713aSLionel Sambuc 
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)720f4a2713aSLionel Sambuc bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721f4a2713aSLionel Sambuc                                    ClassTemplatePartialSpecializationDecl *D) {
722f4a2713aSLionel Sambuc   // FIXME: Visit the "outer" template parameter lists on the TagDecl
723f4a2713aSLionel Sambuc   // before visiting these template parameters.
724f4a2713aSLionel Sambuc   if (VisitTemplateParameters(D->getTemplateParameters()))
725f4a2713aSLionel Sambuc     return true;
726f4a2713aSLionel Sambuc 
727f4a2713aSLionel Sambuc   // Visit the partial specialization arguments.
728f4a2713aSLionel Sambuc   const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729f4a2713aSLionel Sambuc   const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730f4a2713aSLionel Sambuc   for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
731f4a2713aSLionel Sambuc     if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732f4a2713aSLionel Sambuc       return true;
733f4a2713aSLionel Sambuc 
734f4a2713aSLionel Sambuc   return VisitCXXRecordDecl(D);
735f4a2713aSLionel Sambuc }
736f4a2713aSLionel Sambuc 
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)737f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738f4a2713aSLionel Sambuc   // Visit the default argument.
739f4a2713aSLionel Sambuc   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740f4a2713aSLionel Sambuc     if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741f4a2713aSLionel Sambuc       if (Visit(DefArg->getTypeLoc()))
742f4a2713aSLionel Sambuc         return true;
743f4a2713aSLionel Sambuc 
744f4a2713aSLionel Sambuc   return false;
745f4a2713aSLionel Sambuc }
746f4a2713aSLionel Sambuc 
VisitEnumConstantDecl(EnumConstantDecl * D)747f4a2713aSLionel Sambuc bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748f4a2713aSLionel Sambuc   if (Expr *Init = D->getInitExpr())
749f4a2713aSLionel Sambuc     return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750f4a2713aSLionel Sambuc   return false;
751f4a2713aSLionel Sambuc }
752f4a2713aSLionel Sambuc 
VisitDeclaratorDecl(DeclaratorDecl * DD)753f4a2713aSLionel Sambuc bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
754f4a2713aSLionel Sambuc   unsigned NumParamList = DD->getNumTemplateParameterLists();
755f4a2713aSLionel Sambuc   for (unsigned i = 0; i < NumParamList; i++) {
756f4a2713aSLionel Sambuc     TemplateParameterList* Params = DD->getTemplateParameterList(i);
757f4a2713aSLionel Sambuc     if (VisitTemplateParameters(Params))
758f4a2713aSLionel Sambuc       return true;
759f4a2713aSLionel Sambuc   }
760f4a2713aSLionel Sambuc 
761f4a2713aSLionel Sambuc   if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762f4a2713aSLionel Sambuc     if (Visit(TSInfo->getTypeLoc()))
763f4a2713aSLionel Sambuc       return true;
764f4a2713aSLionel Sambuc 
765f4a2713aSLionel Sambuc   // Visit the nested-name-specifier, if present.
766f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767f4a2713aSLionel Sambuc     if (VisitNestedNameSpecifierLoc(QualifierLoc))
768f4a2713aSLionel Sambuc       return true;
769f4a2713aSLionel Sambuc 
770f4a2713aSLionel Sambuc   return false;
771f4a2713aSLionel Sambuc }
772f4a2713aSLionel Sambuc 
773f4a2713aSLionel Sambuc /// \brief Compare two base or member initializers based on their source order.
CompareCXXCtorInitializers(CXXCtorInitializer * const * X,CXXCtorInitializer * const * Y)774f4a2713aSLionel Sambuc static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775f4a2713aSLionel Sambuc                                       CXXCtorInitializer *const *Y) {
776f4a2713aSLionel Sambuc   return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777f4a2713aSLionel Sambuc }
778f4a2713aSLionel Sambuc 
VisitFunctionDecl(FunctionDecl * ND)779f4a2713aSLionel Sambuc bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
780f4a2713aSLionel Sambuc   unsigned NumParamList = ND->getNumTemplateParameterLists();
781f4a2713aSLionel Sambuc   for (unsigned i = 0; i < NumParamList; i++) {
782f4a2713aSLionel Sambuc     TemplateParameterList* Params = ND->getTemplateParameterList(i);
783f4a2713aSLionel Sambuc     if (VisitTemplateParameters(Params))
784f4a2713aSLionel Sambuc       return true;
785f4a2713aSLionel Sambuc   }
786f4a2713aSLionel Sambuc 
787f4a2713aSLionel Sambuc   if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788f4a2713aSLionel Sambuc     // Visit the function declaration's syntactic components in the order
789f4a2713aSLionel Sambuc     // written. This requires a bit of work.
790f4a2713aSLionel Sambuc     TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
791f4a2713aSLionel Sambuc     FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
792f4a2713aSLionel Sambuc 
793f4a2713aSLionel Sambuc     // If we have a function declared directly (without the use of a typedef),
794f4a2713aSLionel Sambuc     // visit just the return type. Otherwise, just visit the function's type
795f4a2713aSLionel Sambuc     // now.
796*0a6a1f1dSLionel Sambuc     if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
797f4a2713aSLionel Sambuc         (!FTL && Visit(TL)))
798f4a2713aSLionel Sambuc       return true;
799f4a2713aSLionel Sambuc 
800f4a2713aSLionel Sambuc     // Visit the nested-name-specifier, if present.
801f4a2713aSLionel Sambuc     if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802f4a2713aSLionel Sambuc       if (VisitNestedNameSpecifierLoc(QualifierLoc))
803f4a2713aSLionel Sambuc         return true;
804f4a2713aSLionel Sambuc 
805f4a2713aSLionel Sambuc     // Visit the declaration name.
806*0a6a1f1dSLionel Sambuc     if (!isa<CXXDestructorDecl>(ND))
807f4a2713aSLionel Sambuc       if (VisitDeclarationNameInfo(ND->getNameInfo()))
808f4a2713aSLionel Sambuc         return true;
809f4a2713aSLionel Sambuc 
810f4a2713aSLionel Sambuc     // FIXME: Visit explicitly-specified template arguments!
811f4a2713aSLionel Sambuc 
812f4a2713aSLionel Sambuc     // Visit the function parameters, if we have a function type.
813f4a2713aSLionel Sambuc     if (FTL && VisitFunctionTypeLoc(FTL, true))
814f4a2713aSLionel Sambuc       return true;
815f4a2713aSLionel Sambuc 
816f4a2713aSLionel Sambuc     // FIXME: Attributes?
817f4a2713aSLionel Sambuc   }
818f4a2713aSLionel Sambuc 
819f4a2713aSLionel Sambuc   if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820f4a2713aSLionel Sambuc     if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821f4a2713aSLionel Sambuc       // Find the initializers that were written in the source.
822f4a2713aSLionel Sambuc       SmallVector<CXXCtorInitializer *, 4> WrittenInits;
823*0a6a1f1dSLionel Sambuc       for (auto *I : Constructor->inits()) {
824*0a6a1f1dSLionel Sambuc         if (!I->isWritten())
825f4a2713aSLionel Sambuc           continue;
826f4a2713aSLionel Sambuc 
827*0a6a1f1dSLionel Sambuc         WrittenInits.push_back(I);
828f4a2713aSLionel Sambuc       }
829f4a2713aSLionel Sambuc 
830f4a2713aSLionel Sambuc       // Sort the initializers in source order
831f4a2713aSLionel Sambuc       llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832f4a2713aSLionel Sambuc                            &CompareCXXCtorInitializers);
833f4a2713aSLionel Sambuc 
834f4a2713aSLionel Sambuc       // Visit the initializers in source order
835f4a2713aSLionel Sambuc       for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836f4a2713aSLionel Sambuc         CXXCtorInitializer *Init = WrittenInits[I];
837f4a2713aSLionel Sambuc         if (Init->isAnyMemberInitializer()) {
838f4a2713aSLionel Sambuc           if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839f4a2713aSLionel Sambuc                                         Init->getMemberLocation(), TU)))
840f4a2713aSLionel Sambuc             return true;
841f4a2713aSLionel Sambuc         } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842f4a2713aSLionel Sambuc           if (Visit(TInfo->getTypeLoc()))
843f4a2713aSLionel Sambuc             return true;
844f4a2713aSLionel Sambuc         }
845f4a2713aSLionel Sambuc 
846f4a2713aSLionel Sambuc         // Visit the initializer value.
847f4a2713aSLionel Sambuc         if (Expr *Initializer = Init->getInit())
848f4a2713aSLionel Sambuc           if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849f4a2713aSLionel Sambuc             return true;
850f4a2713aSLionel Sambuc       }
851f4a2713aSLionel Sambuc     }
852f4a2713aSLionel Sambuc 
853f4a2713aSLionel Sambuc     if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854f4a2713aSLionel Sambuc       return true;
855f4a2713aSLionel Sambuc   }
856f4a2713aSLionel Sambuc 
857f4a2713aSLionel Sambuc   return false;
858f4a2713aSLionel Sambuc }
859f4a2713aSLionel Sambuc 
VisitFieldDecl(FieldDecl * D)860f4a2713aSLionel Sambuc bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861f4a2713aSLionel Sambuc   if (VisitDeclaratorDecl(D))
862f4a2713aSLionel Sambuc     return true;
863f4a2713aSLionel Sambuc 
864f4a2713aSLionel Sambuc   if (Expr *BitWidth = D->getBitWidth())
865f4a2713aSLionel Sambuc     return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866f4a2713aSLionel Sambuc 
867f4a2713aSLionel Sambuc   return false;
868f4a2713aSLionel Sambuc }
869f4a2713aSLionel Sambuc 
VisitVarDecl(VarDecl * D)870f4a2713aSLionel Sambuc bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871f4a2713aSLionel Sambuc   if (VisitDeclaratorDecl(D))
872f4a2713aSLionel Sambuc     return true;
873f4a2713aSLionel Sambuc 
874f4a2713aSLionel Sambuc   if (Expr *Init = D->getInit())
875f4a2713aSLionel Sambuc     return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876f4a2713aSLionel Sambuc 
877f4a2713aSLionel Sambuc   return false;
878f4a2713aSLionel Sambuc }
879f4a2713aSLionel Sambuc 
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)880f4a2713aSLionel Sambuc bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881f4a2713aSLionel Sambuc   if (VisitDeclaratorDecl(D))
882f4a2713aSLionel Sambuc     return true;
883f4a2713aSLionel Sambuc 
884f4a2713aSLionel Sambuc   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885f4a2713aSLionel Sambuc     if (Expr *DefArg = D->getDefaultArgument())
886f4a2713aSLionel Sambuc       return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887f4a2713aSLionel Sambuc 
888f4a2713aSLionel Sambuc   return false;
889f4a2713aSLionel Sambuc }
890f4a2713aSLionel Sambuc 
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)891f4a2713aSLionel Sambuc bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892f4a2713aSLionel Sambuc   // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893f4a2713aSLionel Sambuc   // before visiting these template parameters.
894f4a2713aSLionel Sambuc   if (VisitTemplateParameters(D->getTemplateParameters()))
895f4a2713aSLionel Sambuc     return true;
896f4a2713aSLionel Sambuc 
897f4a2713aSLionel Sambuc   return VisitFunctionDecl(D->getTemplatedDecl());
898f4a2713aSLionel Sambuc }
899f4a2713aSLionel Sambuc 
VisitClassTemplateDecl(ClassTemplateDecl * D)900f4a2713aSLionel Sambuc bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901f4a2713aSLionel Sambuc   // FIXME: Visit the "outer" template parameter lists on the TagDecl
902f4a2713aSLionel Sambuc   // before visiting these template parameters.
903f4a2713aSLionel Sambuc   if (VisitTemplateParameters(D->getTemplateParameters()))
904f4a2713aSLionel Sambuc     return true;
905f4a2713aSLionel Sambuc 
906f4a2713aSLionel Sambuc   return VisitCXXRecordDecl(D->getTemplatedDecl());
907f4a2713aSLionel Sambuc }
908f4a2713aSLionel Sambuc 
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)909f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910f4a2713aSLionel Sambuc   if (VisitTemplateParameters(D->getTemplateParameters()))
911f4a2713aSLionel Sambuc     return true;
912f4a2713aSLionel Sambuc 
913f4a2713aSLionel Sambuc   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914f4a2713aSLionel Sambuc       VisitTemplateArgumentLoc(D->getDefaultArgument()))
915f4a2713aSLionel Sambuc     return true;
916f4a2713aSLionel Sambuc 
917f4a2713aSLionel Sambuc   return false;
918f4a2713aSLionel Sambuc }
919f4a2713aSLionel Sambuc 
VisitObjCMethodDecl(ObjCMethodDecl * ND)920f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
921*0a6a1f1dSLionel Sambuc   if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
922f4a2713aSLionel Sambuc     if (Visit(TSInfo->getTypeLoc()))
923f4a2713aSLionel Sambuc       return true;
924f4a2713aSLionel Sambuc 
925*0a6a1f1dSLionel Sambuc   for (const auto *P : ND->params()) {
926*0a6a1f1dSLionel Sambuc     if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
927f4a2713aSLionel Sambuc       return true;
928f4a2713aSLionel Sambuc   }
929f4a2713aSLionel Sambuc 
930f4a2713aSLionel Sambuc   if (ND->isThisDeclarationADefinition() &&
931f4a2713aSLionel Sambuc       Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
932f4a2713aSLionel Sambuc     return true;
933f4a2713aSLionel Sambuc 
934f4a2713aSLionel Sambuc   return false;
935f4a2713aSLionel Sambuc }
936f4a2713aSLionel Sambuc 
937f4a2713aSLionel Sambuc template <typename DeclIt>
addRangedDeclsInContainer(DeclIt * DI_current,DeclIt DE_current,SourceManager & SM,SourceLocation EndLoc,SmallVectorImpl<Decl * > & Decls)938f4a2713aSLionel Sambuc static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
939f4a2713aSLionel Sambuc                                       SourceManager &SM, SourceLocation EndLoc,
940f4a2713aSLionel Sambuc                                       SmallVectorImpl<Decl *> &Decls) {
941f4a2713aSLionel Sambuc   DeclIt next = *DI_current;
942f4a2713aSLionel Sambuc   while (++next != DE_current) {
943f4a2713aSLionel Sambuc     Decl *D_next = *next;
944f4a2713aSLionel Sambuc     if (!D_next)
945f4a2713aSLionel Sambuc       break;
946f4a2713aSLionel Sambuc     SourceLocation L = D_next->getLocStart();
947f4a2713aSLionel Sambuc     if (!L.isValid())
948f4a2713aSLionel Sambuc       break;
949f4a2713aSLionel Sambuc     if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
950f4a2713aSLionel Sambuc       *DI_current = next;
951f4a2713aSLionel Sambuc       Decls.push_back(D_next);
952f4a2713aSLionel Sambuc       continue;
953f4a2713aSLionel Sambuc     }
954f4a2713aSLionel Sambuc     break;
955f4a2713aSLionel Sambuc   }
956f4a2713aSLionel Sambuc }
957f4a2713aSLionel Sambuc 
VisitObjCContainerDecl(ObjCContainerDecl * D)958f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959f4a2713aSLionel Sambuc   // FIXME: Eventually convert back to just 'VisitDeclContext()'.  Essentially
960f4a2713aSLionel Sambuc   // an @implementation can lexically contain Decls that are not properly
961f4a2713aSLionel Sambuc   // nested in the AST.  When we identify such cases, we need to retrofit
962f4a2713aSLionel Sambuc   // this nesting here.
963f4a2713aSLionel Sambuc   if (!DI_current && !FileDI_current)
964f4a2713aSLionel Sambuc     return VisitDeclContext(D);
965f4a2713aSLionel Sambuc 
966f4a2713aSLionel Sambuc   // Scan the Decls that immediately come after the container
967f4a2713aSLionel Sambuc   // in the current DeclContext.  If any fall within the
968f4a2713aSLionel Sambuc   // container's lexical region, stash them into a vector
969f4a2713aSLionel Sambuc   // for later processing.
970f4a2713aSLionel Sambuc   SmallVector<Decl *, 24> DeclsInContainer;
971f4a2713aSLionel Sambuc   SourceLocation EndLoc = D->getSourceRange().getEnd();
972f4a2713aSLionel Sambuc   SourceManager &SM = AU->getSourceManager();
973f4a2713aSLionel Sambuc   if (EndLoc.isValid()) {
974f4a2713aSLionel Sambuc     if (DI_current) {
975f4a2713aSLionel Sambuc       addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976f4a2713aSLionel Sambuc                                 DeclsInContainer);
977f4a2713aSLionel Sambuc     } else {
978f4a2713aSLionel Sambuc       addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979f4a2713aSLionel Sambuc                                 DeclsInContainer);
980f4a2713aSLionel Sambuc     }
981f4a2713aSLionel Sambuc   }
982f4a2713aSLionel Sambuc 
983f4a2713aSLionel Sambuc   // The common case.
984f4a2713aSLionel Sambuc   if (DeclsInContainer.empty())
985f4a2713aSLionel Sambuc     return VisitDeclContext(D);
986f4a2713aSLionel Sambuc 
987f4a2713aSLionel Sambuc   // Get all the Decls in the DeclContext, and sort them with the
988f4a2713aSLionel Sambuc   // additional ones we've collected.  Then visit them.
989*0a6a1f1dSLionel Sambuc   for (auto *SubDecl : D->decls()) {
990*0a6a1f1dSLionel Sambuc     if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
991*0a6a1f1dSLionel Sambuc         SubDecl->getLocStart().isInvalid())
992f4a2713aSLionel Sambuc       continue;
993*0a6a1f1dSLionel Sambuc     DeclsInContainer.push_back(SubDecl);
994f4a2713aSLionel Sambuc   }
995f4a2713aSLionel Sambuc 
996f4a2713aSLionel Sambuc   // Now sort the Decls so that they appear in lexical order.
997f4a2713aSLionel Sambuc   std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
998*0a6a1f1dSLionel Sambuc             [&SM](Decl *A, Decl *B) {
999*0a6a1f1dSLionel Sambuc     SourceLocation L_A = A->getLocStart();
1000*0a6a1f1dSLionel Sambuc     SourceLocation L_B = B->getLocStart();
1001*0a6a1f1dSLionel Sambuc     assert(L_A.isValid() && L_B.isValid());
1002*0a6a1f1dSLionel Sambuc     return SM.isBeforeInTranslationUnit(L_A, L_B);
1003*0a6a1f1dSLionel Sambuc   });
1004f4a2713aSLionel Sambuc 
1005f4a2713aSLionel Sambuc   // Now visit the decls.
1006f4a2713aSLionel Sambuc   for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1007f4a2713aSLionel Sambuc          E = DeclsInContainer.end(); I != E; ++I) {
1008f4a2713aSLionel Sambuc     CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
1009f4a2713aSLionel Sambuc     const Optional<bool> &V = shouldVisitCursor(Cursor);
1010f4a2713aSLionel Sambuc     if (!V.hasValue())
1011f4a2713aSLionel Sambuc       continue;
1012f4a2713aSLionel Sambuc     if (!V.getValue())
1013f4a2713aSLionel Sambuc       return false;
1014f4a2713aSLionel Sambuc     if (Visit(Cursor, true))
1015f4a2713aSLionel Sambuc       return true;
1016f4a2713aSLionel Sambuc   }
1017f4a2713aSLionel Sambuc   return false;
1018f4a2713aSLionel Sambuc }
1019f4a2713aSLionel Sambuc 
VisitObjCCategoryDecl(ObjCCategoryDecl * ND)1020f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1021f4a2713aSLionel Sambuc   if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1022f4a2713aSLionel Sambuc                                    TU)))
1023f4a2713aSLionel Sambuc     return true;
1024f4a2713aSLionel Sambuc 
1025f4a2713aSLionel Sambuc   ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1026f4a2713aSLionel Sambuc   for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1027f4a2713aSLionel Sambuc          E = ND->protocol_end(); I != E; ++I, ++PL)
1028f4a2713aSLionel Sambuc     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1029f4a2713aSLionel Sambuc       return true;
1030f4a2713aSLionel Sambuc 
1031f4a2713aSLionel Sambuc   return VisitObjCContainerDecl(ND);
1032f4a2713aSLionel Sambuc }
1033f4a2713aSLionel Sambuc 
VisitObjCProtocolDecl(ObjCProtocolDecl * PID)1034f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1035f4a2713aSLionel Sambuc   if (!PID->isThisDeclarationADefinition())
1036f4a2713aSLionel Sambuc     return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1037f4a2713aSLionel Sambuc 
1038f4a2713aSLionel Sambuc   ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1039f4a2713aSLionel Sambuc   for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1040f4a2713aSLionel Sambuc        E = PID->protocol_end(); I != E; ++I, ++PL)
1041f4a2713aSLionel Sambuc     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1042f4a2713aSLionel Sambuc       return true;
1043f4a2713aSLionel Sambuc 
1044f4a2713aSLionel Sambuc   return VisitObjCContainerDecl(PID);
1045f4a2713aSLionel Sambuc }
1046f4a2713aSLionel Sambuc 
VisitObjCPropertyDecl(ObjCPropertyDecl * PD)1047f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1048f4a2713aSLionel Sambuc   if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1049f4a2713aSLionel Sambuc     return true;
1050f4a2713aSLionel Sambuc 
1051f4a2713aSLionel Sambuc   // FIXME: This implements a workaround with @property declarations also being
1052f4a2713aSLionel Sambuc   // installed in the DeclContext for the @interface.  Eventually this code
1053f4a2713aSLionel Sambuc   // should be removed.
1054f4a2713aSLionel Sambuc   ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1055f4a2713aSLionel Sambuc   if (!CDecl || !CDecl->IsClassExtension())
1056f4a2713aSLionel Sambuc     return false;
1057f4a2713aSLionel Sambuc 
1058f4a2713aSLionel Sambuc   ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1059f4a2713aSLionel Sambuc   if (!ID)
1060f4a2713aSLionel Sambuc     return false;
1061f4a2713aSLionel Sambuc 
1062f4a2713aSLionel Sambuc   IdentifierInfo *PropertyId = PD->getIdentifier();
1063f4a2713aSLionel Sambuc   ObjCPropertyDecl *prevDecl =
1064f4a2713aSLionel Sambuc     ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1065f4a2713aSLionel Sambuc 
1066f4a2713aSLionel Sambuc   if (!prevDecl)
1067f4a2713aSLionel Sambuc     return false;
1068f4a2713aSLionel Sambuc 
1069f4a2713aSLionel Sambuc   // Visit synthesized methods since they will be skipped when visiting
1070f4a2713aSLionel Sambuc   // the @interface.
1071f4a2713aSLionel Sambuc   if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1072f4a2713aSLionel Sambuc     if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1073f4a2713aSLionel Sambuc       if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1074f4a2713aSLionel Sambuc         return true;
1075f4a2713aSLionel Sambuc 
1076f4a2713aSLionel Sambuc   if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1077f4a2713aSLionel Sambuc     if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1078f4a2713aSLionel Sambuc       if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1079f4a2713aSLionel Sambuc         return true;
1080f4a2713aSLionel Sambuc 
1081f4a2713aSLionel Sambuc   return false;
1082f4a2713aSLionel Sambuc }
1083f4a2713aSLionel Sambuc 
VisitObjCInterfaceDecl(ObjCInterfaceDecl * D)1084f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1085f4a2713aSLionel Sambuc   if (!D->isThisDeclarationADefinition()) {
1086f4a2713aSLionel Sambuc     // Forward declaration is treated like a reference.
1087f4a2713aSLionel Sambuc     return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1088f4a2713aSLionel Sambuc   }
1089f4a2713aSLionel Sambuc 
1090f4a2713aSLionel Sambuc   // Issue callbacks for super class.
1091f4a2713aSLionel Sambuc   if (D->getSuperClass() &&
1092f4a2713aSLionel Sambuc       Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1093f4a2713aSLionel Sambuc                                         D->getSuperClassLoc(),
1094f4a2713aSLionel Sambuc                                         TU)))
1095f4a2713aSLionel Sambuc     return true;
1096f4a2713aSLionel Sambuc 
1097f4a2713aSLionel Sambuc   ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1098f4a2713aSLionel Sambuc   for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1099f4a2713aSLionel Sambuc          E = D->protocol_end(); I != E; ++I, ++PL)
1100f4a2713aSLionel Sambuc     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101f4a2713aSLionel Sambuc       return true;
1102f4a2713aSLionel Sambuc 
1103f4a2713aSLionel Sambuc   return VisitObjCContainerDecl(D);
1104f4a2713aSLionel Sambuc }
1105f4a2713aSLionel Sambuc 
VisitObjCImplDecl(ObjCImplDecl * D)1106f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1107f4a2713aSLionel Sambuc   return VisitObjCContainerDecl(D);
1108f4a2713aSLionel Sambuc }
1109f4a2713aSLionel Sambuc 
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)1110f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1111f4a2713aSLionel Sambuc   // 'ID' could be null when dealing with invalid code.
1112f4a2713aSLionel Sambuc   if (ObjCInterfaceDecl *ID = D->getClassInterface())
1113f4a2713aSLionel Sambuc     if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1114f4a2713aSLionel Sambuc       return true;
1115f4a2713aSLionel Sambuc 
1116f4a2713aSLionel Sambuc   return VisitObjCImplDecl(D);
1117f4a2713aSLionel Sambuc }
1118f4a2713aSLionel Sambuc 
VisitObjCImplementationDecl(ObjCImplementationDecl * D)1119f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1120f4a2713aSLionel Sambuc #if 0
1121f4a2713aSLionel Sambuc   // Issue callbacks for super class.
1122f4a2713aSLionel Sambuc   // FIXME: No source location information!
1123f4a2713aSLionel Sambuc   if (D->getSuperClass() &&
1124f4a2713aSLionel Sambuc       Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125f4a2713aSLionel Sambuc                                         D->getSuperClassLoc(),
1126f4a2713aSLionel Sambuc                                         TU)))
1127f4a2713aSLionel Sambuc     return true;
1128f4a2713aSLionel Sambuc #endif
1129f4a2713aSLionel Sambuc 
1130f4a2713aSLionel Sambuc   return VisitObjCImplDecl(D);
1131f4a2713aSLionel Sambuc }
1132f4a2713aSLionel Sambuc 
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * PD)1133f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1134f4a2713aSLionel Sambuc   if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1135f4a2713aSLionel Sambuc     if (PD->isIvarNameSpecified())
1136f4a2713aSLionel Sambuc       return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1137f4a2713aSLionel Sambuc 
1138f4a2713aSLionel Sambuc   return false;
1139f4a2713aSLionel Sambuc }
1140f4a2713aSLionel Sambuc 
VisitNamespaceDecl(NamespaceDecl * D)1141f4a2713aSLionel Sambuc bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1142f4a2713aSLionel Sambuc   return VisitDeclContext(D);
1143f4a2713aSLionel Sambuc }
1144f4a2713aSLionel Sambuc 
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)1145f4a2713aSLionel Sambuc bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1146f4a2713aSLionel Sambuc   // Visit nested-name-specifier.
1147f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1148f4a2713aSLionel Sambuc     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1149f4a2713aSLionel Sambuc       return true;
1150f4a2713aSLionel Sambuc 
1151f4a2713aSLionel Sambuc   return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1152f4a2713aSLionel Sambuc                                       D->getTargetNameLoc(), TU));
1153f4a2713aSLionel Sambuc }
1154f4a2713aSLionel Sambuc 
VisitUsingDecl(UsingDecl * D)1155f4a2713aSLionel Sambuc bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1156f4a2713aSLionel Sambuc   // Visit nested-name-specifier.
1157f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1158f4a2713aSLionel Sambuc     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1159f4a2713aSLionel Sambuc       return true;
1160f4a2713aSLionel Sambuc   }
1161f4a2713aSLionel Sambuc 
1162f4a2713aSLionel Sambuc   if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1163f4a2713aSLionel Sambuc     return true;
1164f4a2713aSLionel Sambuc 
1165f4a2713aSLionel Sambuc   return VisitDeclarationNameInfo(D->getNameInfo());
1166f4a2713aSLionel Sambuc }
1167f4a2713aSLionel Sambuc 
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)1168f4a2713aSLionel Sambuc bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1169f4a2713aSLionel Sambuc   // Visit nested-name-specifier.
1170f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1171f4a2713aSLionel Sambuc     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1172f4a2713aSLionel Sambuc       return true;
1173f4a2713aSLionel Sambuc 
1174f4a2713aSLionel Sambuc   return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1175f4a2713aSLionel Sambuc                                       D->getIdentLocation(), TU));
1176f4a2713aSLionel Sambuc }
1177f4a2713aSLionel Sambuc 
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)1178f4a2713aSLionel Sambuc bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1179f4a2713aSLionel Sambuc   // Visit nested-name-specifier.
1180f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1181f4a2713aSLionel Sambuc     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1182f4a2713aSLionel Sambuc       return true;
1183f4a2713aSLionel Sambuc   }
1184f4a2713aSLionel Sambuc 
1185f4a2713aSLionel Sambuc   return VisitDeclarationNameInfo(D->getNameInfo());
1186f4a2713aSLionel Sambuc }
1187f4a2713aSLionel Sambuc 
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)1188f4a2713aSLionel Sambuc bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1189f4a2713aSLionel Sambuc                                                UnresolvedUsingTypenameDecl *D) {
1190f4a2713aSLionel Sambuc   // Visit nested-name-specifier.
1191f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1192f4a2713aSLionel Sambuc     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1193f4a2713aSLionel Sambuc       return true;
1194f4a2713aSLionel Sambuc 
1195f4a2713aSLionel Sambuc   return false;
1196f4a2713aSLionel Sambuc }
1197f4a2713aSLionel Sambuc 
VisitDeclarationNameInfo(DeclarationNameInfo Name)1198f4a2713aSLionel Sambuc bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1199f4a2713aSLionel Sambuc   switch (Name.getName().getNameKind()) {
1200f4a2713aSLionel Sambuc   case clang::DeclarationName::Identifier:
1201f4a2713aSLionel Sambuc   case clang::DeclarationName::CXXLiteralOperatorName:
1202f4a2713aSLionel Sambuc   case clang::DeclarationName::CXXOperatorName:
1203f4a2713aSLionel Sambuc   case clang::DeclarationName::CXXUsingDirective:
1204f4a2713aSLionel Sambuc     return false;
1205f4a2713aSLionel Sambuc 
1206f4a2713aSLionel Sambuc   case clang::DeclarationName::CXXConstructorName:
1207f4a2713aSLionel Sambuc   case clang::DeclarationName::CXXDestructorName:
1208f4a2713aSLionel Sambuc   case clang::DeclarationName::CXXConversionFunctionName:
1209f4a2713aSLionel Sambuc     if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1210f4a2713aSLionel Sambuc       return Visit(TSInfo->getTypeLoc());
1211f4a2713aSLionel Sambuc     return false;
1212f4a2713aSLionel Sambuc 
1213f4a2713aSLionel Sambuc   case clang::DeclarationName::ObjCZeroArgSelector:
1214f4a2713aSLionel Sambuc   case clang::DeclarationName::ObjCOneArgSelector:
1215f4a2713aSLionel Sambuc   case clang::DeclarationName::ObjCMultiArgSelector:
1216f4a2713aSLionel Sambuc     // FIXME: Per-identifier location info?
1217f4a2713aSLionel Sambuc     return false;
1218f4a2713aSLionel Sambuc   }
1219f4a2713aSLionel Sambuc 
1220f4a2713aSLionel Sambuc   llvm_unreachable("Invalid DeclarationName::Kind!");
1221f4a2713aSLionel Sambuc }
1222f4a2713aSLionel Sambuc 
VisitNestedNameSpecifier(NestedNameSpecifier * NNS,SourceRange Range)1223f4a2713aSLionel Sambuc bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1224f4a2713aSLionel Sambuc                                              SourceRange Range) {
1225f4a2713aSLionel Sambuc   // FIXME: This whole routine is a hack to work around the lack of proper
1226f4a2713aSLionel Sambuc   // source information in nested-name-specifiers (PR5791). Since we do have
1227f4a2713aSLionel Sambuc   // a beginning source location, we can visit the first component of the
1228f4a2713aSLionel Sambuc   // nested-name-specifier, if it's a single-token component.
1229f4a2713aSLionel Sambuc   if (!NNS)
1230f4a2713aSLionel Sambuc     return false;
1231f4a2713aSLionel Sambuc 
1232f4a2713aSLionel Sambuc   // Get the first component in the nested-name-specifier.
1233f4a2713aSLionel Sambuc   while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1234f4a2713aSLionel Sambuc     NNS = Prefix;
1235f4a2713aSLionel Sambuc 
1236f4a2713aSLionel Sambuc   switch (NNS->getKind()) {
1237f4a2713aSLionel Sambuc   case NestedNameSpecifier::Namespace:
1238f4a2713aSLionel Sambuc     return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1239f4a2713aSLionel Sambuc                                         TU));
1240f4a2713aSLionel Sambuc 
1241f4a2713aSLionel Sambuc   case NestedNameSpecifier::NamespaceAlias:
1242f4a2713aSLionel Sambuc     return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1243f4a2713aSLionel Sambuc                                         Range.getBegin(), TU));
1244f4a2713aSLionel Sambuc 
1245f4a2713aSLionel Sambuc   case NestedNameSpecifier::TypeSpec: {
1246f4a2713aSLionel Sambuc     // If the type has a form where we know that the beginning of the source
1247f4a2713aSLionel Sambuc     // range matches up with a reference cursor. Visit the appropriate reference
1248f4a2713aSLionel Sambuc     // cursor.
1249f4a2713aSLionel Sambuc     const Type *T = NNS->getAsType();
1250f4a2713aSLionel Sambuc     if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1251f4a2713aSLionel Sambuc       return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1252f4a2713aSLionel Sambuc     if (const TagType *Tag = dyn_cast<TagType>(T))
1253f4a2713aSLionel Sambuc       return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1254f4a2713aSLionel Sambuc     if (const TemplateSpecializationType *TST
1255f4a2713aSLionel Sambuc                                       = dyn_cast<TemplateSpecializationType>(T))
1256f4a2713aSLionel Sambuc       return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1257f4a2713aSLionel Sambuc     break;
1258f4a2713aSLionel Sambuc   }
1259f4a2713aSLionel Sambuc 
1260f4a2713aSLionel Sambuc   case NestedNameSpecifier::TypeSpecWithTemplate:
1261f4a2713aSLionel Sambuc   case NestedNameSpecifier::Global:
1262f4a2713aSLionel Sambuc   case NestedNameSpecifier::Identifier:
1263*0a6a1f1dSLionel Sambuc   case NestedNameSpecifier::Super:
1264f4a2713aSLionel Sambuc     break;
1265f4a2713aSLionel Sambuc   }
1266f4a2713aSLionel Sambuc 
1267f4a2713aSLionel Sambuc   return false;
1268f4a2713aSLionel Sambuc }
1269f4a2713aSLionel Sambuc 
1270f4a2713aSLionel Sambuc bool
VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)1271f4a2713aSLionel Sambuc CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1272f4a2713aSLionel Sambuc   SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1273f4a2713aSLionel Sambuc   for (; Qualifier; Qualifier = Qualifier.getPrefix())
1274f4a2713aSLionel Sambuc     Qualifiers.push_back(Qualifier);
1275f4a2713aSLionel Sambuc 
1276f4a2713aSLionel Sambuc   while (!Qualifiers.empty()) {
1277f4a2713aSLionel Sambuc     NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1278f4a2713aSLionel Sambuc     NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1279f4a2713aSLionel Sambuc     switch (NNS->getKind()) {
1280f4a2713aSLionel Sambuc     case NestedNameSpecifier::Namespace:
1281f4a2713aSLionel Sambuc       if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1282f4a2713aSLionel Sambuc                                        Q.getLocalBeginLoc(),
1283f4a2713aSLionel Sambuc                                        TU)))
1284f4a2713aSLionel Sambuc         return true;
1285f4a2713aSLionel Sambuc 
1286f4a2713aSLionel Sambuc       break;
1287f4a2713aSLionel Sambuc 
1288f4a2713aSLionel Sambuc     case NestedNameSpecifier::NamespaceAlias:
1289f4a2713aSLionel Sambuc       if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1290f4a2713aSLionel Sambuc                                        Q.getLocalBeginLoc(),
1291f4a2713aSLionel Sambuc                                        TU)))
1292f4a2713aSLionel Sambuc         return true;
1293f4a2713aSLionel Sambuc 
1294f4a2713aSLionel Sambuc       break;
1295f4a2713aSLionel Sambuc 
1296f4a2713aSLionel Sambuc     case NestedNameSpecifier::TypeSpec:
1297f4a2713aSLionel Sambuc     case NestedNameSpecifier::TypeSpecWithTemplate:
1298f4a2713aSLionel Sambuc       if (Visit(Q.getTypeLoc()))
1299f4a2713aSLionel Sambuc         return true;
1300f4a2713aSLionel Sambuc 
1301f4a2713aSLionel Sambuc       break;
1302f4a2713aSLionel Sambuc 
1303f4a2713aSLionel Sambuc     case NestedNameSpecifier::Global:
1304f4a2713aSLionel Sambuc     case NestedNameSpecifier::Identifier:
1305*0a6a1f1dSLionel Sambuc     case NestedNameSpecifier::Super:
1306f4a2713aSLionel Sambuc       break;
1307f4a2713aSLionel Sambuc     }
1308f4a2713aSLionel Sambuc   }
1309f4a2713aSLionel Sambuc 
1310f4a2713aSLionel Sambuc   return false;
1311f4a2713aSLionel Sambuc }
1312f4a2713aSLionel Sambuc 
VisitTemplateParameters(const TemplateParameterList * Params)1313f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateParameters(
1314f4a2713aSLionel Sambuc                                           const TemplateParameterList *Params) {
1315f4a2713aSLionel Sambuc   if (!Params)
1316f4a2713aSLionel Sambuc     return false;
1317f4a2713aSLionel Sambuc 
1318f4a2713aSLionel Sambuc   for (TemplateParameterList::const_iterator P = Params->begin(),
1319f4a2713aSLionel Sambuc                                           PEnd = Params->end();
1320f4a2713aSLionel Sambuc        P != PEnd; ++P) {
1321f4a2713aSLionel Sambuc     if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1322f4a2713aSLionel Sambuc       return true;
1323f4a2713aSLionel Sambuc   }
1324f4a2713aSLionel Sambuc 
1325f4a2713aSLionel Sambuc   return false;
1326f4a2713aSLionel Sambuc }
1327f4a2713aSLionel Sambuc 
VisitTemplateName(TemplateName Name,SourceLocation Loc)1328f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1329f4a2713aSLionel Sambuc   switch (Name.getKind()) {
1330f4a2713aSLionel Sambuc   case TemplateName::Template:
1331f4a2713aSLionel Sambuc     return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1332f4a2713aSLionel Sambuc 
1333f4a2713aSLionel Sambuc   case TemplateName::OverloadedTemplate:
1334f4a2713aSLionel Sambuc     // Visit the overloaded template set.
1335f4a2713aSLionel Sambuc     if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1336f4a2713aSLionel Sambuc       return true;
1337f4a2713aSLionel Sambuc 
1338f4a2713aSLionel Sambuc     return false;
1339f4a2713aSLionel Sambuc 
1340f4a2713aSLionel Sambuc   case TemplateName::DependentTemplate:
1341f4a2713aSLionel Sambuc     // FIXME: Visit nested-name-specifier.
1342f4a2713aSLionel Sambuc     return false;
1343f4a2713aSLionel Sambuc 
1344f4a2713aSLionel Sambuc   case TemplateName::QualifiedTemplate:
1345f4a2713aSLionel Sambuc     // FIXME: Visit nested-name-specifier.
1346f4a2713aSLionel Sambuc     return Visit(MakeCursorTemplateRef(
1347f4a2713aSLionel Sambuc                                   Name.getAsQualifiedTemplateName()->getDecl(),
1348f4a2713aSLionel Sambuc                                        Loc, TU));
1349f4a2713aSLionel Sambuc 
1350f4a2713aSLionel Sambuc   case TemplateName::SubstTemplateTemplateParm:
1351f4a2713aSLionel Sambuc     return Visit(MakeCursorTemplateRef(
1352f4a2713aSLionel Sambuc                          Name.getAsSubstTemplateTemplateParm()->getParameter(),
1353f4a2713aSLionel Sambuc                                        Loc, TU));
1354f4a2713aSLionel Sambuc 
1355f4a2713aSLionel Sambuc   case TemplateName::SubstTemplateTemplateParmPack:
1356f4a2713aSLionel Sambuc     return Visit(MakeCursorTemplateRef(
1357f4a2713aSLionel Sambuc                   Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1358f4a2713aSLionel Sambuc                                        Loc, TU));
1359f4a2713aSLionel Sambuc   }
1360f4a2713aSLionel Sambuc 
1361f4a2713aSLionel Sambuc   llvm_unreachable("Invalid TemplateName::Kind!");
1362f4a2713aSLionel Sambuc }
1363f4a2713aSLionel Sambuc 
VisitTemplateArgumentLoc(const TemplateArgumentLoc & TAL)1364f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1365f4a2713aSLionel Sambuc   switch (TAL.getArgument().getKind()) {
1366f4a2713aSLionel Sambuc   case TemplateArgument::Null:
1367f4a2713aSLionel Sambuc   case TemplateArgument::Integral:
1368f4a2713aSLionel Sambuc   case TemplateArgument::Pack:
1369f4a2713aSLionel Sambuc     return false;
1370f4a2713aSLionel Sambuc 
1371f4a2713aSLionel Sambuc   case TemplateArgument::Type:
1372f4a2713aSLionel Sambuc     if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1373f4a2713aSLionel Sambuc       return Visit(TSInfo->getTypeLoc());
1374f4a2713aSLionel Sambuc     return false;
1375f4a2713aSLionel Sambuc 
1376f4a2713aSLionel Sambuc   case TemplateArgument::Declaration:
1377f4a2713aSLionel Sambuc     if (Expr *E = TAL.getSourceDeclExpression())
1378f4a2713aSLionel Sambuc       return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379f4a2713aSLionel Sambuc     return false;
1380f4a2713aSLionel Sambuc 
1381f4a2713aSLionel Sambuc   case TemplateArgument::NullPtr:
1382f4a2713aSLionel Sambuc     if (Expr *E = TAL.getSourceNullPtrExpression())
1383f4a2713aSLionel Sambuc       return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1384f4a2713aSLionel Sambuc     return false;
1385f4a2713aSLionel Sambuc 
1386f4a2713aSLionel Sambuc   case TemplateArgument::Expression:
1387f4a2713aSLionel Sambuc     if (Expr *E = TAL.getSourceExpression())
1388f4a2713aSLionel Sambuc       return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1389f4a2713aSLionel Sambuc     return false;
1390f4a2713aSLionel Sambuc 
1391f4a2713aSLionel Sambuc   case TemplateArgument::Template:
1392f4a2713aSLionel Sambuc   case TemplateArgument::TemplateExpansion:
1393f4a2713aSLionel Sambuc     if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1394f4a2713aSLionel Sambuc       return true;
1395f4a2713aSLionel Sambuc 
1396f4a2713aSLionel Sambuc     return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1397f4a2713aSLionel Sambuc                              TAL.getTemplateNameLoc());
1398f4a2713aSLionel Sambuc   }
1399f4a2713aSLionel Sambuc 
1400f4a2713aSLionel Sambuc   llvm_unreachable("Invalid TemplateArgument::Kind!");
1401f4a2713aSLionel Sambuc }
1402f4a2713aSLionel Sambuc 
VisitLinkageSpecDecl(LinkageSpecDecl * D)1403f4a2713aSLionel Sambuc bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1404f4a2713aSLionel Sambuc   return VisitDeclContext(D);
1405f4a2713aSLionel Sambuc }
1406f4a2713aSLionel Sambuc 
VisitQualifiedTypeLoc(QualifiedTypeLoc TL)1407f4a2713aSLionel Sambuc bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1408f4a2713aSLionel Sambuc   return Visit(TL.getUnqualifiedLoc());
1409f4a2713aSLionel Sambuc }
1410f4a2713aSLionel Sambuc 
VisitBuiltinTypeLoc(BuiltinTypeLoc TL)1411f4a2713aSLionel Sambuc bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1412f4a2713aSLionel Sambuc   ASTContext &Context = AU->getASTContext();
1413f4a2713aSLionel Sambuc 
1414f4a2713aSLionel Sambuc   // Some builtin types (such as Objective-C's "id", "sel", and
1415f4a2713aSLionel Sambuc   // "Class") have associated declarations. Create cursors for those.
1416f4a2713aSLionel Sambuc   QualType VisitType;
1417f4a2713aSLionel Sambuc   switch (TL.getTypePtr()->getKind()) {
1418f4a2713aSLionel Sambuc 
1419f4a2713aSLionel Sambuc   case BuiltinType::Void:
1420f4a2713aSLionel Sambuc   case BuiltinType::NullPtr:
1421f4a2713aSLionel Sambuc   case BuiltinType::Dependent:
1422f4a2713aSLionel Sambuc   case BuiltinType::OCLImage1d:
1423f4a2713aSLionel Sambuc   case BuiltinType::OCLImage1dArray:
1424f4a2713aSLionel Sambuc   case BuiltinType::OCLImage1dBuffer:
1425f4a2713aSLionel Sambuc   case BuiltinType::OCLImage2d:
1426f4a2713aSLionel Sambuc   case BuiltinType::OCLImage2dArray:
1427f4a2713aSLionel Sambuc   case BuiltinType::OCLImage3d:
1428f4a2713aSLionel Sambuc   case BuiltinType::OCLSampler:
1429f4a2713aSLionel Sambuc   case BuiltinType::OCLEvent:
1430f4a2713aSLionel Sambuc #define BUILTIN_TYPE(Id, SingletonId)
1431f4a2713aSLionel Sambuc #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1432f4a2713aSLionel Sambuc #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1433f4a2713aSLionel Sambuc #define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1434f4a2713aSLionel Sambuc #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1435f4a2713aSLionel Sambuc #include "clang/AST/BuiltinTypes.def"
1436f4a2713aSLionel Sambuc     break;
1437f4a2713aSLionel Sambuc 
1438f4a2713aSLionel Sambuc   case BuiltinType::ObjCId:
1439f4a2713aSLionel Sambuc     VisitType = Context.getObjCIdType();
1440f4a2713aSLionel Sambuc     break;
1441f4a2713aSLionel Sambuc 
1442f4a2713aSLionel Sambuc   case BuiltinType::ObjCClass:
1443f4a2713aSLionel Sambuc     VisitType = Context.getObjCClassType();
1444f4a2713aSLionel Sambuc     break;
1445f4a2713aSLionel Sambuc 
1446f4a2713aSLionel Sambuc   case BuiltinType::ObjCSel:
1447f4a2713aSLionel Sambuc     VisitType = Context.getObjCSelType();
1448f4a2713aSLionel Sambuc     break;
1449f4a2713aSLionel Sambuc   }
1450f4a2713aSLionel Sambuc 
1451f4a2713aSLionel Sambuc   if (!VisitType.isNull()) {
1452f4a2713aSLionel Sambuc     if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1453f4a2713aSLionel Sambuc       return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1454f4a2713aSLionel Sambuc                                      TU));
1455f4a2713aSLionel Sambuc   }
1456f4a2713aSLionel Sambuc 
1457f4a2713aSLionel Sambuc   return false;
1458f4a2713aSLionel Sambuc }
1459f4a2713aSLionel Sambuc 
VisitTypedefTypeLoc(TypedefTypeLoc TL)1460f4a2713aSLionel Sambuc bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1461f4a2713aSLionel Sambuc   return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1462f4a2713aSLionel Sambuc }
1463f4a2713aSLionel Sambuc 
VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL)1464f4a2713aSLionel Sambuc bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1465f4a2713aSLionel Sambuc   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1466f4a2713aSLionel Sambuc }
1467f4a2713aSLionel Sambuc 
VisitTagTypeLoc(TagTypeLoc TL)1468f4a2713aSLionel Sambuc bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1469f4a2713aSLionel Sambuc   if (TL.isDefinition())
1470f4a2713aSLionel Sambuc     return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1471f4a2713aSLionel Sambuc 
1472f4a2713aSLionel Sambuc   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1473f4a2713aSLionel Sambuc }
1474f4a2713aSLionel Sambuc 
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)1475f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1476f4a2713aSLionel Sambuc   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1477f4a2713aSLionel Sambuc }
1478f4a2713aSLionel Sambuc 
VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL)1479f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1480f4a2713aSLionel Sambuc   if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1481f4a2713aSLionel Sambuc     return true;
1482f4a2713aSLionel Sambuc 
1483f4a2713aSLionel Sambuc   return false;
1484f4a2713aSLionel Sambuc }
1485f4a2713aSLionel Sambuc 
VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL)1486f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1487f4a2713aSLionel Sambuc   if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1488f4a2713aSLionel Sambuc     return true;
1489f4a2713aSLionel Sambuc 
1490f4a2713aSLionel Sambuc   for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1491f4a2713aSLionel Sambuc     if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1492f4a2713aSLionel Sambuc                                         TU)))
1493f4a2713aSLionel Sambuc       return true;
1494f4a2713aSLionel Sambuc   }
1495f4a2713aSLionel Sambuc 
1496f4a2713aSLionel Sambuc   return false;
1497f4a2713aSLionel Sambuc }
1498f4a2713aSLionel Sambuc 
VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL)1499f4a2713aSLionel Sambuc bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1500f4a2713aSLionel Sambuc   return Visit(TL.getPointeeLoc());
1501f4a2713aSLionel Sambuc }
1502f4a2713aSLionel Sambuc 
VisitParenTypeLoc(ParenTypeLoc TL)1503f4a2713aSLionel Sambuc bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1504f4a2713aSLionel Sambuc   return Visit(TL.getInnerLoc());
1505f4a2713aSLionel Sambuc }
1506f4a2713aSLionel Sambuc 
VisitPointerTypeLoc(PointerTypeLoc TL)1507f4a2713aSLionel Sambuc bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1508f4a2713aSLionel Sambuc   return Visit(TL.getPointeeLoc());
1509f4a2713aSLionel Sambuc }
1510f4a2713aSLionel Sambuc 
VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL)1511f4a2713aSLionel Sambuc bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1512f4a2713aSLionel Sambuc   return Visit(TL.getPointeeLoc());
1513f4a2713aSLionel Sambuc }
1514f4a2713aSLionel Sambuc 
VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL)1515f4a2713aSLionel Sambuc bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1516f4a2713aSLionel Sambuc   return Visit(TL.getPointeeLoc());
1517f4a2713aSLionel Sambuc }
1518f4a2713aSLionel Sambuc 
VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL)1519f4a2713aSLionel Sambuc bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1520f4a2713aSLionel Sambuc   return Visit(TL.getPointeeLoc());
1521f4a2713aSLionel Sambuc }
1522f4a2713aSLionel Sambuc 
VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL)1523f4a2713aSLionel Sambuc bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1524f4a2713aSLionel Sambuc   return Visit(TL.getPointeeLoc());
1525f4a2713aSLionel Sambuc }
1526f4a2713aSLionel Sambuc 
VisitAttributedTypeLoc(AttributedTypeLoc TL)1527f4a2713aSLionel Sambuc bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1528f4a2713aSLionel Sambuc   return Visit(TL.getModifiedLoc());
1529f4a2713aSLionel Sambuc }
1530f4a2713aSLionel Sambuc 
VisitFunctionTypeLoc(FunctionTypeLoc TL,bool SkipResultType)1531f4a2713aSLionel Sambuc bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1532f4a2713aSLionel Sambuc                                          bool SkipResultType) {
1533*0a6a1f1dSLionel Sambuc   if (!SkipResultType && Visit(TL.getReturnLoc()))
1534f4a2713aSLionel Sambuc     return true;
1535f4a2713aSLionel Sambuc 
1536*0a6a1f1dSLionel Sambuc   for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1537*0a6a1f1dSLionel Sambuc     if (Decl *D = TL.getParam(I))
1538f4a2713aSLionel Sambuc       if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1539f4a2713aSLionel Sambuc         return true;
1540f4a2713aSLionel Sambuc 
1541f4a2713aSLionel Sambuc   return false;
1542f4a2713aSLionel Sambuc }
1543f4a2713aSLionel Sambuc 
VisitArrayTypeLoc(ArrayTypeLoc TL)1544f4a2713aSLionel Sambuc bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1545f4a2713aSLionel Sambuc   if (Visit(TL.getElementLoc()))
1546f4a2713aSLionel Sambuc     return true;
1547f4a2713aSLionel Sambuc 
1548f4a2713aSLionel Sambuc   if (Expr *Size = TL.getSizeExpr())
1549f4a2713aSLionel Sambuc     return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1550f4a2713aSLionel Sambuc 
1551f4a2713aSLionel Sambuc   return false;
1552f4a2713aSLionel Sambuc }
1553f4a2713aSLionel Sambuc 
VisitDecayedTypeLoc(DecayedTypeLoc TL)1554f4a2713aSLionel Sambuc bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1555f4a2713aSLionel Sambuc   return Visit(TL.getOriginalLoc());
1556f4a2713aSLionel Sambuc }
1557f4a2713aSLionel Sambuc 
VisitAdjustedTypeLoc(AdjustedTypeLoc TL)1558*0a6a1f1dSLionel Sambuc bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1559*0a6a1f1dSLionel Sambuc   return Visit(TL.getOriginalLoc());
1560*0a6a1f1dSLionel Sambuc }
1561*0a6a1f1dSLionel Sambuc 
VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)1562f4a2713aSLionel Sambuc bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1563f4a2713aSLionel Sambuc                                              TemplateSpecializationTypeLoc TL) {
1564f4a2713aSLionel Sambuc   // Visit the template name.
1565f4a2713aSLionel Sambuc   if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1566f4a2713aSLionel Sambuc                         TL.getTemplateNameLoc()))
1567f4a2713aSLionel Sambuc     return true;
1568f4a2713aSLionel Sambuc 
1569f4a2713aSLionel Sambuc   // Visit the template arguments.
1570f4a2713aSLionel Sambuc   for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1571f4a2713aSLionel Sambuc     if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1572f4a2713aSLionel Sambuc       return true;
1573f4a2713aSLionel Sambuc 
1574f4a2713aSLionel Sambuc   return false;
1575f4a2713aSLionel Sambuc }
1576f4a2713aSLionel Sambuc 
VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL)1577f4a2713aSLionel Sambuc bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1578f4a2713aSLionel Sambuc   return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1579f4a2713aSLionel Sambuc }
1580f4a2713aSLionel Sambuc 
VisitTypeOfTypeLoc(TypeOfTypeLoc TL)1581f4a2713aSLionel Sambuc bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1582f4a2713aSLionel Sambuc   if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1583f4a2713aSLionel Sambuc     return Visit(TSInfo->getTypeLoc());
1584f4a2713aSLionel Sambuc 
1585f4a2713aSLionel Sambuc   return false;
1586f4a2713aSLionel Sambuc }
1587f4a2713aSLionel Sambuc 
VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL)1588f4a2713aSLionel Sambuc bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1589f4a2713aSLionel Sambuc   if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1590f4a2713aSLionel Sambuc     return Visit(TSInfo->getTypeLoc());
1591f4a2713aSLionel Sambuc 
1592f4a2713aSLionel Sambuc   return false;
1593f4a2713aSLionel Sambuc }
1594f4a2713aSLionel Sambuc 
VisitDependentNameTypeLoc(DependentNameTypeLoc TL)1595f4a2713aSLionel Sambuc bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1596f4a2713aSLionel Sambuc   if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1597f4a2713aSLionel Sambuc     return true;
1598f4a2713aSLionel Sambuc 
1599f4a2713aSLionel Sambuc   return false;
1600f4a2713aSLionel Sambuc }
1601f4a2713aSLionel Sambuc 
VisitDependentTemplateSpecializationTypeLoc(DependentTemplateSpecializationTypeLoc TL)1602f4a2713aSLionel Sambuc bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1603f4a2713aSLionel Sambuc                                     DependentTemplateSpecializationTypeLoc TL) {
1604f4a2713aSLionel Sambuc   // Visit the nested-name-specifier, if there is one.
1605f4a2713aSLionel Sambuc   if (TL.getQualifierLoc() &&
1606f4a2713aSLionel Sambuc       VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1607f4a2713aSLionel Sambuc     return true;
1608f4a2713aSLionel Sambuc 
1609f4a2713aSLionel Sambuc   // Visit the template arguments.
1610f4a2713aSLionel Sambuc   for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1611f4a2713aSLionel Sambuc     if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1612f4a2713aSLionel Sambuc       return true;
1613f4a2713aSLionel Sambuc 
1614f4a2713aSLionel Sambuc   return false;
1615f4a2713aSLionel Sambuc }
1616f4a2713aSLionel Sambuc 
VisitElaboratedTypeLoc(ElaboratedTypeLoc TL)1617f4a2713aSLionel Sambuc bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1618f4a2713aSLionel Sambuc   if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1619f4a2713aSLionel Sambuc     return true;
1620f4a2713aSLionel Sambuc 
1621f4a2713aSLionel Sambuc   return Visit(TL.getNamedTypeLoc());
1622f4a2713aSLionel Sambuc }
1623f4a2713aSLionel Sambuc 
VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL)1624f4a2713aSLionel Sambuc bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1625f4a2713aSLionel Sambuc   return Visit(TL.getPatternLoc());
1626f4a2713aSLionel Sambuc }
1627f4a2713aSLionel Sambuc 
VisitDecltypeTypeLoc(DecltypeTypeLoc TL)1628f4a2713aSLionel Sambuc bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1629f4a2713aSLionel Sambuc   if (Expr *E = TL.getUnderlyingExpr())
1630f4a2713aSLionel Sambuc     return Visit(MakeCXCursor(E, StmtParent, TU));
1631f4a2713aSLionel Sambuc 
1632f4a2713aSLionel Sambuc   return false;
1633f4a2713aSLionel Sambuc }
1634f4a2713aSLionel Sambuc 
VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL)1635f4a2713aSLionel Sambuc bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1636f4a2713aSLionel Sambuc   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1637f4a2713aSLionel Sambuc }
1638f4a2713aSLionel Sambuc 
VisitAtomicTypeLoc(AtomicTypeLoc TL)1639f4a2713aSLionel Sambuc bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1640f4a2713aSLionel Sambuc   return Visit(TL.getValueLoc());
1641f4a2713aSLionel Sambuc }
1642f4a2713aSLionel Sambuc 
1643f4a2713aSLionel Sambuc #define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1644f4a2713aSLionel Sambuc bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1645f4a2713aSLionel Sambuc   return Visit##PARENT##Loc(TL); \
1646f4a2713aSLionel Sambuc }
1647f4a2713aSLionel Sambuc 
DEFAULT_TYPELOC_IMPL(Complex,Type)1648f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(Complex, Type)
1649f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1650f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1651f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1652f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1653f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1654f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(Vector, Type)
1655f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1656f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1657f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1658f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(Record, TagType)
1659f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(Enum, TagType)
1660f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1661f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1662f4a2713aSLionel Sambuc DEFAULT_TYPELOC_IMPL(Auto, Type)
1663f4a2713aSLionel Sambuc 
1664f4a2713aSLionel Sambuc bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1665f4a2713aSLionel Sambuc   // Visit the nested-name-specifier, if present.
1666f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1667f4a2713aSLionel Sambuc     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1668f4a2713aSLionel Sambuc       return true;
1669f4a2713aSLionel Sambuc 
1670f4a2713aSLionel Sambuc   if (D->isCompleteDefinition()) {
1671*0a6a1f1dSLionel Sambuc     for (const auto &I : D->bases()) {
1672*0a6a1f1dSLionel Sambuc       if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
1673f4a2713aSLionel Sambuc         return true;
1674f4a2713aSLionel Sambuc     }
1675f4a2713aSLionel Sambuc   }
1676f4a2713aSLionel Sambuc 
1677f4a2713aSLionel Sambuc   return VisitTagDecl(D);
1678f4a2713aSLionel Sambuc }
1679f4a2713aSLionel Sambuc 
VisitAttributes(Decl * D)1680f4a2713aSLionel Sambuc bool CursorVisitor::VisitAttributes(Decl *D) {
1681*0a6a1f1dSLionel Sambuc   for (const auto *I : D->attrs())
1682*0a6a1f1dSLionel Sambuc     if (Visit(MakeCXCursor(I, D, TU)))
1683f4a2713aSLionel Sambuc         return true;
1684f4a2713aSLionel Sambuc 
1685f4a2713aSLionel Sambuc   return false;
1686f4a2713aSLionel Sambuc }
1687f4a2713aSLionel Sambuc 
1688f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1689f4a2713aSLionel Sambuc // Data-recursive visitor methods.
1690f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
1691f4a2713aSLionel Sambuc 
1692f4a2713aSLionel Sambuc namespace {
1693f4a2713aSLionel Sambuc #define DEF_JOB(NAME, DATA, KIND)\
1694f4a2713aSLionel Sambuc class NAME : public VisitorJob {\
1695f4a2713aSLionel Sambuc public:\
1696f4a2713aSLionel Sambuc   NAME(const DATA *d, CXCursor parent) : \
1697f4a2713aSLionel Sambuc       VisitorJob(parent, VisitorJob::KIND, d) {} \
1698f4a2713aSLionel Sambuc   static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
1699f4a2713aSLionel Sambuc   const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
1700f4a2713aSLionel Sambuc };
1701f4a2713aSLionel Sambuc 
1702f4a2713aSLionel Sambuc DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1703f4a2713aSLionel Sambuc DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1704f4a2713aSLionel Sambuc DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1705f4a2713aSLionel Sambuc DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1706f4a2713aSLionel Sambuc DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1707f4a2713aSLionel Sambuc         ExplicitTemplateArgsVisitKind)
1708f4a2713aSLionel Sambuc DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1709f4a2713aSLionel Sambuc DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1710f4a2713aSLionel Sambuc DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1711f4a2713aSLionel Sambuc #undef DEF_JOB
1712f4a2713aSLionel Sambuc 
1713f4a2713aSLionel Sambuc class DeclVisit : public VisitorJob {
1714f4a2713aSLionel Sambuc public:
DeclVisit(const Decl * D,CXCursor parent,bool isFirst)1715f4a2713aSLionel Sambuc   DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
1716f4a2713aSLionel Sambuc     VisitorJob(parent, VisitorJob::DeclVisitKind,
1717*0a6a1f1dSLionel Sambuc                D, isFirst ? (void*) 1 : (void*) nullptr) {}
classof(const VisitorJob * VJ)1718f4a2713aSLionel Sambuc   static bool classof(const VisitorJob *VJ) {
1719f4a2713aSLionel Sambuc     return VJ->getKind() == DeclVisitKind;
1720f4a2713aSLionel Sambuc   }
get() const1721f4a2713aSLionel Sambuc   const Decl *get() const { return static_cast<const Decl *>(data[0]); }
isFirst() const1722f4a2713aSLionel Sambuc   bool isFirst() const { return data[1] ? true : false; }
1723f4a2713aSLionel Sambuc };
1724f4a2713aSLionel Sambuc class TypeLocVisit : public VisitorJob {
1725f4a2713aSLionel Sambuc public:
TypeLocVisit(TypeLoc tl,CXCursor parent)1726f4a2713aSLionel Sambuc   TypeLocVisit(TypeLoc tl, CXCursor parent) :
1727f4a2713aSLionel Sambuc     VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1728f4a2713aSLionel Sambuc                tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1729f4a2713aSLionel Sambuc 
classof(const VisitorJob * VJ)1730f4a2713aSLionel Sambuc   static bool classof(const VisitorJob *VJ) {
1731f4a2713aSLionel Sambuc     return VJ->getKind() == TypeLocVisitKind;
1732f4a2713aSLionel Sambuc   }
1733f4a2713aSLionel Sambuc 
get() const1734f4a2713aSLionel Sambuc   TypeLoc get() const {
1735f4a2713aSLionel Sambuc     QualType T = QualType::getFromOpaquePtr(data[0]);
1736f4a2713aSLionel Sambuc     return TypeLoc(T, const_cast<void *>(data[1]));
1737f4a2713aSLionel Sambuc   }
1738f4a2713aSLionel Sambuc };
1739f4a2713aSLionel Sambuc 
1740f4a2713aSLionel Sambuc class LabelRefVisit : public VisitorJob {
1741f4a2713aSLionel Sambuc public:
LabelRefVisit(LabelDecl * LD,SourceLocation labelLoc,CXCursor parent)1742f4a2713aSLionel Sambuc   LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1743f4a2713aSLionel Sambuc     : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1744f4a2713aSLionel Sambuc                  labelLoc.getPtrEncoding()) {}
1745f4a2713aSLionel Sambuc 
classof(const VisitorJob * VJ)1746f4a2713aSLionel Sambuc   static bool classof(const VisitorJob *VJ) {
1747f4a2713aSLionel Sambuc     return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1748f4a2713aSLionel Sambuc   }
get() const1749f4a2713aSLionel Sambuc   const LabelDecl *get() const {
1750f4a2713aSLionel Sambuc     return static_cast<const LabelDecl *>(data[0]);
1751f4a2713aSLionel Sambuc   }
getLoc() const1752f4a2713aSLionel Sambuc   SourceLocation getLoc() const {
1753f4a2713aSLionel Sambuc     return SourceLocation::getFromPtrEncoding(data[1]); }
1754f4a2713aSLionel Sambuc };
1755f4a2713aSLionel Sambuc 
1756f4a2713aSLionel Sambuc class NestedNameSpecifierLocVisit : public VisitorJob {
1757f4a2713aSLionel Sambuc public:
NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier,CXCursor parent)1758f4a2713aSLionel Sambuc   NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1759f4a2713aSLionel Sambuc     : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1760f4a2713aSLionel Sambuc                  Qualifier.getNestedNameSpecifier(),
1761f4a2713aSLionel Sambuc                  Qualifier.getOpaqueData()) { }
1762f4a2713aSLionel Sambuc 
classof(const VisitorJob * VJ)1763f4a2713aSLionel Sambuc   static bool classof(const VisitorJob *VJ) {
1764f4a2713aSLionel Sambuc     return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1765f4a2713aSLionel Sambuc   }
1766f4a2713aSLionel Sambuc 
get() const1767f4a2713aSLionel Sambuc   NestedNameSpecifierLoc get() const {
1768f4a2713aSLionel Sambuc     return NestedNameSpecifierLoc(
1769f4a2713aSLionel Sambuc             const_cast<NestedNameSpecifier *>(
1770f4a2713aSLionel Sambuc               static_cast<const NestedNameSpecifier *>(data[0])),
1771f4a2713aSLionel Sambuc             const_cast<void *>(data[1]));
1772f4a2713aSLionel Sambuc   }
1773f4a2713aSLionel Sambuc };
1774f4a2713aSLionel Sambuc 
1775f4a2713aSLionel Sambuc class DeclarationNameInfoVisit : public VisitorJob {
1776f4a2713aSLionel Sambuc public:
DeclarationNameInfoVisit(const Stmt * S,CXCursor parent)1777f4a2713aSLionel Sambuc   DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
1778f4a2713aSLionel Sambuc     : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
classof(const VisitorJob * VJ)1779f4a2713aSLionel Sambuc   static bool classof(const VisitorJob *VJ) {
1780f4a2713aSLionel Sambuc     return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1781f4a2713aSLionel Sambuc   }
get() const1782f4a2713aSLionel Sambuc   DeclarationNameInfo get() const {
1783f4a2713aSLionel Sambuc     const Stmt *S = static_cast<const Stmt *>(data[0]);
1784f4a2713aSLionel Sambuc     switch (S->getStmtClass()) {
1785f4a2713aSLionel Sambuc     default:
1786f4a2713aSLionel Sambuc       llvm_unreachable("Unhandled Stmt");
1787f4a2713aSLionel Sambuc     case clang::Stmt::MSDependentExistsStmtClass:
1788f4a2713aSLionel Sambuc       return cast<MSDependentExistsStmt>(S)->getNameInfo();
1789f4a2713aSLionel Sambuc     case Stmt::CXXDependentScopeMemberExprClass:
1790f4a2713aSLionel Sambuc       return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1791f4a2713aSLionel Sambuc     case Stmt::DependentScopeDeclRefExprClass:
1792f4a2713aSLionel Sambuc       return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1793*0a6a1f1dSLionel Sambuc     case Stmt::OMPCriticalDirectiveClass:
1794*0a6a1f1dSLionel Sambuc       return cast<OMPCriticalDirective>(S)->getDirectiveName();
1795f4a2713aSLionel Sambuc     }
1796f4a2713aSLionel Sambuc   }
1797f4a2713aSLionel Sambuc };
1798f4a2713aSLionel Sambuc class MemberRefVisit : public VisitorJob {
1799f4a2713aSLionel Sambuc public:
MemberRefVisit(const FieldDecl * D,SourceLocation L,CXCursor parent)1800f4a2713aSLionel Sambuc   MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
1801f4a2713aSLionel Sambuc     : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1802f4a2713aSLionel Sambuc                  L.getPtrEncoding()) {}
classof(const VisitorJob * VJ)1803f4a2713aSLionel Sambuc   static bool classof(const VisitorJob *VJ) {
1804f4a2713aSLionel Sambuc     return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1805f4a2713aSLionel Sambuc   }
get() const1806f4a2713aSLionel Sambuc   const FieldDecl *get() const {
1807f4a2713aSLionel Sambuc     return static_cast<const FieldDecl *>(data[0]);
1808f4a2713aSLionel Sambuc   }
getLoc() const1809f4a2713aSLionel Sambuc   SourceLocation getLoc() const {
1810f4a2713aSLionel Sambuc     return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1811f4a2713aSLionel Sambuc   }
1812f4a2713aSLionel Sambuc };
1813f4a2713aSLionel Sambuc class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
1814f4a2713aSLionel Sambuc   friend class OMPClauseEnqueue;
1815f4a2713aSLionel Sambuc   VisitorWorkList &WL;
1816f4a2713aSLionel Sambuc   CXCursor Parent;
1817f4a2713aSLionel Sambuc public:
EnqueueVisitor(VisitorWorkList & wl,CXCursor parent)1818f4a2713aSLionel Sambuc   EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1819f4a2713aSLionel Sambuc     : WL(wl), Parent(parent) {}
1820f4a2713aSLionel Sambuc 
1821f4a2713aSLionel Sambuc   void VisitAddrLabelExpr(const AddrLabelExpr *E);
1822f4a2713aSLionel Sambuc   void VisitBlockExpr(const BlockExpr *B);
1823f4a2713aSLionel Sambuc   void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1824f4a2713aSLionel Sambuc   void VisitCompoundStmt(const CompoundStmt *S);
VisitCXXDefaultArgExpr(const CXXDefaultArgExpr * E)1825f4a2713aSLionel Sambuc   void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1826f4a2713aSLionel Sambuc   void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1827f4a2713aSLionel Sambuc   void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1828f4a2713aSLionel Sambuc   void VisitCXXNewExpr(const CXXNewExpr *E);
1829f4a2713aSLionel Sambuc   void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1830f4a2713aSLionel Sambuc   void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1831f4a2713aSLionel Sambuc   void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1832f4a2713aSLionel Sambuc   void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1833f4a2713aSLionel Sambuc   void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1834f4a2713aSLionel Sambuc   void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1835f4a2713aSLionel Sambuc   void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1836f4a2713aSLionel Sambuc   void VisitCXXCatchStmt(const CXXCatchStmt *S);
1837*0a6a1f1dSLionel Sambuc   void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
1838f4a2713aSLionel Sambuc   void VisitDeclRefExpr(const DeclRefExpr *D);
1839f4a2713aSLionel Sambuc   void VisitDeclStmt(const DeclStmt *S);
1840f4a2713aSLionel Sambuc   void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1841f4a2713aSLionel Sambuc   void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1842f4a2713aSLionel Sambuc   void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1843f4a2713aSLionel Sambuc   void VisitForStmt(const ForStmt *FS);
1844f4a2713aSLionel Sambuc   void VisitGotoStmt(const GotoStmt *GS);
1845f4a2713aSLionel Sambuc   void VisitIfStmt(const IfStmt *If);
1846f4a2713aSLionel Sambuc   void VisitInitListExpr(const InitListExpr *IE);
1847f4a2713aSLionel Sambuc   void VisitMemberExpr(const MemberExpr *M);
1848f4a2713aSLionel Sambuc   void VisitOffsetOfExpr(const OffsetOfExpr *E);
1849f4a2713aSLionel Sambuc   void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1850f4a2713aSLionel Sambuc   void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1851f4a2713aSLionel Sambuc   void VisitOverloadExpr(const OverloadExpr *E);
1852f4a2713aSLionel Sambuc   void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1853f4a2713aSLionel Sambuc   void VisitStmt(const Stmt *S);
1854f4a2713aSLionel Sambuc   void VisitSwitchStmt(const SwitchStmt *S);
1855f4a2713aSLionel Sambuc   void VisitWhileStmt(const WhileStmt *W);
1856f4a2713aSLionel Sambuc   void VisitTypeTraitExpr(const TypeTraitExpr *E);
1857f4a2713aSLionel Sambuc   void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1858f4a2713aSLionel Sambuc   void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1859f4a2713aSLionel Sambuc   void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1860f4a2713aSLionel Sambuc   void VisitVAArgExpr(const VAArgExpr *E);
1861f4a2713aSLionel Sambuc   void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1862f4a2713aSLionel Sambuc   void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1863f4a2713aSLionel Sambuc   void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1864f4a2713aSLionel Sambuc   void VisitLambdaExpr(const LambdaExpr *E);
1865f4a2713aSLionel Sambuc   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1866*0a6a1f1dSLionel Sambuc   void VisitOMPLoopDirective(const OMPLoopDirective *D);
1867f4a2713aSLionel Sambuc   void VisitOMPParallelDirective(const OMPParallelDirective *D);
1868*0a6a1f1dSLionel Sambuc   void VisitOMPSimdDirective(const OMPSimdDirective *D);
1869*0a6a1f1dSLionel Sambuc   void VisitOMPForDirective(const OMPForDirective *D);
1870*0a6a1f1dSLionel Sambuc   void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
1871*0a6a1f1dSLionel Sambuc   void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
1872*0a6a1f1dSLionel Sambuc   void VisitOMPSectionDirective(const OMPSectionDirective *D);
1873*0a6a1f1dSLionel Sambuc   void VisitOMPSingleDirective(const OMPSingleDirective *D);
1874*0a6a1f1dSLionel Sambuc   void VisitOMPMasterDirective(const OMPMasterDirective *D);
1875*0a6a1f1dSLionel Sambuc   void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
1876*0a6a1f1dSLionel Sambuc   void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
1877*0a6a1f1dSLionel Sambuc   void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
1878*0a6a1f1dSLionel Sambuc   void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
1879*0a6a1f1dSLionel Sambuc   void VisitOMPTaskDirective(const OMPTaskDirective *D);
1880*0a6a1f1dSLionel Sambuc   void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
1881*0a6a1f1dSLionel Sambuc   void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
1882*0a6a1f1dSLionel Sambuc   void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
1883*0a6a1f1dSLionel Sambuc   void VisitOMPFlushDirective(const OMPFlushDirective *D);
1884*0a6a1f1dSLionel Sambuc   void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
1885*0a6a1f1dSLionel Sambuc   void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
1886*0a6a1f1dSLionel Sambuc   void VisitOMPTargetDirective(const OMPTargetDirective *D);
1887*0a6a1f1dSLionel Sambuc   void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
1888f4a2713aSLionel Sambuc 
1889f4a2713aSLionel Sambuc private:
1890f4a2713aSLionel Sambuc   void AddDeclarationNameInfo(const Stmt *S);
1891f4a2713aSLionel Sambuc   void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1892f4a2713aSLionel Sambuc   void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
1893f4a2713aSLionel Sambuc   void AddMemberRef(const FieldDecl *D, SourceLocation L);
1894f4a2713aSLionel Sambuc   void AddStmt(const Stmt *S);
1895f4a2713aSLionel Sambuc   void AddDecl(const Decl *D, bool isFirst = true);
1896f4a2713aSLionel Sambuc   void AddTypeLoc(TypeSourceInfo *TI);
1897f4a2713aSLionel Sambuc   void EnqueueChildren(const Stmt *S);
1898f4a2713aSLionel Sambuc   void EnqueueChildren(const OMPClause *S);
1899f4a2713aSLionel Sambuc };
1900f4a2713aSLionel Sambuc } // end anonyous namespace
1901f4a2713aSLionel Sambuc 
AddDeclarationNameInfo(const Stmt * S)1902f4a2713aSLionel Sambuc void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
1903f4a2713aSLionel Sambuc   // 'S' should always be non-null, since it comes from the
1904f4a2713aSLionel Sambuc   // statement we are visiting.
1905f4a2713aSLionel Sambuc   WL.push_back(DeclarationNameInfoVisit(S, Parent));
1906f4a2713aSLionel Sambuc }
1907f4a2713aSLionel Sambuc 
1908f4a2713aSLionel Sambuc void
AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)1909f4a2713aSLionel Sambuc EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1910f4a2713aSLionel Sambuc   if (Qualifier)
1911f4a2713aSLionel Sambuc     WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1912f4a2713aSLionel Sambuc }
1913f4a2713aSLionel Sambuc 
AddStmt(const Stmt * S)1914f4a2713aSLionel Sambuc void EnqueueVisitor::AddStmt(const Stmt *S) {
1915f4a2713aSLionel Sambuc   if (S)
1916f4a2713aSLionel Sambuc     WL.push_back(StmtVisit(S, Parent));
1917f4a2713aSLionel Sambuc }
AddDecl(const Decl * D,bool isFirst)1918f4a2713aSLionel Sambuc void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
1919f4a2713aSLionel Sambuc   if (D)
1920f4a2713aSLionel Sambuc     WL.push_back(DeclVisit(D, Parent, isFirst));
1921f4a2713aSLionel Sambuc }
1922f4a2713aSLionel Sambuc void EnqueueVisitor::
AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo * A)1923f4a2713aSLionel Sambuc   AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1924f4a2713aSLionel Sambuc   if (A)
1925f4a2713aSLionel Sambuc     WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
1926f4a2713aSLionel Sambuc }
AddMemberRef(const FieldDecl * D,SourceLocation L)1927f4a2713aSLionel Sambuc void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
1928f4a2713aSLionel Sambuc   if (D)
1929f4a2713aSLionel Sambuc     WL.push_back(MemberRefVisit(D, L, Parent));
1930f4a2713aSLionel Sambuc }
AddTypeLoc(TypeSourceInfo * TI)1931f4a2713aSLionel Sambuc void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1932f4a2713aSLionel Sambuc   if (TI)
1933f4a2713aSLionel Sambuc     WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1934f4a2713aSLionel Sambuc  }
EnqueueChildren(const Stmt * S)1935f4a2713aSLionel Sambuc void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
1936f4a2713aSLionel Sambuc   unsigned size = WL.size();
1937f4a2713aSLionel Sambuc   for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
1938f4a2713aSLionel Sambuc     AddStmt(*Child);
1939f4a2713aSLionel Sambuc   }
1940f4a2713aSLionel Sambuc   if (size == WL.size())
1941f4a2713aSLionel Sambuc     return;
1942f4a2713aSLionel Sambuc   // Now reverse the entries we just added.  This will match the DFS
1943f4a2713aSLionel Sambuc   // ordering performed by the worklist.
1944f4a2713aSLionel Sambuc   VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1945f4a2713aSLionel Sambuc   std::reverse(I, E);
1946f4a2713aSLionel Sambuc }
1947f4a2713aSLionel Sambuc namespace {
1948f4a2713aSLionel Sambuc class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1949f4a2713aSLionel Sambuc   EnqueueVisitor *Visitor;
1950f4a2713aSLionel Sambuc   /// \brief Process clauses with list of variables.
1951f4a2713aSLionel Sambuc   template <typename T>
1952f4a2713aSLionel Sambuc   void VisitOMPClauseList(T *Node);
1953f4a2713aSLionel Sambuc public:
OMPClauseEnqueue(EnqueueVisitor * Visitor)1954f4a2713aSLionel Sambuc   OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1955f4a2713aSLionel Sambuc #define OPENMP_CLAUSE(Name, Class)                                             \
1956f4a2713aSLionel Sambuc   void Visit##Class(const Class *C);
1957f4a2713aSLionel Sambuc #include "clang/Basic/OpenMPKinds.def"
1958f4a2713aSLionel Sambuc };
1959f4a2713aSLionel Sambuc 
VisitOMPIfClause(const OMPIfClause * C)1960*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1961*0a6a1f1dSLionel Sambuc   Visitor->AddStmt(C->getCondition());
1962*0a6a1f1dSLionel Sambuc }
1963*0a6a1f1dSLionel Sambuc 
VisitOMPFinalClause(const OMPFinalClause * C)1964*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
1965*0a6a1f1dSLionel Sambuc   Visitor->AddStmt(C->getCondition());
1966*0a6a1f1dSLionel Sambuc }
1967*0a6a1f1dSLionel Sambuc 
VisitOMPNumThreadsClause(const OMPNumThreadsClause * C)1968*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1969*0a6a1f1dSLionel Sambuc   Visitor->AddStmt(C->getNumThreads());
1970*0a6a1f1dSLionel Sambuc }
1971*0a6a1f1dSLionel Sambuc 
VisitOMPSafelenClause(const OMPSafelenClause * C)1972*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1973*0a6a1f1dSLionel Sambuc   Visitor->AddStmt(C->getSafelen());
1974*0a6a1f1dSLionel Sambuc }
1975*0a6a1f1dSLionel Sambuc 
VisitOMPCollapseClause(const OMPCollapseClause * C)1976*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1977*0a6a1f1dSLionel Sambuc   Visitor->AddStmt(C->getNumForLoops());
1978*0a6a1f1dSLionel Sambuc }
1979*0a6a1f1dSLionel Sambuc 
VisitOMPDefaultClause(const OMPDefaultClause * C)1980f4a2713aSLionel Sambuc void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
1981f4a2713aSLionel Sambuc 
VisitOMPProcBindClause(const OMPProcBindClause * C)1982*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1983*0a6a1f1dSLionel Sambuc 
VisitOMPScheduleClause(const OMPScheduleClause * C)1984*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
1985*0a6a1f1dSLionel Sambuc   Visitor->AddStmt(C->getChunkSize());
1986*0a6a1f1dSLionel Sambuc }
1987*0a6a1f1dSLionel Sambuc 
VisitOMPOrderedClause(const OMPOrderedClause *)1988*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *) {}
1989*0a6a1f1dSLionel Sambuc 
VisitOMPNowaitClause(const OMPNowaitClause *)1990*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
1991*0a6a1f1dSLionel Sambuc 
VisitOMPUntiedClause(const OMPUntiedClause *)1992*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
1993*0a6a1f1dSLionel Sambuc 
VisitOMPMergeableClause(const OMPMergeableClause *)1994*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
1995*0a6a1f1dSLionel Sambuc 
VisitOMPReadClause(const OMPReadClause *)1996*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
1997*0a6a1f1dSLionel Sambuc 
VisitOMPWriteClause(const OMPWriteClause *)1998*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
1999*0a6a1f1dSLionel Sambuc 
VisitOMPUpdateClause(const OMPUpdateClause *)2000*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2001*0a6a1f1dSLionel Sambuc 
VisitOMPCaptureClause(const OMPCaptureClause *)2002*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2003*0a6a1f1dSLionel Sambuc 
VisitOMPSeqCstClause(const OMPSeqCstClause *)2004*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2005*0a6a1f1dSLionel Sambuc 
2006f4a2713aSLionel Sambuc template<typename T>
VisitOMPClauseList(T * Node)2007f4a2713aSLionel Sambuc void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
2008*0a6a1f1dSLionel Sambuc   for (const auto *I : Node->varlists()) {
2009*0a6a1f1dSLionel Sambuc     Visitor->AddStmt(I);
2010*0a6a1f1dSLionel Sambuc   }
2011f4a2713aSLionel Sambuc }
2012f4a2713aSLionel Sambuc 
VisitOMPPrivateClause(const OMPPrivateClause * C)2013f4a2713aSLionel Sambuc void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
2014f4a2713aSLionel Sambuc   VisitOMPClauseList(C);
2015*0a6a1f1dSLionel Sambuc   for (const auto *E : C->private_copies()) {
2016*0a6a1f1dSLionel Sambuc     Visitor->AddStmt(E);
2017*0a6a1f1dSLionel Sambuc   }
2018f4a2713aSLionel Sambuc }
VisitOMPFirstprivateClause(const OMPFirstprivateClause * C)2019f4a2713aSLionel Sambuc void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2020f4a2713aSLionel Sambuc                                         const OMPFirstprivateClause *C) {
2021f4a2713aSLionel Sambuc   VisitOMPClauseList(C);
2022f4a2713aSLionel Sambuc }
VisitOMPLastprivateClause(const OMPLastprivateClause * C)2023*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPLastprivateClause(
2024*0a6a1f1dSLionel Sambuc                                         const OMPLastprivateClause *C) {
2025*0a6a1f1dSLionel Sambuc   VisitOMPClauseList(C);
2026*0a6a1f1dSLionel Sambuc }
VisitOMPSharedClause(const OMPSharedClause * C)2027f4a2713aSLionel Sambuc void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
2028f4a2713aSLionel Sambuc   VisitOMPClauseList(C);
2029f4a2713aSLionel Sambuc }
VisitOMPReductionClause(const OMPReductionClause * C)2030*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2031*0a6a1f1dSLionel Sambuc   VisitOMPClauseList(C);
2032*0a6a1f1dSLionel Sambuc }
VisitOMPLinearClause(const OMPLinearClause * C)2033*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2034*0a6a1f1dSLionel Sambuc   VisitOMPClauseList(C);
2035*0a6a1f1dSLionel Sambuc   Visitor->AddStmt(C->getStep());
2036*0a6a1f1dSLionel Sambuc }
VisitOMPAlignedClause(const OMPAlignedClause * C)2037*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2038*0a6a1f1dSLionel Sambuc   VisitOMPClauseList(C);
2039*0a6a1f1dSLionel Sambuc   Visitor->AddStmt(C->getAlignment());
2040*0a6a1f1dSLionel Sambuc }
VisitOMPCopyinClause(const OMPCopyinClause * C)2041*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2042*0a6a1f1dSLionel Sambuc   VisitOMPClauseList(C);
2043*0a6a1f1dSLionel Sambuc }
2044*0a6a1f1dSLionel Sambuc void
VisitOMPCopyprivateClause(const OMPCopyprivateClause * C)2045*0a6a1f1dSLionel Sambuc OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2046*0a6a1f1dSLionel Sambuc   VisitOMPClauseList(C);
2047*0a6a1f1dSLionel Sambuc }
VisitOMPFlushClause(const OMPFlushClause * C)2048*0a6a1f1dSLionel Sambuc void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2049*0a6a1f1dSLionel Sambuc   VisitOMPClauseList(C);
2050*0a6a1f1dSLionel Sambuc }
2051f4a2713aSLionel Sambuc }
2052f4a2713aSLionel Sambuc 
EnqueueChildren(const OMPClause * S)2053f4a2713aSLionel Sambuc void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2054f4a2713aSLionel Sambuc   unsigned size = WL.size();
2055f4a2713aSLionel Sambuc   OMPClauseEnqueue Visitor(this);
2056f4a2713aSLionel Sambuc   Visitor.Visit(S);
2057f4a2713aSLionel Sambuc   if (size == WL.size())
2058f4a2713aSLionel Sambuc     return;
2059f4a2713aSLionel Sambuc   // Now reverse the entries we just added.  This will match the DFS
2060f4a2713aSLionel Sambuc   // ordering performed by the worklist.
2061f4a2713aSLionel Sambuc   VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2062f4a2713aSLionel Sambuc   std::reverse(I, E);
2063f4a2713aSLionel Sambuc }
VisitAddrLabelExpr(const AddrLabelExpr * E)2064f4a2713aSLionel Sambuc void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
2065f4a2713aSLionel Sambuc   WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2066f4a2713aSLionel Sambuc }
VisitBlockExpr(const BlockExpr * B)2067f4a2713aSLionel Sambuc void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
2068f4a2713aSLionel Sambuc   AddDecl(B->getBlockDecl());
2069f4a2713aSLionel Sambuc }
VisitCompoundLiteralExpr(const CompoundLiteralExpr * E)2070f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
2071f4a2713aSLionel Sambuc   EnqueueChildren(E);
2072f4a2713aSLionel Sambuc   AddTypeLoc(E->getTypeSourceInfo());
2073f4a2713aSLionel Sambuc }
VisitCompoundStmt(const CompoundStmt * S)2074f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2075f4a2713aSLionel Sambuc   for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
2076f4a2713aSLionel Sambuc         E = S->body_rend(); I != E; ++I) {
2077f4a2713aSLionel Sambuc     AddStmt(*I);
2078f4a2713aSLionel Sambuc   }
2079f4a2713aSLionel Sambuc }
2080f4a2713aSLionel Sambuc void EnqueueVisitor::
VisitMSDependentExistsStmt(const MSDependentExistsStmt * S)2081f4a2713aSLionel Sambuc VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
2082f4a2713aSLionel Sambuc   AddStmt(S->getSubStmt());
2083f4a2713aSLionel Sambuc   AddDeclarationNameInfo(S);
2084f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2085f4a2713aSLionel Sambuc     AddNestedNameSpecifierLoc(QualifierLoc);
2086f4a2713aSLionel Sambuc }
2087f4a2713aSLionel Sambuc 
2088f4a2713aSLionel Sambuc void EnqueueVisitor::
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr * E)2089f4a2713aSLionel Sambuc VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
2090f4a2713aSLionel Sambuc   AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2091f4a2713aSLionel Sambuc   AddDeclarationNameInfo(E);
2092f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2093f4a2713aSLionel Sambuc     AddNestedNameSpecifierLoc(QualifierLoc);
2094f4a2713aSLionel Sambuc   if (!E->isImplicitAccess())
2095f4a2713aSLionel Sambuc     AddStmt(E->getBase());
2096f4a2713aSLionel Sambuc }
VisitCXXNewExpr(const CXXNewExpr * E)2097f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
2098f4a2713aSLionel Sambuc   // Enqueue the initializer , if any.
2099f4a2713aSLionel Sambuc   AddStmt(E->getInitializer());
2100f4a2713aSLionel Sambuc   // Enqueue the array size, if any.
2101f4a2713aSLionel Sambuc   AddStmt(E->getArraySize());
2102f4a2713aSLionel Sambuc   // Enqueue the allocated type.
2103f4a2713aSLionel Sambuc   AddTypeLoc(E->getAllocatedTypeSourceInfo());
2104f4a2713aSLionel Sambuc   // Enqueue the placement arguments.
2105f4a2713aSLionel Sambuc   for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2106f4a2713aSLionel Sambuc     AddStmt(E->getPlacementArg(I-1));
2107f4a2713aSLionel Sambuc }
VisitCXXOperatorCallExpr(const CXXOperatorCallExpr * CE)2108f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
2109f4a2713aSLionel Sambuc   for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2110f4a2713aSLionel Sambuc     AddStmt(CE->getArg(I-1));
2111f4a2713aSLionel Sambuc   AddStmt(CE->getCallee());
2112f4a2713aSLionel Sambuc   AddStmt(CE->getArg(0));
2113f4a2713aSLionel Sambuc }
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)2114f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2115f4a2713aSLionel Sambuc                                         const CXXPseudoDestructorExpr *E) {
2116f4a2713aSLionel Sambuc   // Visit the name of the type being destroyed.
2117f4a2713aSLionel Sambuc   AddTypeLoc(E->getDestroyedTypeInfo());
2118f4a2713aSLionel Sambuc   // Visit the scope type that looks disturbingly like the nested-name-specifier
2119f4a2713aSLionel Sambuc   // but isn't.
2120f4a2713aSLionel Sambuc   AddTypeLoc(E->getScopeTypeInfo());
2121f4a2713aSLionel Sambuc   // Visit the nested-name-specifier.
2122f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2123f4a2713aSLionel Sambuc     AddNestedNameSpecifierLoc(QualifierLoc);
2124f4a2713aSLionel Sambuc   // Visit base expression.
2125f4a2713aSLionel Sambuc   AddStmt(E->getBase());
2126f4a2713aSLionel Sambuc }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)2127f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2128f4a2713aSLionel Sambuc                                         const CXXScalarValueInitExpr *E) {
2129f4a2713aSLionel Sambuc   AddTypeLoc(E->getTypeSourceInfo());
2130f4a2713aSLionel Sambuc }
VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr * E)2131f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2132f4a2713aSLionel Sambuc                                         const CXXTemporaryObjectExpr *E) {
2133f4a2713aSLionel Sambuc   EnqueueChildren(E);
2134f4a2713aSLionel Sambuc   AddTypeLoc(E->getTypeSourceInfo());
2135f4a2713aSLionel Sambuc }
VisitCXXTypeidExpr(const CXXTypeidExpr * E)2136f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
2137f4a2713aSLionel Sambuc   EnqueueChildren(E);
2138f4a2713aSLionel Sambuc   if (E->isTypeOperand())
2139f4a2713aSLionel Sambuc     AddTypeLoc(E->getTypeOperandSourceInfo());
2140f4a2713aSLionel Sambuc }
2141f4a2713aSLionel Sambuc 
VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr * E)2142f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2143f4a2713aSLionel Sambuc                                         const CXXUnresolvedConstructExpr *E) {
2144f4a2713aSLionel Sambuc   EnqueueChildren(E);
2145f4a2713aSLionel Sambuc   AddTypeLoc(E->getTypeSourceInfo());
2146f4a2713aSLionel Sambuc }
VisitCXXUuidofExpr(const CXXUuidofExpr * E)2147f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
2148f4a2713aSLionel Sambuc   EnqueueChildren(E);
2149f4a2713aSLionel Sambuc   if (E->isTypeOperand())
2150f4a2713aSLionel Sambuc     AddTypeLoc(E->getTypeOperandSourceInfo());
2151f4a2713aSLionel Sambuc }
2152f4a2713aSLionel Sambuc 
VisitCXXCatchStmt(const CXXCatchStmt * S)2153f4a2713aSLionel Sambuc void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
2154f4a2713aSLionel Sambuc   EnqueueChildren(S);
2155f4a2713aSLionel Sambuc   AddDecl(S->getExceptionDecl());
2156f4a2713aSLionel Sambuc }
2157f4a2713aSLionel Sambuc 
VisitCXXForRangeStmt(const CXXForRangeStmt * S)2158*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
2159*0a6a1f1dSLionel Sambuc   AddStmt(S->getBody());
2160*0a6a1f1dSLionel Sambuc   AddStmt(S->getRangeInit());
2161*0a6a1f1dSLionel Sambuc   AddDecl(S->getLoopVariable());
2162*0a6a1f1dSLionel Sambuc }
2163*0a6a1f1dSLionel Sambuc 
VisitDeclRefExpr(const DeclRefExpr * DR)2164f4a2713aSLionel Sambuc void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
2165f4a2713aSLionel Sambuc   if (DR->hasExplicitTemplateArgs()) {
2166f4a2713aSLionel Sambuc     AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2167f4a2713aSLionel Sambuc   }
2168f4a2713aSLionel Sambuc   WL.push_back(DeclRefExprParts(DR, Parent));
2169f4a2713aSLionel Sambuc }
VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr * E)2170f4a2713aSLionel Sambuc void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2171f4a2713aSLionel Sambuc                                         const DependentScopeDeclRefExpr *E) {
2172f4a2713aSLionel Sambuc   AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2173f4a2713aSLionel Sambuc   AddDeclarationNameInfo(E);
2174f4a2713aSLionel Sambuc   AddNestedNameSpecifierLoc(E->getQualifierLoc());
2175f4a2713aSLionel Sambuc }
VisitDeclStmt(const DeclStmt * S)2176f4a2713aSLionel Sambuc void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
2177f4a2713aSLionel Sambuc   unsigned size = WL.size();
2178f4a2713aSLionel Sambuc   bool isFirst = true;
2179*0a6a1f1dSLionel Sambuc   for (const auto *D : S->decls()) {
2180*0a6a1f1dSLionel Sambuc     AddDecl(D, isFirst);
2181f4a2713aSLionel Sambuc     isFirst = false;
2182f4a2713aSLionel Sambuc   }
2183f4a2713aSLionel Sambuc   if (size == WL.size())
2184f4a2713aSLionel Sambuc     return;
2185f4a2713aSLionel Sambuc   // Now reverse the entries we just added.  This will match the DFS
2186f4a2713aSLionel Sambuc   // ordering performed by the worklist.
2187f4a2713aSLionel Sambuc   VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2188f4a2713aSLionel Sambuc   std::reverse(I, E);
2189f4a2713aSLionel Sambuc }
VisitDesignatedInitExpr(const DesignatedInitExpr * E)2190f4a2713aSLionel Sambuc void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
2191f4a2713aSLionel Sambuc   AddStmt(E->getInit());
2192f4a2713aSLionel Sambuc   for (DesignatedInitExpr::const_reverse_designators_iterator
2193f4a2713aSLionel Sambuc          D = E->designators_rbegin(), DEnd = E->designators_rend();
2194f4a2713aSLionel Sambuc          D != DEnd; ++D) {
2195f4a2713aSLionel Sambuc     if (D->isFieldDesignator()) {
2196f4a2713aSLionel Sambuc       if (FieldDecl *Field = D->getField())
2197f4a2713aSLionel Sambuc         AddMemberRef(Field, D->getFieldLoc());
2198f4a2713aSLionel Sambuc       continue;
2199f4a2713aSLionel Sambuc     }
2200f4a2713aSLionel Sambuc     if (D->isArrayDesignator()) {
2201f4a2713aSLionel Sambuc       AddStmt(E->getArrayIndex(*D));
2202f4a2713aSLionel Sambuc       continue;
2203f4a2713aSLionel Sambuc     }
2204f4a2713aSLionel Sambuc     assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2205f4a2713aSLionel Sambuc     AddStmt(E->getArrayRangeEnd(*D));
2206f4a2713aSLionel Sambuc     AddStmt(E->getArrayRangeStart(*D));
2207f4a2713aSLionel Sambuc   }
2208f4a2713aSLionel Sambuc }
VisitExplicitCastExpr(const ExplicitCastExpr * E)2209f4a2713aSLionel Sambuc void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
2210f4a2713aSLionel Sambuc   EnqueueChildren(E);
2211f4a2713aSLionel Sambuc   AddTypeLoc(E->getTypeInfoAsWritten());
2212f4a2713aSLionel Sambuc }
VisitForStmt(const ForStmt * FS)2213f4a2713aSLionel Sambuc void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
2214f4a2713aSLionel Sambuc   AddStmt(FS->getBody());
2215f4a2713aSLionel Sambuc   AddStmt(FS->getInc());
2216f4a2713aSLionel Sambuc   AddStmt(FS->getCond());
2217f4a2713aSLionel Sambuc   AddDecl(FS->getConditionVariable());
2218f4a2713aSLionel Sambuc   AddStmt(FS->getInit());
2219f4a2713aSLionel Sambuc }
VisitGotoStmt(const GotoStmt * GS)2220f4a2713aSLionel Sambuc void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
2221f4a2713aSLionel Sambuc   WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2222f4a2713aSLionel Sambuc }
VisitIfStmt(const IfStmt * If)2223f4a2713aSLionel Sambuc void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
2224f4a2713aSLionel Sambuc   AddStmt(If->getElse());
2225f4a2713aSLionel Sambuc   AddStmt(If->getThen());
2226f4a2713aSLionel Sambuc   AddStmt(If->getCond());
2227f4a2713aSLionel Sambuc   AddDecl(If->getConditionVariable());
2228f4a2713aSLionel Sambuc }
VisitInitListExpr(const InitListExpr * IE)2229f4a2713aSLionel Sambuc void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
2230f4a2713aSLionel Sambuc   // We care about the syntactic form of the initializer list, only.
2231f4a2713aSLionel Sambuc   if (InitListExpr *Syntactic = IE->getSyntacticForm())
2232f4a2713aSLionel Sambuc     IE = Syntactic;
2233f4a2713aSLionel Sambuc   EnqueueChildren(IE);
2234f4a2713aSLionel Sambuc }
VisitMemberExpr(const MemberExpr * M)2235f4a2713aSLionel Sambuc void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
2236f4a2713aSLionel Sambuc   WL.push_back(MemberExprParts(M, Parent));
2237f4a2713aSLionel Sambuc 
2238f4a2713aSLionel Sambuc   // If the base of the member access expression is an implicit 'this', don't
2239f4a2713aSLionel Sambuc   // visit it.
2240f4a2713aSLionel Sambuc   // FIXME: If we ever want to show these implicit accesses, this will be
2241f4a2713aSLionel Sambuc   // unfortunate. However, clang_getCursor() relies on this behavior.
2242f4a2713aSLionel Sambuc   if (!M->isImplicitAccess())
2243f4a2713aSLionel Sambuc     AddStmt(M->getBase());
2244f4a2713aSLionel Sambuc }
VisitObjCEncodeExpr(const ObjCEncodeExpr * E)2245f4a2713aSLionel Sambuc void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
2246f4a2713aSLionel Sambuc   AddTypeLoc(E->getEncodedTypeSourceInfo());
2247f4a2713aSLionel Sambuc }
VisitObjCMessageExpr(const ObjCMessageExpr * M)2248f4a2713aSLionel Sambuc void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
2249f4a2713aSLionel Sambuc   EnqueueChildren(M);
2250f4a2713aSLionel Sambuc   AddTypeLoc(M->getClassReceiverTypeInfo());
2251f4a2713aSLionel Sambuc }
VisitOffsetOfExpr(const OffsetOfExpr * E)2252f4a2713aSLionel Sambuc void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
2253f4a2713aSLionel Sambuc   // Visit the components of the offsetof expression.
2254f4a2713aSLionel Sambuc   for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2255f4a2713aSLionel Sambuc     typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2256f4a2713aSLionel Sambuc     const OffsetOfNode &Node = E->getComponent(I-1);
2257f4a2713aSLionel Sambuc     switch (Node.getKind()) {
2258f4a2713aSLionel Sambuc     case OffsetOfNode::Array:
2259f4a2713aSLionel Sambuc       AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2260f4a2713aSLionel Sambuc       break;
2261f4a2713aSLionel Sambuc     case OffsetOfNode::Field:
2262f4a2713aSLionel Sambuc       AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2263f4a2713aSLionel Sambuc       break;
2264f4a2713aSLionel Sambuc     case OffsetOfNode::Identifier:
2265f4a2713aSLionel Sambuc     case OffsetOfNode::Base:
2266f4a2713aSLionel Sambuc       continue;
2267f4a2713aSLionel Sambuc     }
2268f4a2713aSLionel Sambuc   }
2269f4a2713aSLionel Sambuc   // Visit the type into which we're computing the offset.
2270f4a2713aSLionel Sambuc   AddTypeLoc(E->getTypeSourceInfo());
2271f4a2713aSLionel Sambuc }
VisitOverloadExpr(const OverloadExpr * E)2272f4a2713aSLionel Sambuc void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
2273f4a2713aSLionel Sambuc   AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2274f4a2713aSLionel Sambuc   WL.push_back(OverloadExprParts(E, Parent));
2275f4a2713aSLionel Sambuc }
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)2276f4a2713aSLionel Sambuc void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2277f4a2713aSLionel Sambuc                                         const UnaryExprOrTypeTraitExpr *E) {
2278f4a2713aSLionel Sambuc   EnqueueChildren(E);
2279f4a2713aSLionel Sambuc   if (E->isArgumentType())
2280f4a2713aSLionel Sambuc     AddTypeLoc(E->getArgumentTypeInfo());
2281f4a2713aSLionel Sambuc }
VisitStmt(const Stmt * S)2282f4a2713aSLionel Sambuc void EnqueueVisitor::VisitStmt(const Stmt *S) {
2283f4a2713aSLionel Sambuc   EnqueueChildren(S);
2284f4a2713aSLionel Sambuc }
VisitSwitchStmt(const SwitchStmt * S)2285f4a2713aSLionel Sambuc void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
2286f4a2713aSLionel Sambuc   AddStmt(S->getBody());
2287f4a2713aSLionel Sambuc   AddStmt(S->getCond());
2288f4a2713aSLionel Sambuc   AddDecl(S->getConditionVariable());
2289f4a2713aSLionel Sambuc }
2290f4a2713aSLionel Sambuc 
VisitWhileStmt(const WhileStmt * W)2291f4a2713aSLionel Sambuc void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
2292f4a2713aSLionel Sambuc   AddStmt(W->getBody());
2293f4a2713aSLionel Sambuc   AddStmt(W->getCond());
2294f4a2713aSLionel Sambuc   AddDecl(W->getConditionVariable());
2295f4a2713aSLionel Sambuc }
2296f4a2713aSLionel Sambuc 
VisitTypeTraitExpr(const TypeTraitExpr * E)2297f4a2713aSLionel Sambuc void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
2298f4a2713aSLionel Sambuc   for (unsigned I = E->getNumArgs(); I > 0; --I)
2299f4a2713aSLionel Sambuc     AddTypeLoc(E->getArg(I-1));
2300f4a2713aSLionel Sambuc }
2301f4a2713aSLionel Sambuc 
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)2302f4a2713aSLionel Sambuc void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
2303f4a2713aSLionel Sambuc   AddTypeLoc(E->getQueriedTypeSourceInfo());
2304f4a2713aSLionel Sambuc }
2305f4a2713aSLionel Sambuc 
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)2306f4a2713aSLionel Sambuc void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
2307f4a2713aSLionel Sambuc   EnqueueChildren(E);
2308f4a2713aSLionel Sambuc }
2309f4a2713aSLionel Sambuc 
VisitUnresolvedMemberExpr(const UnresolvedMemberExpr * U)2310f4a2713aSLionel Sambuc void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
2311f4a2713aSLionel Sambuc   VisitOverloadExpr(U);
2312f4a2713aSLionel Sambuc   if (!U->isImplicitAccess())
2313f4a2713aSLionel Sambuc     AddStmt(U->getBase());
2314f4a2713aSLionel Sambuc }
VisitVAArgExpr(const VAArgExpr * E)2315f4a2713aSLionel Sambuc void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
2316f4a2713aSLionel Sambuc   AddStmt(E->getSubExpr());
2317f4a2713aSLionel Sambuc   AddTypeLoc(E->getWrittenTypeInfo());
2318f4a2713aSLionel Sambuc }
VisitSizeOfPackExpr(const SizeOfPackExpr * E)2319f4a2713aSLionel Sambuc void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
2320f4a2713aSLionel Sambuc   WL.push_back(SizeOfPackExprParts(E, Parent));
2321f4a2713aSLionel Sambuc }
VisitOpaqueValueExpr(const OpaqueValueExpr * E)2322f4a2713aSLionel Sambuc void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2323f4a2713aSLionel Sambuc   // If the opaque value has a source expression, just transparently
2324f4a2713aSLionel Sambuc   // visit that.  This is useful for (e.g.) pseudo-object expressions.
2325f4a2713aSLionel Sambuc   if (Expr *SourceExpr = E->getSourceExpr())
2326f4a2713aSLionel Sambuc     return Visit(SourceExpr);
2327f4a2713aSLionel Sambuc }
VisitLambdaExpr(const LambdaExpr * E)2328f4a2713aSLionel Sambuc void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
2329f4a2713aSLionel Sambuc   AddStmt(E->getBody());
2330f4a2713aSLionel Sambuc   WL.push_back(LambdaExprParts(E, Parent));
2331f4a2713aSLionel Sambuc }
VisitPseudoObjectExpr(const PseudoObjectExpr * E)2332f4a2713aSLionel Sambuc void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
2333f4a2713aSLionel Sambuc   // Treat the expression like its syntactic form.
2334f4a2713aSLionel Sambuc   Visit(E->getSyntacticForm());
2335f4a2713aSLionel Sambuc }
2336f4a2713aSLionel Sambuc 
VisitOMPExecutableDirective(const OMPExecutableDirective * D)2337f4a2713aSLionel Sambuc void EnqueueVisitor::VisitOMPExecutableDirective(
2338f4a2713aSLionel Sambuc   const OMPExecutableDirective *D) {
2339f4a2713aSLionel Sambuc   EnqueueChildren(D);
2340f4a2713aSLionel Sambuc   for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2341f4a2713aSLionel Sambuc                                        E = D->clauses().end();
2342f4a2713aSLionel Sambuc        I != E; ++I)
2343f4a2713aSLionel Sambuc     EnqueueChildren(*I);
2344f4a2713aSLionel Sambuc }
2345f4a2713aSLionel Sambuc 
VisitOMPLoopDirective(const OMPLoopDirective * D)2346*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2347*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2348*0a6a1f1dSLionel Sambuc }
2349*0a6a1f1dSLionel Sambuc 
VisitOMPParallelDirective(const OMPParallelDirective * D)2350f4a2713aSLionel Sambuc void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2351f4a2713aSLionel Sambuc   VisitOMPExecutableDirective(D);
2352f4a2713aSLionel Sambuc }
2353f4a2713aSLionel Sambuc 
VisitOMPSimdDirective(const OMPSimdDirective * D)2354*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2355*0a6a1f1dSLionel Sambuc   VisitOMPLoopDirective(D);
2356*0a6a1f1dSLionel Sambuc }
2357*0a6a1f1dSLionel Sambuc 
VisitOMPForDirective(const OMPForDirective * D)2358*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2359*0a6a1f1dSLionel Sambuc   VisitOMPLoopDirective(D);
2360*0a6a1f1dSLionel Sambuc }
2361*0a6a1f1dSLionel Sambuc 
VisitOMPForSimdDirective(const OMPForSimdDirective * D)2362*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2363*0a6a1f1dSLionel Sambuc   VisitOMPLoopDirective(D);
2364*0a6a1f1dSLionel Sambuc }
2365*0a6a1f1dSLionel Sambuc 
VisitOMPSectionsDirective(const OMPSectionsDirective * D)2366*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2367*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2368*0a6a1f1dSLionel Sambuc }
2369*0a6a1f1dSLionel Sambuc 
VisitOMPSectionDirective(const OMPSectionDirective * D)2370*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2371*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2372*0a6a1f1dSLionel Sambuc }
2373*0a6a1f1dSLionel Sambuc 
VisitOMPSingleDirective(const OMPSingleDirective * D)2374*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2375*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2376*0a6a1f1dSLionel Sambuc }
2377*0a6a1f1dSLionel Sambuc 
VisitOMPMasterDirective(const OMPMasterDirective * D)2378*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2379*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2380*0a6a1f1dSLionel Sambuc }
2381*0a6a1f1dSLionel Sambuc 
VisitOMPCriticalDirective(const OMPCriticalDirective * D)2382*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2383*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2384*0a6a1f1dSLionel Sambuc   AddDeclarationNameInfo(D);
2385*0a6a1f1dSLionel Sambuc }
2386*0a6a1f1dSLionel Sambuc 
2387*0a6a1f1dSLionel Sambuc void
VisitOMPParallelForDirective(const OMPParallelForDirective * D)2388*0a6a1f1dSLionel Sambuc EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2389*0a6a1f1dSLionel Sambuc   VisitOMPLoopDirective(D);
2390*0a6a1f1dSLionel Sambuc }
2391*0a6a1f1dSLionel Sambuc 
VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective * D)2392*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2393*0a6a1f1dSLionel Sambuc     const OMPParallelForSimdDirective *D) {
2394*0a6a1f1dSLionel Sambuc   VisitOMPLoopDirective(D);
2395*0a6a1f1dSLionel Sambuc }
2396*0a6a1f1dSLionel Sambuc 
VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective * D)2397*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2398*0a6a1f1dSLionel Sambuc     const OMPParallelSectionsDirective *D) {
2399*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2400*0a6a1f1dSLionel Sambuc }
2401*0a6a1f1dSLionel Sambuc 
VisitOMPTaskDirective(const OMPTaskDirective * D)2402*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2403*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2404*0a6a1f1dSLionel Sambuc }
2405*0a6a1f1dSLionel Sambuc 
2406*0a6a1f1dSLionel Sambuc void
VisitOMPTaskyieldDirective(const OMPTaskyieldDirective * D)2407*0a6a1f1dSLionel Sambuc EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2408*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2409*0a6a1f1dSLionel Sambuc }
2410*0a6a1f1dSLionel Sambuc 
VisitOMPBarrierDirective(const OMPBarrierDirective * D)2411*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2412*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2413*0a6a1f1dSLionel Sambuc }
2414*0a6a1f1dSLionel Sambuc 
VisitOMPTaskwaitDirective(const OMPTaskwaitDirective * D)2415*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2416*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2417*0a6a1f1dSLionel Sambuc }
2418*0a6a1f1dSLionel Sambuc 
VisitOMPFlushDirective(const OMPFlushDirective * D)2419*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2420*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2421*0a6a1f1dSLionel Sambuc }
2422*0a6a1f1dSLionel Sambuc 
VisitOMPOrderedDirective(const OMPOrderedDirective * D)2423*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2424*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2425*0a6a1f1dSLionel Sambuc }
2426*0a6a1f1dSLionel Sambuc 
VisitOMPAtomicDirective(const OMPAtomicDirective * D)2427*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2428*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2429*0a6a1f1dSLionel Sambuc }
2430*0a6a1f1dSLionel Sambuc 
VisitOMPTargetDirective(const OMPTargetDirective * D)2431*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2432*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2433*0a6a1f1dSLionel Sambuc }
2434*0a6a1f1dSLionel Sambuc 
VisitOMPTeamsDirective(const OMPTeamsDirective * D)2435*0a6a1f1dSLionel Sambuc void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2436*0a6a1f1dSLionel Sambuc   VisitOMPExecutableDirective(D);
2437*0a6a1f1dSLionel Sambuc }
2438*0a6a1f1dSLionel Sambuc 
EnqueueWorkList(VisitorWorkList & WL,const Stmt * S)2439f4a2713aSLionel Sambuc void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
2440f4a2713aSLionel Sambuc   EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2441f4a2713aSLionel Sambuc }
2442f4a2713aSLionel Sambuc 
IsInRegionOfInterest(CXCursor C)2443f4a2713aSLionel Sambuc bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2444f4a2713aSLionel Sambuc   if (RegionOfInterest.isValid()) {
2445f4a2713aSLionel Sambuc     SourceRange Range = getRawCursorExtent(C);
2446f4a2713aSLionel Sambuc     if (Range.isInvalid() || CompareRegionOfInterest(Range))
2447f4a2713aSLionel Sambuc       return false;
2448f4a2713aSLionel Sambuc   }
2449f4a2713aSLionel Sambuc   return true;
2450f4a2713aSLionel Sambuc }
2451f4a2713aSLionel Sambuc 
RunVisitorWorkList(VisitorWorkList & WL)2452f4a2713aSLionel Sambuc bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2453f4a2713aSLionel Sambuc   while (!WL.empty()) {
2454f4a2713aSLionel Sambuc     // Dequeue the worklist item.
2455f4a2713aSLionel Sambuc     VisitorJob LI = WL.pop_back_val();
2456f4a2713aSLionel Sambuc 
2457f4a2713aSLionel Sambuc     // Set the Parent field, then back to its old value once we're done.
2458f4a2713aSLionel Sambuc     SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2459f4a2713aSLionel Sambuc 
2460f4a2713aSLionel Sambuc     switch (LI.getKind()) {
2461f4a2713aSLionel Sambuc       case VisitorJob::DeclVisitKind: {
2462f4a2713aSLionel Sambuc         const Decl *D = cast<DeclVisit>(&LI)->get();
2463f4a2713aSLionel Sambuc         if (!D)
2464f4a2713aSLionel Sambuc           continue;
2465f4a2713aSLionel Sambuc 
2466f4a2713aSLionel Sambuc         // For now, perform default visitation for Decls.
2467f4a2713aSLionel Sambuc         if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2468f4a2713aSLionel Sambuc                                cast<DeclVisit>(&LI)->isFirst())))
2469f4a2713aSLionel Sambuc             return true;
2470f4a2713aSLionel Sambuc 
2471f4a2713aSLionel Sambuc         continue;
2472f4a2713aSLionel Sambuc       }
2473f4a2713aSLionel Sambuc       case VisitorJob::ExplicitTemplateArgsVisitKind: {
2474f4a2713aSLionel Sambuc         const ASTTemplateArgumentListInfo *ArgList =
2475f4a2713aSLionel Sambuc           cast<ExplicitTemplateArgsVisit>(&LI)->get();
2476f4a2713aSLionel Sambuc         for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2477f4a2713aSLionel Sambuc                *ArgEnd = Arg + ArgList->NumTemplateArgs;
2478f4a2713aSLionel Sambuc                Arg != ArgEnd; ++Arg) {
2479f4a2713aSLionel Sambuc           if (VisitTemplateArgumentLoc(*Arg))
2480f4a2713aSLionel Sambuc             return true;
2481f4a2713aSLionel Sambuc         }
2482f4a2713aSLionel Sambuc         continue;
2483f4a2713aSLionel Sambuc       }
2484f4a2713aSLionel Sambuc       case VisitorJob::TypeLocVisitKind: {
2485f4a2713aSLionel Sambuc         // Perform default visitation for TypeLocs.
2486f4a2713aSLionel Sambuc         if (Visit(cast<TypeLocVisit>(&LI)->get()))
2487f4a2713aSLionel Sambuc           return true;
2488f4a2713aSLionel Sambuc         continue;
2489f4a2713aSLionel Sambuc       }
2490f4a2713aSLionel Sambuc       case VisitorJob::LabelRefVisitKind: {
2491f4a2713aSLionel Sambuc         const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
2492f4a2713aSLionel Sambuc         if (LabelStmt *stmt = LS->getStmt()) {
2493f4a2713aSLionel Sambuc           if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2494f4a2713aSLionel Sambuc                                        TU))) {
2495f4a2713aSLionel Sambuc             return true;
2496f4a2713aSLionel Sambuc           }
2497f4a2713aSLionel Sambuc         }
2498f4a2713aSLionel Sambuc         continue;
2499f4a2713aSLionel Sambuc       }
2500f4a2713aSLionel Sambuc 
2501f4a2713aSLionel Sambuc       case VisitorJob::NestedNameSpecifierLocVisitKind: {
2502f4a2713aSLionel Sambuc         NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2503f4a2713aSLionel Sambuc         if (VisitNestedNameSpecifierLoc(V->get()))
2504f4a2713aSLionel Sambuc           return true;
2505f4a2713aSLionel Sambuc         continue;
2506f4a2713aSLionel Sambuc       }
2507f4a2713aSLionel Sambuc 
2508f4a2713aSLionel Sambuc       case VisitorJob::DeclarationNameInfoVisitKind: {
2509f4a2713aSLionel Sambuc         if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2510f4a2713aSLionel Sambuc                                      ->get()))
2511f4a2713aSLionel Sambuc           return true;
2512f4a2713aSLionel Sambuc         continue;
2513f4a2713aSLionel Sambuc       }
2514f4a2713aSLionel Sambuc       case VisitorJob::MemberRefVisitKind: {
2515f4a2713aSLionel Sambuc         MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2516f4a2713aSLionel Sambuc         if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2517f4a2713aSLionel Sambuc           return true;
2518f4a2713aSLionel Sambuc         continue;
2519f4a2713aSLionel Sambuc       }
2520f4a2713aSLionel Sambuc       case VisitorJob::StmtVisitKind: {
2521f4a2713aSLionel Sambuc         const Stmt *S = cast<StmtVisit>(&LI)->get();
2522f4a2713aSLionel Sambuc         if (!S)
2523f4a2713aSLionel Sambuc           continue;
2524f4a2713aSLionel Sambuc 
2525f4a2713aSLionel Sambuc         // Update the current cursor.
2526f4a2713aSLionel Sambuc         CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2527f4a2713aSLionel Sambuc         if (!IsInRegionOfInterest(Cursor))
2528f4a2713aSLionel Sambuc           continue;
2529f4a2713aSLionel Sambuc         switch (Visitor(Cursor, Parent, ClientData)) {
2530f4a2713aSLionel Sambuc           case CXChildVisit_Break: return true;
2531f4a2713aSLionel Sambuc           case CXChildVisit_Continue: break;
2532f4a2713aSLionel Sambuc           case CXChildVisit_Recurse:
2533f4a2713aSLionel Sambuc             if (PostChildrenVisitor)
2534*0a6a1f1dSLionel Sambuc               WL.push_back(PostChildrenVisit(nullptr, Cursor));
2535f4a2713aSLionel Sambuc             EnqueueWorkList(WL, S);
2536f4a2713aSLionel Sambuc             break;
2537f4a2713aSLionel Sambuc         }
2538f4a2713aSLionel Sambuc         continue;
2539f4a2713aSLionel Sambuc       }
2540f4a2713aSLionel Sambuc       case VisitorJob::MemberExprPartsKind: {
2541f4a2713aSLionel Sambuc         // Handle the other pieces in the MemberExpr besides the base.
2542f4a2713aSLionel Sambuc         const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
2543f4a2713aSLionel Sambuc 
2544f4a2713aSLionel Sambuc         // Visit the nested-name-specifier
2545f4a2713aSLionel Sambuc         if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2546f4a2713aSLionel Sambuc           if (VisitNestedNameSpecifierLoc(QualifierLoc))
2547f4a2713aSLionel Sambuc             return true;
2548f4a2713aSLionel Sambuc 
2549f4a2713aSLionel Sambuc         // Visit the declaration name.
2550f4a2713aSLionel Sambuc         if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2551f4a2713aSLionel Sambuc           return true;
2552f4a2713aSLionel Sambuc 
2553f4a2713aSLionel Sambuc         // Visit the explicitly-specified template arguments, if any.
2554f4a2713aSLionel Sambuc         if (M->hasExplicitTemplateArgs()) {
2555f4a2713aSLionel Sambuc           for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2556f4a2713aSLionel Sambuc                *ArgEnd = Arg + M->getNumTemplateArgs();
2557f4a2713aSLionel Sambuc                Arg != ArgEnd; ++Arg) {
2558f4a2713aSLionel Sambuc             if (VisitTemplateArgumentLoc(*Arg))
2559f4a2713aSLionel Sambuc               return true;
2560f4a2713aSLionel Sambuc           }
2561f4a2713aSLionel Sambuc         }
2562f4a2713aSLionel Sambuc         continue;
2563f4a2713aSLionel Sambuc       }
2564f4a2713aSLionel Sambuc       case VisitorJob::DeclRefExprPartsKind: {
2565f4a2713aSLionel Sambuc         const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
2566f4a2713aSLionel Sambuc         // Visit nested-name-specifier, if present.
2567f4a2713aSLionel Sambuc         if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2568f4a2713aSLionel Sambuc           if (VisitNestedNameSpecifierLoc(QualifierLoc))
2569f4a2713aSLionel Sambuc             return true;
2570f4a2713aSLionel Sambuc         // Visit declaration name.
2571f4a2713aSLionel Sambuc         if (VisitDeclarationNameInfo(DR->getNameInfo()))
2572f4a2713aSLionel Sambuc           return true;
2573f4a2713aSLionel Sambuc         continue;
2574f4a2713aSLionel Sambuc       }
2575f4a2713aSLionel Sambuc       case VisitorJob::OverloadExprPartsKind: {
2576f4a2713aSLionel Sambuc         const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
2577f4a2713aSLionel Sambuc         // Visit the nested-name-specifier.
2578f4a2713aSLionel Sambuc         if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2579f4a2713aSLionel Sambuc           if (VisitNestedNameSpecifierLoc(QualifierLoc))
2580f4a2713aSLionel Sambuc             return true;
2581f4a2713aSLionel Sambuc         // Visit the declaration name.
2582f4a2713aSLionel Sambuc         if (VisitDeclarationNameInfo(O->getNameInfo()))
2583f4a2713aSLionel Sambuc           return true;
2584f4a2713aSLionel Sambuc         // Visit the overloaded declaration reference.
2585f4a2713aSLionel Sambuc         if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2586f4a2713aSLionel Sambuc           return true;
2587f4a2713aSLionel Sambuc         continue;
2588f4a2713aSLionel Sambuc       }
2589f4a2713aSLionel Sambuc       case VisitorJob::SizeOfPackExprPartsKind: {
2590f4a2713aSLionel Sambuc         const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2591f4a2713aSLionel Sambuc         NamedDecl *Pack = E->getPack();
2592f4a2713aSLionel Sambuc         if (isa<TemplateTypeParmDecl>(Pack)) {
2593f4a2713aSLionel Sambuc           if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2594f4a2713aSLionel Sambuc                                       E->getPackLoc(), TU)))
2595f4a2713aSLionel Sambuc             return true;
2596f4a2713aSLionel Sambuc 
2597f4a2713aSLionel Sambuc           continue;
2598f4a2713aSLionel Sambuc         }
2599f4a2713aSLionel Sambuc 
2600f4a2713aSLionel Sambuc         if (isa<TemplateTemplateParmDecl>(Pack)) {
2601f4a2713aSLionel Sambuc           if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2602f4a2713aSLionel Sambuc                                           E->getPackLoc(), TU)))
2603f4a2713aSLionel Sambuc             return true;
2604f4a2713aSLionel Sambuc 
2605f4a2713aSLionel Sambuc           continue;
2606f4a2713aSLionel Sambuc         }
2607f4a2713aSLionel Sambuc 
2608f4a2713aSLionel Sambuc         // Non-type template parameter packs and function parameter packs are
2609f4a2713aSLionel Sambuc         // treated like DeclRefExpr cursors.
2610f4a2713aSLionel Sambuc         continue;
2611f4a2713aSLionel Sambuc       }
2612f4a2713aSLionel Sambuc 
2613f4a2713aSLionel Sambuc       case VisitorJob::LambdaExprPartsKind: {
2614f4a2713aSLionel Sambuc         // Visit captures.
2615f4a2713aSLionel Sambuc         const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
2616f4a2713aSLionel Sambuc         for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2617f4a2713aSLionel Sambuc                                        CEnd = E->explicit_capture_end();
2618f4a2713aSLionel Sambuc              C != CEnd; ++C) {
2619f4a2713aSLionel Sambuc           // FIXME: Lambda init-captures.
2620f4a2713aSLionel Sambuc           if (!C->capturesVariable())
2621f4a2713aSLionel Sambuc             continue;
2622f4a2713aSLionel Sambuc 
2623f4a2713aSLionel Sambuc           if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2624f4a2713aSLionel Sambuc                                           C->getLocation(),
2625f4a2713aSLionel Sambuc                                           TU)))
2626f4a2713aSLionel Sambuc             return true;
2627f4a2713aSLionel Sambuc         }
2628f4a2713aSLionel Sambuc 
2629f4a2713aSLionel Sambuc         // Visit parameters and return type, if present.
2630f4a2713aSLionel Sambuc         if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2631f4a2713aSLionel Sambuc           TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2632f4a2713aSLionel Sambuc           if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2633f4a2713aSLionel Sambuc             // Visit the whole type.
2634f4a2713aSLionel Sambuc             if (Visit(TL))
2635f4a2713aSLionel Sambuc               return true;
2636f4a2713aSLionel Sambuc           } else if (FunctionProtoTypeLoc Proto =
2637f4a2713aSLionel Sambuc                          TL.getAs<FunctionProtoTypeLoc>()) {
2638f4a2713aSLionel Sambuc             if (E->hasExplicitParameters()) {
2639f4a2713aSLionel Sambuc               // Visit parameters.
2640*0a6a1f1dSLionel Sambuc               for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2641*0a6a1f1dSLionel Sambuc                 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
2642f4a2713aSLionel Sambuc                   return true;
2643f4a2713aSLionel Sambuc             } else {
2644f4a2713aSLionel Sambuc               // Visit result type.
2645*0a6a1f1dSLionel Sambuc               if (Visit(Proto.getReturnLoc()))
2646f4a2713aSLionel Sambuc                 return true;
2647f4a2713aSLionel Sambuc             }
2648f4a2713aSLionel Sambuc           }
2649f4a2713aSLionel Sambuc         }
2650f4a2713aSLionel Sambuc         break;
2651f4a2713aSLionel Sambuc       }
2652f4a2713aSLionel Sambuc 
2653f4a2713aSLionel Sambuc       case VisitorJob::PostChildrenVisitKind:
2654f4a2713aSLionel Sambuc         if (PostChildrenVisitor(Parent, ClientData))
2655f4a2713aSLionel Sambuc           return true;
2656f4a2713aSLionel Sambuc         break;
2657f4a2713aSLionel Sambuc     }
2658f4a2713aSLionel Sambuc   }
2659f4a2713aSLionel Sambuc   return false;
2660f4a2713aSLionel Sambuc }
2661f4a2713aSLionel Sambuc 
Visit(const Stmt * S)2662f4a2713aSLionel Sambuc bool CursorVisitor::Visit(const Stmt *S) {
2663*0a6a1f1dSLionel Sambuc   VisitorWorkList *WL = nullptr;
2664f4a2713aSLionel Sambuc   if (!WorkListFreeList.empty()) {
2665f4a2713aSLionel Sambuc     WL = WorkListFreeList.back();
2666f4a2713aSLionel Sambuc     WL->clear();
2667f4a2713aSLionel Sambuc     WorkListFreeList.pop_back();
2668f4a2713aSLionel Sambuc   }
2669f4a2713aSLionel Sambuc   else {
2670f4a2713aSLionel Sambuc     WL = new VisitorWorkList();
2671f4a2713aSLionel Sambuc     WorkListCache.push_back(WL);
2672f4a2713aSLionel Sambuc   }
2673f4a2713aSLionel Sambuc   EnqueueWorkList(*WL, S);
2674f4a2713aSLionel Sambuc   bool result = RunVisitorWorkList(*WL);
2675f4a2713aSLionel Sambuc   WorkListFreeList.push_back(WL);
2676f4a2713aSLionel Sambuc   return result;
2677f4a2713aSLionel Sambuc }
2678f4a2713aSLionel Sambuc 
2679f4a2713aSLionel Sambuc namespace {
2680f4a2713aSLionel Sambuc typedef SmallVector<SourceRange, 4> RefNamePieces;
2681*0a6a1f1dSLionel Sambuc RefNamePieces
buildPieces(unsigned NameFlags,bool IsMemberRefExpr,const DeclarationNameInfo & NI,const SourceRange & QLoc,const ASTTemplateArgumentListInfo * TemplateArgs=nullptr)2682*0a6a1f1dSLionel Sambuc buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2683*0a6a1f1dSLionel Sambuc             const DeclarationNameInfo &NI, const SourceRange &QLoc,
2684*0a6a1f1dSLionel Sambuc             const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
2685f4a2713aSLionel Sambuc   const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2686f4a2713aSLionel Sambuc   const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2687f4a2713aSLionel Sambuc   const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2688f4a2713aSLionel Sambuc 
2689f4a2713aSLionel Sambuc   const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2690f4a2713aSLionel Sambuc 
2691f4a2713aSLionel Sambuc   RefNamePieces Pieces;
2692f4a2713aSLionel Sambuc 
2693f4a2713aSLionel Sambuc   if (WantQualifier && QLoc.isValid())
2694f4a2713aSLionel Sambuc     Pieces.push_back(QLoc);
2695f4a2713aSLionel Sambuc 
2696f4a2713aSLionel Sambuc   if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2697f4a2713aSLionel Sambuc     Pieces.push_back(NI.getLoc());
2698f4a2713aSLionel Sambuc 
2699f4a2713aSLionel Sambuc   if (WantTemplateArgs && TemplateArgs)
2700f4a2713aSLionel Sambuc     Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2701f4a2713aSLionel Sambuc                                  TemplateArgs->RAngleLoc));
2702f4a2713aSLionel Sambuc 
2703f4a2713aSLionel Sambuc   if (Kind == DeclarationName::CXXOperatorName) {
2704f4a2713aSLionel Sambuc     Pieces.push_back(SourceLocation::getFromRawEncoding(
2705f4a2713aSLionel Sambuc                        NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2706f4a2713aSLionel Sambuc     Pieces.push_back(SourceLocation::getFromRawEncoding(
2707f4a2713aSLionel Sambuc                        NI.getInfo().CXXOperatorName.EndOpNameLoc));
2708f4a2713aSLionel Sambuc   }
2709f4a2713aSLionel Sambuc 
2710f4a2713aSLionel Sambuc   if (WantSinglePiece) {
2711f4a2713aSLionel Sambuc     SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2712f4a2713aSLionel Sambuc     Pieces.clear();
2713f4a2713aSLionel Sambuc     Pieces.push_back(R);
2714f4a2713aSLionel Sambuc   }
2715f4a2713aSLionel Sambuc 
2716f4a2713aSLionel Sambuc   return Pieces;
2717f4a2713aSLionel Sambuc }
2718f4a2713aSLionel Sambuc }
2719f4a2713aSLionel Sambuc 
2720f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2721f4a2713aSLionel Sambuc // Misc. API hooks.
2722f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
2723f4a2713aSLionel Sambuc 
fatal_error_handler(void * user_data,const std::string & reason,bool gen_crash_diag)2724f4a2713aSLionel Sambuc static void fatal_error_handler(void *user_data, const std::string& reason,
2725f4a2713aSLionel Sambuc                                 bool gen_crash_diag) {
2726f4a2713aSLionel Sambuc   // Write the result out to stderr avoiding errs() because raw_ostreams can
2727f4a2713aSLionel Sambuc   // call report_fatal_error.
2728f4a2713aSLionel Sambuc   fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2729f4a2713aSLionel Sambuc   ::abort();
2730f4a2713aSLionel Sambuc }
2731f4a2713aSLionel Sambuc 
2732*0a6a1f1dSLionel Sambuc namespace {
2733*0a6a1f1dSLionel Sambuc struct RegisterFatalErrorHandler {
RegisterFatalErrorHandler__anon527c650d0511::RegisterFatalErrorHandler2734*0a6a1f1dSLionel Sambuc   RegisterFatalErrorHandler() {
2735*0a6a1f1dSLionel Sambuc     llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2736*0a6a1f1dSLionel Sambuc   }
2737*0a6a1f1dSLionel Sambuc };
2738*0a6a1f1dSLionel Sambuc }
2739*0a6a1f1dSLionel Sambuc 
2740*0a6a1f1dSLionel Sambuc static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2741*0a6a1f1dSLionel Sambuc 
2742f4a2713aSLionel Sambuc extern "C" {
clang_createIndex(int excludeDeclarationsFromPCH,int displayDiagnostics)2743f4a2713aSLionel Sambuc CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2744f4a2713aSLionel Sambuc                           int displayDiagnostics) {
2745f4a2713aSLionel Sambuc   // We use crash recovery to make some of our APIs more reliable, implicitly
2746f4a2713aSLionel Sambuc   // enable it.
2747*0a6a1f1dSLionel Sambuc   if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2748f4a2713aSLionel Sambuc     llvm::CrashRecoveryContext::Enable();
2749f4a2713aSLionel Sambuc 
2750*0a6a1f1dSLionel Sambuc   // Look through the managed static to trigger construction of the managed
2751*0a6a1f1dSLionel Sambuc   // static which registers our fatal error handler. This ensures it is only
2752*0a6a1f1dSLionel Sambuc   // registered once.
2753*0a6a1f1dSLionel Sambuc   (void)*RegisterFatalErrorHandlerOnce;
2754f4a2713aSLionel Sambuc 
2755f4a2713aSLionel Sambuc   CIndexer *CIdxr = new CIndexer();
2756f4a2713aSLionel Sambuc   if (excludeDeclarationsFromPCH)
2757f4a2713aSLionel Sambuc     CIdxr->setOnlyLocalDecls();
2758f4a2713aSLionel Sambuc   if (displayDiagnostics)
2759f4a2713aSLionel Sambuc     CIdxr->setDisplayDiagnostics();
2760f4a2713aSLionel Sambuc 
2761f4a2713aSLionel Sambuc   if (getenv("LIBCLANG_BGPRIO_INDEX"))
2762f4a2713aSLionel Sambuc     CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2763f4a2713aSLionel Sambuc                                CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2764f4a2713aSLionel Sambuc   if (getenv("LIBCLANG_BGPRIO_EDIT"))
2765f4a2713aSLionel Sambuc     CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2766f4a2713aSLionel Sambuc                                CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2767f4a2713aSLionel Sambuc 
2768f4a2713aSLionel Sambuc   return CIdxr;
2769f4a2713aSLionel Sambuc }
2770f4a2713aSLionel Sambuc 
clang_disposeIndex(CXIndex CIdx)2771f4a2713aSLionel Sambuc void clang_disposeIndex(CXIndex CIdx) {
2772f4a2713aSLionel Sambuc   if (CIdx)
2773f4a2713aSLionel Sambuc     delete static_cast<CIndexer *>(CIdx);
2774f4a2713aSLionel Sambuc }
2775f4a2713aSLionel Sambuc 
clang_CXIndex_setGlobalOptions(CXIndex CIdx,unsigned options)2776f4a2713aSLionel Sambuc void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2777f4a2713aSLionel Sambuc   if (CIdx)
2778f4a2713aSLionel Sambuc     static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2779f4a2713aSLionel Sambuc }
2780f4a2713aSLionel Sambuc 
clang_CXIndex_getGlobalOptions(CXIndex CIdx)2781f4a2713aSLionel Sambuc unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2782f4a2713aSLionel Sambuc   if (CIdx)
2783f4a2713aSLionel Sambuc     return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2784f4a2713aSLionel Sambuc   return 0;
2785f4a2713aSLionel Sambuc }
2786f4a2713aSLionel Sambuc 
clang_toggleCrashRecovery(unsigned isEnabled)2787f4a2713aSLionel Sambuc void clang_toggleCrashRecovery(unsigned isEnabled) {
2788f4a2713aSLionel Sambuc   if (isEnabled)
2789f4a2713aSLionel Sambuc     llvm::CrashRecoveryContext::Enable();
2790f4a2713aSLionel Sambuc   else
2791f4a2713aSLionel Sambuc     llvm::CrashRecoveryContext::Disable();
2792f4a2713aSLionel Sambuc }
2793f4a2713aSLionel Sambuc 
clang_createTranslationUnit(CXIndex CIdx,const char * ast_filename)2794f4a2713aSLionel Sambuc CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2795f4a2713aSLionel Sambuc                                               const char *ast_filename) {
2796*0a6a1f1dSLionel Sambuc   CXTranslationUnit TU;
2797*0a6a1f1dSLionel Sambuc   enum CXErrorCode Result =
2798*0a6a1f1dSLionel Sambuc       clang_createTranslationUnit2(CIdx, ast_filename, &TU);
2799*0a6a1f1dSLionel Sambuc   (void)Result;
2800*0a6a1f1dSLionel Sambuc   assert((TU && Result == CXError_Success) ||
2801*0a6a1f1dSLionel Sambuc          (!TU && Result != CXError_Success));
2802*0a6a1f1dSLionel Sambuc   return TU;
2803*0a6a1f1dSLionel Sambuc }
2804*0a6a1f1dSLionel Sambuc 
clang_createTranslationUnit2(CXIndex CIdx,const char * ast_filename,CXTranslationUnit * out_TU)2805*0a6a1f1dSLionel Sambuc enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2806*0a6a1f1dSLionel Sambuc                                               const char *ast_filename,
2807*0a6a1f1dSLionel Sambuc                                               CXTranslationUnit *out_TU) {
2808*0a6a1f1dSLionel Sambuc   if (out_TU)
2809*0a6a1f1dSLionel Sambuc     *out_TU = nullptr;
2810*0a6a1f1dSLionel Sambuc 
2811*0a6a1f1dSLionel Sambuc   if (!CIdx || !ast_filename || !out_TU)
2812*0a6a1f1dSLionel Sambuc     return CXError_InvalidArguments;
2813f4a2713aSLionel Sambuc 
2814f4a2713aSLionel Sambuc   LOG_FUNC_SECTION {
2815f4a2713aSLionel Sambuc     *Log << ast_filename;
2816f4a2713aSLionel Sambuc   }
2817f4a2713aSLionel Sambuc 
2818f4a2713aSLionel Sambuc   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2819f4a2713aSLionel Sambuc   FileSystemOptions FileSystemOpts;
2820f4a2713aSLionel Sambuc 
2821*0a6a1f1dSLionel Sambuc   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2822*0a6a1f1dSLionel Sambuc       CompilerInstance::createDiagnostics(new DiagnosticOptions());
2823*0a6a1f1dSLionel Sambuc   std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
2824*0a6a1f1dSLionel Sambuc       ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
2825f4a2713aSLionel Sambuc       /*CaptureDiagnostics=*/true,
2826f4a2713aSLionel Sambuc       /*AllowPCHWithCompilerErrors=*/true,
2827f4a2713aSLionel Sambuc       /*UserFilesAreVolatile=*/true);
2828*0a6a1f1dSLionel Sambuc   *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
2829*0a6a1f1dSLionel Sambuc   return *out_TU ? CXError_Success : CXError_Failure;
2830f4a2713aSLionel Sambuc }
2831f4a2713aSLionel Sambuc 
clang_defaultEditingTranslationUnitOptions()2832f4a2713aSLionel Sambuc unsigned clang_defaultEditingTranslationUnitOptions() {
2833f4a2713aSLionel Sambuc   return CXTranslationUnit_PrecompiledPreamble |
2834f4a2713aSLionel Sambuc          CXTranslationUnit_CacheCompletionResults;
2835f4a2713aSLionel Sambuc }
2836f4a2713aSLionel Sambuc 
2837f4a2713aSLionel Sambuc CXTranslationUnit
clang_createTranslationUnitFromSourceFile(CXIndex CIdx,const char * source_filename,int num_command_line_args,const char * const * command_line_args,unsigned num_unsaved_files,struct CXUnsavedFile * unsaved_files)2838f4a2713aSLionel Sambuc clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2839f4a2713aSLionel Sambuc                                           const char *source_filename,
2840f4a2713aSLionel Sambuc                                           int num_command_line_args,
2841f4a2713aSLionel Sambuc                                           const char * const *command_line_args,
2842f4a2713aSLionel Sambuc                                           unsigned num_unsaved_files,
2843f4a2713aSLionel Sambuc                                           struct CXUnsavedFile *unsaved_files) {
2844f4a2713aSLionel Sambuc   unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2845f4a2713aSLionel Sambuc   return clang_parseTranslationUnit(CIdx, source_filename,
2846f4a2713aSLionel Sambuc                                     command_line_args, num_command_line_args,
2847f4a2713aSLionel Sambuc                                     unsaved_files, num_unsaved_files,
2848f4a2713aSLionel Sambuc                                     Options);
2849f4a2713aSLionel Sambuc }
2850f4a2713aSLionel Sambuc 
2851f4a2713aSLionel Sambuc struct ParseTranslationUnitInfo {
2852f4a2713aSLionel Sambuc   CXIndex CIdx;
2853f4a2713aSLionel Sambuc   const char *source_filename;
2854f4a2713aSLionel Sambuc   const char *const *command_line_args;
2855f4a2713aSLionel Sambuc   int num_command_line_args;
2856*0a6a1f1dSLionel Sambuc   ArrayRef<CXUnsavedFile> unsaved_files;
2857f4a2713aSLionel Sambuc   unsigned options;
2858*0a6a1f1dSLionel Sambuc   CXTranslationUnit *out_TU;
2859*0a6a1f1dSLionel Sambuc   CXErrorCode &result;
2860f4a2713aSLionel Sambuc };
clang_parseTranslationUnit_Impl(void * UserData)2861f4a2713aSLionel Sambuc static void clang_parseTranslationUnit_Impl(void *UserData) {
2862*0a6a1f1dSLionel Sambuc   const ParseTranslationUnitInfo *PTUI =
2863f4a2713aSLionel Sambuc       static_cast<ParseTranslationUnitInfo *>(UserData);
2864f4a2713aSLionel Sambuc   CXIndex CIdx = PTUI->CIdx;
2865f4a2713aSLionel Sambuc   const char *source_filename = PTUI->source_filename;
2866f4a2713aSLionel Sambuc   const char * const *command_line_args = PTUI->command_line_args;
2867f4a2713aSLionel Sambuc   int num_command_line_args = PTUI->num_command_line_args;
2868f4a2713aSLionel Sambuc   unsigned options = PTUI->options;
2869*0a6a1f1dSLionel Sambuc   CXTranslationUnit *out_TU = PTUI->out_TU;
2870f4a2713aSLionel Sambuc 
2871*0a6a1f1dSLionel Sambuc   // Set up the initial return values.
2872*0a6a1f1dSLionel Sambuc   if (out_TU)
2873*0a6a1f1dSLionel Sambuc     *out_TU = nullptr;
2874*0a6a1f1dSLionel Sambuc 
2875*0a6a1f1dSLionel Sambuc   // Check arguments.
2876*0a6a1f1dSLionel Sambuc   if (!CIdx || !out_TU) {
2877*0a6a1f1dSLionel Sambuc     PTUI->result = CXError_InvalidArguments;
2878f4a2713aSLionel Sambuc     return;
2879*0a6a1f1dSLionel Sambuc   }
2880f4a2713aSLionel Sambuc 
2881f4a2713aSLionel Sambuc   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2882f4a2713aSLionel Sambuc 
2883f4a2713aSLionel Sambuc   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2884f4a2713aSLionel Sambuc     setThreadBackgroundPriority();
2885f4a2713aSLionel Sambuc 
2886f4a2713aSLionel Sambuc   bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2887f4a2713aSLionel Sambuc   // FIXME: Add a flag for modules.
2888f4a2713aSLionel Sambuc   TranslationUnitKind TUKind
2889f4a2713aSLionel Sambuc     = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2890*0a6a1f1dSLionel Sambuc   bool CacheCodeCompletionResults
2891f4a2713aSLionel Sambuc     = options & CXTranslationUnit_CacheCompletionResults;
2892f4a2713aSLionel Sambuc   bool IncludeBriefCommentsInCodeCompletion
2893f4a2713aSLionel Sambuc     = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2894f4a2713aSLionel Sambuc   bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2895f4a2713aSLionel Sambuc   bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2896f4a2713aSLionel Sambuc 
2897f4a2713aSLionel Sambuc   // Configure the diagnostics.
2898f4a2713aSLionel Sambuc   IntrusiveRefCntPtr<DiagnosticsEngine>
2899f4a2713aSLionel Sambuc     Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
2900f4a2713aSLionel Sambuc 
2901f4a2713aSLionel Sambuc   // Recover resources if we crash before exiting this function.
2902f4a2713aSLionel Sambuc   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2903f4a2713aSLionel Sambuc     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2904*0a6a1f1dSLionel Sambuc     DiagCleanup(Diags.get());
2905f4a2713aSLionel Sambuc 
2906*0a6a1f1dSLionel Sambuc   std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2907*0a6a1f1dSLionel Sambuc       new std::vector<ASTUnit::RemappedFile>());
2908f4a2713aSLionel Sambuc 
2909f4a2713aSLionel Sambuc   // Recover resources if we crash before exiting this function.
2910f4a2713aSLionel Sambuc   llvm::CrashRecoveryContextCleanupRegistrar<
2911f4a2713aSLionel Sambuc     std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2912f4a2713aSLionel Sambuc 
2913*0a6a1f1dSLionel Sambuc   for (auto &UF : PTUI->unsaved_files) {
2914*0a6a1f1dSLionel Sambuc     std::unique_ptr<llvm::MemoryBuffer> MB =
2915*0a6a1f1dSLionel Sambuc         llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
2916*0a6a1f1dSLionel Sambuc     RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
2917f4a2713aSLionel Sambuc   }
2918f4a2713aSLionel Sambuc 
2919*0a6a1f1dSLionel Sambuc   std::unique_ptr<std::vector<const char *>> Args(
2920*0a6a1f1dSLionel Sambuc       new std::vector<const char *>());
2921f4a2713aSLionel Sambuc 
2922f4a2713aSLionel Sambuc   // Recover resources if we crash before exiting this method.
2923f4a2713aSLionel Sambuc   llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2924f4a2713aSLionel Sambuc     ArgsCleanup(Args.get());
2925f4a2713aSLionel Sambuc 
2926f4a2713aSLionel Sambuc   // Since the Clang C library is primarily used by batch tools dealing with
2927f4a2713aSLionel Sambuc   // (often very broken) source code, where spell-checking can have a
2928f4a2713aSLionel Sambuc   // significant negative impact on performance (particularly when
2929f4a2713aSLionel Sambuc   // precompiled headers are involved), we disable it by default.
2930f4a2713aSLionel Sambuc   // Only do this if we haven't found a spell-checking-related argument.
2931f4a2713aSLionel Sambuc   bool FoundSpellCheckingArgument = false;
2932f4a2713aSLionel Sambuc   for (int I = 0; I != num_command_line_args; ++I) {
2933f4a2713aSLionel Sambuc     if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2934f4a2713aSLionel Sambuc         strcmp(command_line_args[I], "-fspell-checking") == 0) {
2935f4a2713aSLionel Sambuc       FoundSpellCheckingArgument = true;
2936f4a2713aSLionel Sambuc       break;
2937f4a2713aSLionel Sambuc     }
2938f4a2713aSLionel Sambuc   }
2939f4a2713aSLionel Sambuc   if (!FoundSpellCheckingArgument)
2940f4a2713aSLionel Sambuc     Args->push_back("-fno-spell-checking");
2941f4a2713aSLionel Sambuc 
2942f4a2713aSLionel Sambuc   Args->insert(Args->end(), command_line_args,
2943f4a2713aSLionel Sambuc                command_line_args + num_command_line_args);
2944f4a2713aSLionel Sambuc 
2945f4a2713aSLionel Sambuc   // The 'source_filename' argument is optional.  If the caller does not
2946f4a2713aSLionel Sambuc   // specify it then it is assumed that the source file is specified
2947f4a2713aSLionel Sambuc   // in the actual argument list.
2948f4a2713aSLionel Sambuc   // Put the source file after command_line_args otherwise if '-x' flag is
2949f4a2713aSLionel Sambuc   // present it will be unused.
2950f4a2713aSLionel Sambuc   if (source_filename)
2951f4a2713aSLionel Sambuc     Args->push_back(source_filename);
2952f4a2713aSLionel Sambuc 
2953f4a2713aSLionel Sambuc   // Do we need the detailed preprocessing record?
2954f4a2713aSLionel Sambuc   if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2955f4a2713aSLionel Sambuc     Args->push_back("-Xclang");
2956f4a2713aSLionel Sambuc     Args->push_back("-detailed-preprocessing-record");
2957f4a2713aSLionel Sambuc   }
2958f4a2713aSLionel Sambuc 
2959f4a2713aSLionel Sambuc   unsigned NumErrors = Diags->getClient()->getNumErrors();
2960*0a6a1f1dSLionel Sambuc   std::unique_ptr<ASTUnit> ErrUnit;
2961*0a6a1f1dSLionel Sambuc   std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
2962*0a6a1f1dSLionel Sambuc       Args->data(), Args->data() + Args->size(), Diags,
2963*0a6a1f1dSLionel Sambuc       CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2964*0a6a1f1dSLionel Sambuc       /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2965*0a6a1f1dSLionel Sambuc       /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2966*0a6a1f1dSLionel Sambuc       CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2967*0a6a1f1dSLionel Sambuc       /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2968*0a6a1f1dSLionel Sambuc       /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
2969f4a2713aSLionel Sambuc 
2970f4a2713aSLionel Sambuc   if (NumErrors != Diags->getClient()->getNumErrors()) {
2971f4a2713aSLionel Sambuc     // Make sure to check that 'Unit' is non-NULL.
2972f4a2713aSLionel Sambuc     if (CXXIdx->getDisplayDiagnostics())
2973f4a2713aSLionel Sambuc       printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2974f4a2713aSLionel Sambuc   }
2975f4a2713aSLionel Sambuc 
2976*0a6a1f1dSLionel Sambuc   if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2977*0a6a1f1dSLionel Sambuc     PTUI->result = CXError_ASTReadError;
2978*0a6a1f1dSLionel Sambuc   } else {
2979*0a6a1f1dSLionel Sambuc     *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
2980*0a6a1f1dSLionel Sambuc     PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2981f4a2713aSLionel Sambuc   }
2982*0a6a1f1dSLionel Sambuc }
2983*0a6a1f1dSLionel Sambuc 
2984*0a6a1f1dSLionel Sambuc CXTranslationUnit
clang_parseTranslationUnit(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,struct CXUnsavedFile * unsaved_files,unsigned num_unsaved_files,unsigned options)2985*0a6a1f1dSLionel Sambuc clang_parseTranslationUnit(CXIndex CIdx,
2986f4a2713aSLionel Sambuc                            const char *source_filename,
2987f4a2713aSLionel Sambuc                            const char *const *command_line_args,
2988f4a2713aSLionel Sambuc                            int num_command_line_args,
2989f4a2713aSLionel Sambuc                            struct CXUnsavedFile *unsaved_files,
2990f4a2713aSLionel Sambuc                            unsigned num_unsaved_files,
2991f4a2713aSLionel Sambuc                            unsigned options) {
2992*0a6a1f1dSLionel Sambuc   CXTranslationUnit TU;
2993*0a6a1f1dSLionel Sambuc   enum CXErrorCode Result = clang_parseTranslationUnit2(
2994*0a6a1f1dSLionel Sambuc       CIdx, source_filename, command_line_args, num_command_line_args,
2995*0a6a1f1dSLionel Sambuc       unsaved_files, num_unsaved_files, options, &TU);
2996*0a6a1f1dSLionel Sambuc   (void)Result;
2997*0a6a1f1dSLionel Sambuc   assert((TU && Result == CXError_Success) ||
2998*0a6a1f1dSLionel Sambuc          (!TU && Result != CXError_Success));
2999*0a6a1f1dSLionel Sambuc   return TU;
3000*0a6a1f1dSLionel Sambuc }
3001*0a6a1f1dSLionel Sambuc 
clang_parseTranslationUnit2(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,struct CXUnsavedFile * unsaved_files,unsigned num_unsaved_files,unsigned options,CXTranslationUnit * out_TU)3002*0a6a1f1dSLionel Sambuc enum CXErrorCode clang_parseTranslationUnit2(
3003*0a6a1f1dSLionel Sambuc     CXIndex CIdx,
3004*0a6a1f1dSLionel Sambuc     const char *source_filename,
3005*0a6a1f1dSLionel Sambuc     const char *const *command_line_args,
3006*0a6a1f1dSLionel Sambuc     int num_command_line_args,
3007*0a6a1f1dSLionel Sambuc     struct CXUnsavedFile *unsaved_files,
3008*0a6a1f1dSLionel Sambuc     unsigned num_unsaved_files,
3009*0a6a1f1dSLionel Sambuc     unsigned options,
3010*0a6a1f1dSLionel Sambuc     CXTranslationUnit *out_TU) {
3011f4a2713aSLionel Sambuc   LOG_FUNC_SECTION {
3012f4a2713aSLionel Sambuc     *Log << source_filename << ": ";
3013f4a2713aSLionel Sambuc     for (int i = 0; i != num_command_line_args; ++i)
3014f4a2713aSLionel Sambuc       *Log << command_line_args[i] << " ";
3015f4a2713aSLionel Sambuc   }
3016f4a2713aSLionel Sambuc 
3017*0a6a1f1dSLionel Sambuc   if (num_unsaved_files && !unsaved_files)
3018*0a6a1f1dSLionel Sambuc     return CXError_InvalidArguments;
3019*0a6a1f1dSLionel Sambuc 
3020*0a6a1f1dSLionel Sambuc   CXErrorCode result = CXError_Failure;
3021*0a6a1f1dSLionel Sambuc   ParseTranslationUnitInfo PTUI = {
3022*0a6a1f1dSLionel Sambuc       CIdx,
3023*0a6a1f1dSLionel Sambuc       source_filename,
3024*0a6a1f1dSLionel Sambuc       command_line_args,
3025*0a6a1f1dSLionel Sambuc       num_command_line_args,
3026*0a6a1f1dSLionel Sambuc       llvm::makeArrayRef(unsaved_files, num_unsaved_files),
3027*0a6a1f1dSLionel Sambuc       options,
3028*0a6a1f1dSLionel Sambuc       out_TU,
3029*0a6a1f1dSLionel Sambuc       result};
3030f4a2713aSLionel Sambuc   llvm::CrashRecoveryContext CRC;
3031f4a2713aSLionel Sambuc 
3032f4a2713aSLionel Sambuc   if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
3033f4a2713aSLionel Sambuc     fprintf(stderr, "libclang: crash detected during parsing: {\n");
3034f4a2713aSLionel Sambuc     fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
3035f4a2713aSLionel Sambuc     fprintf(stderr, "  'command_line_args' : [");
3036f4a2713aSLionel Sambuc     for (int i = 0; i != num_command_line_args; ++i) {
3037f4a2713aSLionel Sambuc       if (i)
3038f4a2713aSLionel Sambuc         fprintf(stderr, ", ");
3039f4a2713aSLionel Sambuc       fprintf(stderr, "'%s'", command_line_args[i]);
3040f4a2713aSLionel Sambuc     }
3041f4a2713aSLionel Sambuc     fprintf(stderr, "],\n");
3042f4a2713aSLionel Sambuc     fprintf(stderr, "  'unsaved_files' : [");
3043f4a2713aSLionel Sambuc     for (unsigned i = 0; i != num_unsaved_files; ++i) {
3044f4a2713aSLionel Sambuc       if (i)
3045f4a2713aSLionel Sambuc         fprintf(stderr, ", ");
3046f4a2713aSLionel Sambuc       fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3047f4a2713aSLionel Sambuc               unsaved_files[i].Length);
3048f4a2713aSLionel Sambuc     }
3049f4a2713aSLionel Sambuc     fprintf(stderr, "],\n");
3050f4a2713aSLionel Sambuc     fprintf(stderr, "  'options' : %d,\n", options);
3051f4a2713aSLionel Sambuc     fprintf(stderr, "}\n");
3052f4a2713aSLionel Sambuc 
3053*0a6a1f1dSLionel Sambuc     return CXError_Crashed;
3054f4a2713aSLionel Sambuc   } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3055*0a6a1f1dSLionel Sambuc     if (CXTranslationUnit *TU = PTUI.out_TU)
3056*0a6a1f1dSLionel Sambuc       PrintLibclangResourceUsage(*TU);
3057f4a2713aSLionel Sambuc   }
3058f4a2713aSLionel Sambuc 
3059*0a6a1f1dSLionel Sambuc   return result;
3060f4a2713aSLionel Sambuc }
3061f4a2713aSLionel Sambuc 
clang_defaultSaveOptions(CXTranslationUnit TU)3062f4a2713aSLionel Sambuc unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3063f4a2713aSLionel Sambuc   return CXSaveTranslationUnit_None;
3064f4a2713aSLionel Sambuc }
3065f4a2713aSLionel Sambuc 
3066f4a2713aSLionel Sambuc namespace {
3067f4a2713aSLionel Sambuc 
3068f4a2713aSLionel Sambuc struct SaveTranslationUnitInfo {
3069f4a2713aSLionel Sambuc   CXTranslationUnit TU;
3070f4a2713aSLionel Sambuc   const char *FileName;
3071f4a2713aSLionel Sambuc   unsigned options;
3072f4a2713aSLionel Sambuc   CXSaveError result;
3073f4a2713aSLionel Sambuc };
3074f4a2713aSLionel Sambuc 
3075f4a2713aSLionel Sambuc }
3076f4a2713aSLionel Sambuc 
clang_saveTranslationUnit_Impl(void * UserData)3077f4a2713aSLionel Sambuc static void clang_saveTranslationUnit_Impl(void *UserData) {
3078f4a2713aSLionel Sambuc   SaveTranslationUnitInfo *STUI =
3079f4a2713aSLionel Sambuc     static_cast<SaveTranslationUnitInfo*>(UserData);
3080f4a2713aSLionel Sambuc 
3081f4a2713aSLionel Sambuc   CIndexer *CXXIdx = STUI->TU->CIdx;
3082f4a2713aSLionel Sambuc   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3083f4a2713aSLionel Sambuc     setThreadBackgroundPriority();
3084f4a2713aSLionel Sambuc 
3085f4a2713aSLionel Sambuc   bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
3086f4a2713aSLionel Sambuc   STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
3087f4a2713aSLionel Sambuc }
3088f4a2713aSLionel Sambuc 
clang_saveTranslationUnit(CXTranslationUnit TU,const char * FileName,unsigned options)3089f4a2713aSLionel Sambuc int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3090f4a2713aSLionel Sambuc                               unsigned options) {
3091f4a2713aSLionel Sambuc   LOG_FUNC_SECTION {
3092f4a2713aSLionel Sambuc     *Log << TU << ' ' << FileName;
3093f4a2713aSLionel Sambuc   }
3094f4a2713aSLionel Sambuc 
3095*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
3096*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
3097f4a2713aSLionel Sambuc     return CXSaveError_InvalidTU;
3098*0a6a1f1dSLionel Sambuc   }
3099f4a2713aSLionel Sambuc 
3100f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3101f4a2713aSLionel Sambuc   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3102f4a2713aSLionel Sambuc   if (!CXXUnit->hasSema())
3103f4a2713aSLionel Sambuc     return CXSaveError_InvalidTU;
3104f4a2713aSLionel Sambuc 
3105f4a2713aSLionel Sambuc   SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
3106f4a2713aSLionel Sambuc 
3107f4a2713aSLionel Sambuc   if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3108f4a2713aSLionel Sambuc       getenv("LIBCLANG_NOTHREADS")) {
3109f4a2713aSLionel Sambuc     clang_saveTranslationUnit_Impl(&STUI);
3110f4a2713aSLionel Sambuc 
3111f4a2713aSLionel Sambuc     if (getenv("LIBCLANG_RESOURCE_USAGE"))
3112f4a2713aSLionel Sambuc       PrintLibclangResourceUsage(TU);
3113f4a2713aSLionel Sambuc 
3114f4a2713aSLionel Sambuc     return STUI.result;
3115f4a2713aSLionel Sambuc   }
3116f4a2713aSLionel Sambuc 
3117f4a2713aSLionel Sambuc   // We have an AST that has invalid nodes due to compiler errors.
3118f4a2713aSLionel Sambuc   // Use a crash recovery thread for protection.
3119f4a2713aSLionel Sambuc 
3120f4a2713aSLionel Sambuc   llvm::CrashRecoveryContext CRC;
3121f4a2713aSLionel Sambuc 
3122f4a2713aSLionel Sambuc   if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
3123f4a2713aSLionel Sambuc     fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3124f4a2713aSLionel Sambuc     fprintf(stderr, "  'filename' : '%s'\n", FileName);
3125f4a2713aSLionel Sambuc     fprintf(stderr, "  'options' : %d,\n", options);
3126f4a2713aSLionel Sambuc     fprintf(stderr, "}\n");
3127f4a2713aSLionel Sambuc 
3128f4a2713aSLionel Sambuc     return CXSaveError_Unknown;
3129f4a2713aSLionel Sambuc 
3130f4a2713aSLionel Sambuc   } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3131f4a2713aSLionel Sambuc     PrintLibclangResourceUsage(TU);
3132f4a2713aSLionel Sambuc   }
3133f4a2713aSLionel Sambuc 
3134f4a2713aSLionel Sambuc   return STUI.result;
3135f4a2713aSLionel Sambuc }
3136f4a2713aSLionel Sambuc 
clang_disposeTranslationUnit(CXTranslationUnit CTUnit)3137f4a2713aSLionel Sambuc void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3138f4a2713aSLionel Sambuc   if (CTUnit) {
3139f4a2713aSLionel Sambuc     // If the translation unit has been marked as unsafe to free, just discard
3140f4a2713aSLionel Sambuc     // it.
3141*0a6a1f1dSLionel Sambuc     ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3142*0a6a1f1dSLionel Sambuc     if (Unit && Unit->isUnsafeToFree())
3143f4a2713aSLionel Sambuc       return;
3144f4a2713aSLionel Sambuc 
3145f4a2713aSLionel Sambuc     delete cxtu::getASTUnit(CTUnit);
3146f4a2713aSLionel Sambuc     delete CTUnit->StringPool;
3147f4a2713aSLionel Sambuc     delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3148f4a2713aSLionel Sambuc     disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
3149f4a2713aSLionel Sambuc     delete CTUnit->CommentToXML;
3150f4a2713aSLionel Sambuc     delete CTUnit;
3151f4a2713aSLionel Sambuc   }
3152f4a2713aSLionel Sambuc }
3153f4a2713aSLionel Sambuc 
clang_defaultReparseOptions(CXTranslationUnit TU)3154f4a2713aSLionel Sambuc unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3155f4a2713aSLionel Sambuc   return CXReparse_None;
3156f4a2713aSLionel Sambuc }
3157f4a2713aSLionel Sambuc 
3158f4a2713aSLionel Sambuc struct ReparseTranslationUnitInfo {
3159f4a2713aSLionel Sambuc   CXTranslationUnit TU;
3160*0a6a1f1dSLionel Sambuc   ArrayRef<CXUnsavedFile> unsaved_files;
3161f4a2713aSLionel Sambuc   unsigned options;
3162*0a6a1f1dSLionel Sambuc   CXErrorCode &result;
3163f4a2713aSLionel Sambuc };
3164f4a2713aSLionel Sambuc 
clang_reparseTranslationUnit_Impl(void * UserData)3165f4a2713aSLionel Sambuc static void clang_reparseTranslationUnit_Impl(void *UserData) {
3166*0a6a1f1dSLionel Sambuc   const ReparseTranslationUnitInfo *RTUI =
3167f4a2713aSLionel Sambuc       static_cast<ReparseTranslationUnitInfo *>(UserData);
3168f4a2713aSLionel Sambuc   CXTranslationUnit TU = RTUI->TU;
3169*0a6a1f1dSLionel Sambuc   unsigned options = RTUI->options;
3170*0a6a1f1dSLionel Sambuc   (void) options;
3171*0a6a1f1dSLionel Sambuc 
3172*0a6a1f1dSLionel Sambuc   // Check arguments.
3173*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
3174*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
3175*0a6a1f1dSLionel Sambuc     RTUI->result = CXError_InvalidArguments;
3176f4a2713aSLionel Sambuc     return;
3177*0a6a1f1dSLionel Sambuc   }
3178f4a2713aSLionel Sambuc 
3179f4a2713aSLionel Sambuc   // Reset the associated diagnostics.
3180f4a2713aSLionel Sambuc   delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3181*0a6a1f1dSLionel Sambuc   TU->Diagnostics = nullptr;
3182f4a2713aSLionel Sambuc 
3183f4a2713aSLionel Sambuc   CIndexer *CXXIdx = TU->CIdx;
3184f4a2713aSLionel Sambuc   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3185f4a2713aSLionel Sambuc     setThreadBackgroundPriority();
3186f4a2713aSLionel Sambuc 
3187f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3188f4a2713aSLionel Sambuc   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3189f4a2713aSLionel Sambuc 
3190*0a6a1f1dSLionel Sambuc   std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3191*0a6a1f1dSLionel Sambuc       new std::vector<ASTUnit::RemappedFile>());
3192f4a2713aSLionel Sambuc 
3193f4a2713aSLionel Sambuc   // Recover resources if we crash before exiting this function.
3194f4a2713aSLionel Sambuc   llvm::CrashRecoveryContextCleanupRegistrar<
3195f4a2713aSLionel Sambuc     std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3196f4a2713aSLionel Sambuc 
3197*0a6a1f1dSLionel Sambuc   for (auto &UF : RTUI->unsaved_files) {
3198*0a6a1f1dSLionel Sambuc     std::unique_ptr<llvm::MemoryBuffer> MB =
3199*0a6a1f1dSLionel Sambuc         llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3200*0a6a1f1dSLionel Sambuc     RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
3201f4a2713aSLionel Sambuc   }
3202f4a2713aSLionel Sambuc 
3203*0a6a1f1dSLionel Sambuc   if (!CXXUnit->Reparse(*RemappedFiles.get()))
3204*0a6a1f1dSLionel Sambuc     RTUI->result = CXError_Success;
3205*0a6a1f1dSLionel Sambuc   else if (isASTReadError(CXXUnit))
3206*0a6a1f1dSLionel Sambuc     RTUI->result = CXError_ASTReadError;
3207f4a2713aSLionel Sambuc }
3208f4a2713aSLionel Sambuc 
clang_reparseTranslationUnit(CXTranslationUnit TU,unsigned num_unsaved_files,struct CXUnsavedFile * unsaved_files,unsigned options)3209f4a2713aSLionel Sambuc int clang_reparseTranslationUnit(CXTranslationUnit TU,
3210f4a2713aSLionel Sambuc                                  unsigned num_unsaved_files,
3211f4a2713aSLionel Sambuc                                  struct CXUnsavedFile *unsaved_files,
3212f4a2713aSLionel Sambuc                                  unsigned options) {
3213f4a2713aSLionel Sambuc   LOG_FUNC_SECTION {
3214f4a2713aSLionel Sambuc     *Log << TU;
3215f4a2713aSLionel Sambuc   }
3216f4a2713aSLionel Sambuc 
3217*0a6a1f1dSLionel Sambuc   if (num_unsaved_files && !unsaved_files)
3218*0a6a1f1dSLionel Sambuc     return CXError_InvalidArguments;
3219*0a6a1f1dSLionel Sambuc 
3220*0a6a1f1dSLionel Sambuc   CXErrorCode result = CXError_Failure;
3221*0a6a1f1dSLionel Sambuc   ReparseTranslationUnitInfo RTUI = {
3222*0a6a1f1dSLionel Sambuc       TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options,
3223*0a6a1f1dSLionel Sambuc       result};
3224f4a2713aSLionel Sambuc 
3225f4a2713aSLionel Sambuc   if (getenv("LIBCLANG_NOTHREADS")) {
3226f4a2713aSLionel Sambuc     clang_reparseTranslationUnit_Impl(&RTUI);
3227*0a6a1f1dSLionel Sambuc     return result;
3228f4a2713aSLionel Sambuc   }
3229f4a2713aSLionel Sambuc 
3230f4a2713aSLionel Sambuc   llvm::CrashRecoveryContext CRC;
3231f4a2713aSLionel Sambuc 
3232f4a2713aSLionel Sambuc   if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3233f4a2713aSLionel Sambuc     fprintf(stderr, "libclang: crash detected during reparsing\n");
3234f4a2713aSLionel Sambuc     cxtu::getASTUnit(TU)->setUnsafeToFree(true);
3235*0a6a1f1dSLionel Sambuc     return CXError_Crashed;
3236f4a2713aSLionel Sambuc   } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3237f4a2713aSLionel Sambuc     PrintLibclangResourceUsage(TU);
3238f4a2713aSLionel Sambuc 
3239*0a6a1f1dSLionel Sambuc   return result;
3240f4a2713aSLionel Sambuc }
3241f4a2713aSLionel Sambuc 
3242f4a2713aSLionel Sambuc 
clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit)3243f4a2713aSLionel Sambuc CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
3244*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(CTUnit)) {
3245*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(CTUnit);
3246f4a2713aSLionel Sambuc     return cxstring::createEmpty();
3247*0a6a1f1dSLionel Sambuc   }
3248f4a2713aSLionel Sambuc 
3249f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
3250f4a2713aSLionel Sambuc   return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
3251f4a2713aSLionel Sambuc }
3252f4a2713aSLionel Sambuc 
clang_getTranslationUnitCursor(CXTranslationUnit TU)3253f4a2713aSLionel Sambuc CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
3254*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
3255*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
3256f4a2713aSLionel Sambuc     return clang_getNullCursor();
3257*0a6a1f1dSLionel Sambuc   }
3258f4a2713aSLionel Sambuc 
3259f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3260f4a2713aSLionel Sambuc   return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3261f4a2713aSLionel Sambuc }
3262f4a2713aSLionel Sambuc 
3263f4a2713aSLionel Sambuc } // end: extern "C"
3264f4a2713aSLionel Sambuc 
3265f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3266f4a2713aSLionel Sambuc // CXFile Operations.
3267f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3268f4a2713aSLionel Sambuc 
3269f4a2713aSLionel Sambuc extern "C" {
clang_getFileName(CXFile SFile)3270f4a2713aSLionel Sambuc CXString clang_getFileName(CXFile SFile) {
3271f4a2713aSLionel Sambuc   if (!SFile)
3272f4a2713aSLionel Sambuc     return cxstring::createNull();
3273f4a2713aSLionel Sambuc 
3274f4a2713aSLionel Sambuc   FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3275f4a2713aSLionel Sambuc   return cxstring::createRef(FEnt->getName());
3276f4a2713aSLionel Sambuc }
3277f4a2713aSLionel Sambuc 
clang_getFileTime(CXFile SFile)3278f4a2713aSLionel Sambuc time_t clang_getFileTime(CXFile SFile) {
3279f4a2713aSLionel Sambuc   if (!SFile)
3280f4a2713aSLionel Sambuc     return 0;
3281f4a2713aSLionel Sambuc 
3282f4a2713aSLionel Sambuc   FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3283f4a2713aSLionel Sambuc   return FEnt->getModificationTime();
3284f4a2713aSLionel Sambuc }
3285f4a2713aSLionel Sambuc 
clang_getFile(CXTranslationUnit TU,const char * file_name)3286f4a2713aSLionel Sambuc CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3287*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
3288*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
3289*0a6a1f1dSLionel Sambuc     return nullptr;
3290*0a6a1f1dSLionel Sambuc   }
3291f4a2713aSLionel Sambuc 
3292f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3293f4a2713aSLionel Sambuc 
3294f4a2713aSLionel Sambuc   FileManager &FMgr = CXXUnit->getFileManager();
3295f4a2713aSLionel Sambuc   return const_cast<FileEntry *>(FMgr.getFile(file_name));
3296f4a2713aSLionel Sambuc }
3297f4a2713aSLionel Sambuc 
clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,CXFile file)3298*0a6a1f1dSLionel Sambuc unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3299*0a6a1f1dSLionel Sambuc                                             CXFile file) {
3300*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
3301*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
3302*0a6a1f1dSLionel Sambuc     return 0;
3303*0a6a1f1dSLionel Sambuc   }
3304*0a6a1f1dSLionel Sambuc 
3305*0a6a1f1dSLionel Sambuc   if (!file)
3306f4a2713aSLionel Sambuc     return 0;
3307f4a2713aSLionel Sambuc 
3308f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3309f4a2713aSLionel Sambuc   FileEntry *FEnt = static_cast<FileEntry *>(file);
3310f4a2713aSLionel Sambuc   return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3311f4a2713aSLionel Sambuc                                           .isFileMultipleIncludeGuarded(FEnt);
3312f4a2713aSLionel Sambuc }
3313f4a2713aSLionel Sambuc 
clang_getFileUniqueID(CXFile file,CXFileUniqueID * outID)3314f4a2713aSLionel Sambuc int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3315f4a2713aSLionel Sambuc   if (!file || !outID)
3316f4a2713aSLionel Sambuc     return 1;
3317f4a2713aSLionel Sambuc 
3318f4a2713aSLionel Sambuc   FileEntry *FEnt = static_cast<FileEntry *>(file);
3319f4a2713aSLionel Sambuc   const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3320f4a2713aSLionel Sambuc   outID->data[0] = ID.getDevice();
3321f4a2713aSLionel Sambuc   outID->data[1] = ID.getFile();
3322f4a2713aSLionel Sambuc   outID->data[2] = FEnt->getModificationTime();
3323f4a2713aSLionel Sambuc   return 0;
3324f4a2713aSLionel Sambuc }
3325f4a2713aSLionel Sambuc 
clang_File_isEqual(CXFile file1,CXFile file2)3326*0a6a1f1dSLionel Sambuc int clang_File_isEqual(CXFile file1, CXFile file2) {
3327*0a6a1f1dSLionel Sambuc   if (file1 == file2)
3328*0a6a1f1dSLionel Sambuc     return true;
3329*0a6a1f1dSLionel Sambuc 
3330*0a6a1f1dSLionel Sambuc   if (!file1 || !file2)
3331*0a6a1f1dSLionel Sambuc     return false;
3332*0a6a1f1dSLionel Sambuc 
3333*0a6a1f1dSLionel Sambuc   FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3334*0a6a1f1dSLionel Sambuc   FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3335*0a6a1f1dSLionel Sambuc   return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3336*0a6a1f1dSLionel Sambuc }
3337*0a6a1f1dSLionel Sambuc 
3338f4a2713aSLionel Sambuc } // end: extern "C"
3339f4a2713aSLionel Sambuc 
3340f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3341f4a2713aSLionel Sambuc // CXCursor Operations.
3342f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
3343f4a2713aSLionel Sambuc 
getDeclFromExpr(const Stmt * E)3344f4a2713aSLionel Sambuc static const Decl *getDeclFromExpr(const Stmt *E) {
3345f4a2713aSLionel Sambuc   if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
3346f4a2713aSLionel Sambuc     return getDeclFromExpr(CE->getSubExpr());
3347f4a2713aSLionel Sambuc 
3348f4a2713aSLionel Sambuc   if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
3349f4a2713aSLionel Sambuc     return RefExpr->getDecl();
3350f4a2713aSLionel Sambuc   if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
3351f4a2713aSLionel Sambuc     return ME->getMemberDecl();
3352f4a2713aSLionel Sambuc   if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
3353f4a2713aSLionel Sambuc     return RE->getDecl();
3354f4a2713aSLionel Sambuc   if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
3355f4a2713aSLionel Sambuc     if (PRE->isExplicitProperty())
3356f4a2713aSLionel Sambuc       return PRE->getExplicitProperty();
3357f4a2713aSLionel Sambuc     // It could be messaging both getter and setter as in:
3358f4a2713aSLionel Sambuc     // ++myobj.myprop;
3359f4a2713aSLionel Sambuc     // in which case prefer to associate the setter since it is less obvious
3360f4a2713aSLionel Sambuc     // from inspecting the source that the setter is going to get called.
3361f4a2713aSLionel Sambuc     if (PRE->isMessagingSetter())
3362f4a2713aSLionel Sambuc       return PRE->getImplicitPropertySetter();
3363f4a2713aSLionel Sambuc     return PRE->getImplicitPropertyGetter();
3364f4a2713aSLionel Sambuc   }
3365f4a2713aSLionel Sambuc   if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
3366f4a2713aSLionel Sambuc     return getDeclFromExpr(POE->getSyntacticForm());
3367f4a2713aSLionel Sambuc   if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
3368f4a2713aSLionel Sambuc     if (Expr *Src = OVE->getSourceExpr())
3369f4a2713aSLionel Sambuc       return getDeclFromExpr(Src);
3370f4a2713aSLionel Sambuc 
3371f4a2713aSLionel Sambuc   if (const CallExpr *CE = dyn_cast<CallExpr>(E))
3372f4a2713aSLionel Sambuc     return getDeclFromExpr(CE->getCallee());
3373f4a2713aSLionel Sambuc   if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
3374f4a2713aSLionel Sambuc     if (!CE->isElidable())
3375f4a2713aSLionel Sambuc     return CE->getConstructor();
3376f4a2713aSLionel Sambuc   if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
3377f4a2713aSLionel Sambuc     return OME->getMethodDecl();
3378f4a2713aSLionel Sambuc 
3379f4a2713aSLionel Sambuc   if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
3380f4a2713aSLionel Sambuc     return PE->getProtocol();
3381f4a2713aSLionel Sambuc   if (const SubstNonTypeTemplateParmPackExpr *NTTP
3382f4a2713aSLionel Sambuc                               = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3383f4a2713aSLionel Sambuc     return NTTP->getParameterPack();
3384f4a2713aSLionel Sambuc   if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
3385f4a2713aSLionel Sambuc     if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3386f4a2713aSLionel Sambuc         isa<ParmVarDecl>(SizeOfPack->getPack()))
3387f4a2713aSLionel Sambuc       return SizeOfPack->getPack();
3388f4a2713aSLionel Sambuc 
3389*0a6a1f1dSLionel Sambuc   return nullptr;
3390f4a2713aSLionel Sambuc }
3391f4a2713aSLionel Sambuc 
getLocationFromExpr(const Expr * E)3392f4a2713aSLionel Sambuc static SourceLocation getLocationFromExpr(const Expr *E) {
3393f4a2713aSLionel Sambuc   if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
3394f4a2713aSLionel Sambuc     return getLocationFromExpr(CE->getSubExpr());
3395f4a2713aSLionel Sambuc 
3396f4a2713aSLionel Sambuc   if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
3397f4a2713aSLionel Sambuc     return /*FIXME:*/Msg->getLeftLoc();
3398f4a2713aSLionel Sambuc   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
3399f4a2713aSLionel Sambuc     return DRE->getLocation();
3400f4a2713aSLionel Sambuc   if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
3401f4a2713aSLionel Sambuc     return Member->getMemberLoc();
3402f4a2713aSLionel Sambuc   if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
3403f4a2713aSLionel Sambuc     return Ivar->getLocation();
3404f4a2713aSLionel Sambuc   if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
3405f4a2713aSLionel Sambuc     return SizeOfPack->getPackLoc();
3406f4a2713aSLionel Sambuc   if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
3407f4a2713aSLionel Sambuc     return PropRef->getLocation();
3408f4a2713aSLionel Sambuc 
3409f4a2713aSLionel Sambuc   return E->getLocStart();
3410f4a2713aSLionel Sambuc }
3411f4a2713aSLionel Sambuc 
3412f4a2713aSLionel Sambuc extern "C" {
3413f4a2713aSLionel Sambuc 
clang_visitChildren(CXCursor parent,CXCursorVisitor visitor,CXClientData client_data)3414f4a2713aSLionel Sambuc unsigned clang_visitChildren(CXCursor parent,
3415f4a2713aSLionel Sambuc                              CXCursorVisitor visitor,
3416f4a2713aSLionel Sambuc                              CXClientData client_data) {
3417f4a2713aSLionel Sambuc   CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3418f4a2713aSLionel Sambuc                           /*VisitPreprocessorLast=*/false);
3419f4a2713aSLionel Sambuc   return CursorVis.VisitChildren(parent);
3420f4a2713aSLionel Sambuc }
3421f4a2713aSLionel Sambuc 
3422f4a2713aSLionel Sambuc #ifndef __has_feature
3423f4a2713aSLionel Sambuc #define __has_feature(x) 0
3424f4a2713aSLionel Sambuc #endif
3425f4a2713aSLionel Sambuc #if __has_feature(blocks)
3426f4a2713aSLionel Sambuc typedef enum CXChildVisitResult
3427f4a2713aSLionel Sambuc      (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3428f4a2713aSLionel Sambuc 
visitWithBlock(CXCursor cursor,CXCursor parent,CXClientData client_data)3429f4a2713aSLionel Sambuc static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3430f4a2713aSLionel Sambuc     CXClientData client_data) {
3431f4a2713aSLionel Sambuc   CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3432f4a2713aSLionel Sambuc   return block(cursor, parent);
3433f4a2713aSLionel Sambuc }
3434f4a2713aSLionel Sambuc #else
3435f4a2713aSLionel Sambuc // If we are compiled with a compiler that doesn't have native blocks support,
3436f4a2713aSLionel Sambuc // define and call the block manually, so the
3437f4a2713aSLionel Sambuc typedef struct _CXChildVisitResult
3438f4a2713aSLionel Sambuc {
3439f4a2713aSLionel Sambuc 	void *isa;
3440f4a2713aSLionel Sambuc 	int flags;
3441f4a2713aSLionel Sambuc 	int reserved;
3442f4a2713aSLionel Sambuc 	enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3443f4a2713aSLionel Sambuc                                          CXCursor);
3444f4a2713aSLionel Sambuc } *CXCursorVisitorBlock;
3445f4a2713aSLionel Sambuc 
visitWithBlock(CXCursor cursor,CXCursor parent,CXClientData client_data)3446f4a2713aSLionel Sambuc static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3447f4a2713aSLionel Sambuc     CXClientData client_data) {
3448f4a2713aSLionel Sambuc   CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3449f4a2713aSLionel Sambuc   return block->invoke(block, cursor, parent);
3450f4a2713aSLionel Sambuc }
3451f4a2713aSLionel Sambuc #endif
3452f4a2713aSLionel Sambuc 
3453f4a2713aSLionel Sambuc 
clang_visitChildrenWithBlock(CXCursor parent,CXCursorVisitorBlock block)3454f4a2713aSLionel Sambuc unsigned clang_visitChildrenWithBlock(CXCursor parent,
3455f4a2713aSLionel Sambuc                                       CXCursorVisitorBlock block) {
3456f4a2713aSLionel Sambuc   return clang_visitChildren(parent, visitWithBlock, block);
3457f4a2713aSLionel Sambuc }
3458f4a2713aSLionel Sambuc 
getDeclSpelling(const Decl * D)3459f4a2713aSLionel Sambuc static CXString getDeclSpelling(const Decl *D) {
3460f4a2713aSLionel Sambuc   if (!D)
3461f4a2713aSLionel Sambuc     return cxstring::createEmpty();
3462f4a2713aSLionel Sambuc 
3463f4a2713aSLionel Sambuc   const NamedDecl *ND = dyn_cast<NamedDecl>(D);
3464f4a2713aSLionel Sambuc   if (!ND) {
3465f4a2713aSLionel Sambuc     if (const ObjCPropertyImplDecl *PropImpl =
3466f4a2713aSLionel Sambuc             dyn_cast<ObjCPropertyImplDecl>(D))
3467f4a2713aSLionel Sambuc       if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
3468f4a2713aSLionel Sambuc         return cxstring::createDup(Property->getIdentifier()->getName());
3469f4a2713aSLionel Sambuc 
3470f4a2713aSLionel Sambuc     if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
3471f4a2713aSLionel Sambuc       if (Module *Mod = ImportD->getImportedModule())
3472f4a2713aSLionel Sambuc         return cxstring::createDup(Mod->getFullModuleName());
3473f4a2713aSLionel Sambuc 
3474f4a2713aSLionel Sambuc     return cxstring::createEmpty();
3475f4a2713aSLionel Sambuc   }
3476f4a2713aSLionel Sambuc 
3477f4a2713aSLionel Sambuc   if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
3478f4a2713aSLionel Sambuc     return cxstring::createDup(OMD->getSelector().getAsString());
3479f4a2713aSLionel Sambuc 
3480f4a2713aSLionel Sambuc   if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
3481f4a2713aSLionel Sambuc     // No, this isn't the same as the code below. getIdentifier() is non-virtual
3482f4a2713aSLionel Sambuc     // and returns different names. NamedDecl returns the class name and
3483f4a2713aSLionel Sambuc     // ObjCCategoryImplDecl returns the category name.
3484f4a2713aSLionel Sambuc     return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
3485f4a2713aSLionel Sambuc 
3486f4a2713aSLionel Sambuc   if (isa<UsingDirectiveDecl>(D))
3487f4a2713aSLionel Sambuc     return cxstring::createEmpty();
3488f4a2713aSLionel Sambuc 
3489f4a2713aSLionel Sambuc   SmallString<1024> S;
3490f4a2713aSLionel Sambuc   llvm::raw_svector_ostream os(S);
3491f4a2713aSLionel Sambuc   ND->printName(os);
3492f4a2713aSLionel Sambuc 
3493f4a2713aSLionel Sambuc   return cxstring::createDup(os.str());
3494f4a2713aSLionel Sambuc }
3495f4a2713aSLionel Sambuc 
clang_getCursorSpelling(CXCursor C)3496f4a2713aSLionel Sambuc CXString clang_getCursorSpelling(CXCursor C) {
3497f4a2713aSLionel Sambuc   if (clang_isTranslationUnit(C.kind))
3498f4a2713aSLionel Sambuc     return clang_getTranslationUnitSpelling(getCursorTU(C));
3499f4a2713aSLionel Sambuc 
3500f4a2713aSLionel Sambuc   if (clang_isReference(C.kind)) {
3501f4a2713aSLionel Sambuc     switch (C.kind) {
3502f4a2713aSLionel Sambuc     case CXCursor_ObjCSuperClassRef: {
3503f4a2713aSLionel Sambuc       const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
3504f4a2713aSLionel Sambuc       return cxstring::createRef(Super->getIdentifier()->getNameStart());
3505f4a2713aSLionel Sambuc     }
3506f4a2713aSLionel Sambuc     case CXCursor_ObjCClassRef: {
3507f4a2713aSLionel Sambuc       const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
3508f4a2713aSLionel Sambuc       return cxstring::createRef(Class->getIdentifier()->getNameStart());
3509f4a2713aSLionel Sambuc     }
3510f4a2713aSLionel Sambuc     case CXCursor_ObjCProtocolRef: {
3511f4a2713aSLionel Sambuc       const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
3512f4a2713aSLionel Sambuc       assert(OID && "getCursorSpelling(): Missing protocol decl");
3513f4a2713aSLionel Sambuc       return cxstring::createRef(OID->getIdentifier()->getNameStart());
3514f4a2713aSLionel Sambuc     }
3515f4a2713aSLionel Sambuc     case CXCursor_CXXBaseSpecifier: {
3516f4a2713aSLionel Sambuc       const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
3517f4a2713aSLionel Sambuc       return cxstring::createDup(B->getType().getAsString());
3518f4a2713aSLionel Sambuc     }
3519f4a2713aSLionel Sambuc     case CXCursor_TypeRef: {
3520f4a2713aSLionel Sambuc       const TypeDecl *Type = getCursorTypeRef(C).first;
3521f4a2713aSLionel Sambuc       assert(Type && "Missing type decl");
3522f4a2713aSLionel Sambuc 
3523f4a2713aSLionel Sambuc       return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
3524f4a2713aSLionel Sambuc                               getAsString());
3525f4a2713aSLionel Sambuc     }
3526f4a2713aSLionel Sambuc     case CXCursor_TemplateRef: {
3527f4a2713aSLionel Sambuc       const TemplateDecl *Template = getCursorTemplateRef(C).first;
3528f4a2713aSLionel Sambuc       assert(Template && "Missing template decl");
3529f4a2713aSLionel Sambuc 
3530f4a2713aSLionel Sambuc       return cxstring::createDup(Template->getNameAsString());
3531f4a2713aSLionel Sambuc     }
3532f4a2713aSLionel Sambuc 
3533f4a2713aSLionel Sambuc     case CXCursor_NamespaceRef: {
3534f4a2713aSLionel Sambuc       const NamedDecl *NS = getCursorNamespaceRef(C).first;
3535f4a2713aSLionel Sambuc       assert(NS && "Missing namespace decl");
3536f4a2713aSLionel Sambuc 
3537f4a2713aSLionel Sambuc       return cxstring::createDup(NS->getNameAsString());
3538f4a2713aSLionel Sambuc     }
3539f4a2713aSLionel Sambuc 
3540f4a2713aSLionel Sambuc     case CXCursor_MemberRef: {
3541f4a2713aSLionel Sambuc       const FieldDecl *Field = getCursorMemberRef(C).first;
3542f4a2713aSLionel Sambuc       assert(Field && "Missing member decl");
3543f4a2713aSLionel Sambuc 
3544f4a2713aSLionel Sambuc       return cxstring::createDup(Field->getNameAsString());
3545f4a2713aSLionel Sambuc     }
3546f4a2713aSLionel Sambuc 
3547f4a2713aSLionel Sambuc     case CXCursor_LabelRef: {
3548f4a2713aSLionel Sambuc       const LabelStmt *Label = getCursorLabelRef(C).first;
3549f4a2713aSLionel Sambuc       assert(Label && "Missing label");
3550f4a2713aSLionel Sambuc 
3551f4a2713aSLionel Sambuc       return cxstring::createRef(Label->getName());
3552f4a2713aSLionel Sambuc     }
3553f4a2713aSLionel Sambuc 
3554f4a2713aSLionel Sambuc     case CXCursor_OverloadedDeclRef: {
3555f4a2713aSLionel Sambuc       OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
3556f4a2713aSLionel Sambuc       if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3557f4a2713aSLionel Sambuc         if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
3558f4a2713aSLionel Sambuc           return cxstring::createDup(ND->getNameAsString());
3559f4a2713aSLionel Sambuc         return cxstring::createEmpty();
3560f4a2713aSLionel Sambuc       }
3561f4a2713aSLionel Sambuc       if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
3562f4a2713aSLionel Sambuc         return cxstring::createDup(E->getName().getAsString());
3563f4a2713aSLionel Sambuc       OverloadedTemplateStorage *Ovl
3564f4a2713aSLionel Sambuc         = Storage.get<OverloadedTemplateStorage*>();
3565f4a2713aSLionel Sambuc       if (Ovl->size() == 0)
3566f4a2713aSLionel Sambuc         return cxstring::createEmpty();
3567f4a2713aSLionel Sambuc       return cxstring::createDup((*Ovl->begin())->getNameAsString());
3568f4a2713aSLionel Sambuc     }
3569f4a2713aSLionel Sambuc 
3570f4a2713aSLionel Sambuc     case CXCursor_VariableRef: {
3571f4a2713aSLionel Sambuc       const VarDecl *Var = getCursorVariableRef(C).first;
3572f4a2713aSLionel Sambuc       assert(Var && "Missing variable decl");
3573f4a2713aSLionel Sambuc 
3574f4a2713aSLionel Sambuc       return cxstring::createDup(Var->getNameAsString());
3575f4a2713aSLionel Sambuc     }
3576f4a2713aSLionel Sambuc 
3577f4a2713aSLionel Sambuc     default:
3578f4a2713aSLionel Sambuc       return cxstring::createRef("<not implemented>");
3579f4a2713aSLionel Sambuc     }
3580f4a2713aSLionel Sambuc   }
3581f4a2713aSLionel Sambuc 
3582f4a2713aSLionel Sambuc   if (clang_isExpression(C.kind)) {
3583*0a6a1f1dSLionel Sambuc     const Expr *E = getCursorExpr(C);
3584*0a6a1f1dSLionel Sambuc 
3585*0a6a1f1dSLionel Sambuc     if (C.kind == CXCursor_ObjCStringLiteral ||
3586*0a6a1f1dSLionel Sambuc         C.kind == CXCursor_StringLiteral) {
3587*0a6a1f1dSLionel Sambuc       const StringLiteral *SLit;
3588*0a6a1f1dSLionel Sambuc       if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3589*0a6a1f1dSLionel Sambuc         SLit = OSL->getString();
3590*0a6a1f1dSLionel Sambuc       } else {
3591*0a6a1f1dSLionel Sambuc         SLit = cast<StringLiteral>(E);
3592*0a6a1f1dSLionel Sambuc       }
3593*0a6a1f1dSLionel Sambuc       SmallString<256> Buf;
3594*0a6a1f1dSLionel Sambuc       llvm::raw_svector_ostream OS(Buf);
3595*0a6a1f1dSLionel Sambuc       SLit->outputString(OS);
3596*0a6a1f1dSLionel Sambuc       return cxstring::createDup(OS.str());
3597*0a6a1f1dSLionel Sambuc     }
3598*0a6a1f1dSLionel Sambuc 
3599f4a2713aSLionel Sambuc     const Decl *D = getDeclFromExpr(getCursorExpr(C));
3600f4a2713aSLionel Sambuc     if (D)
3601f4a2713aSLionel Sambuc       return getDeclSpelling(D);
3602f4a2713aSLionel Sambuc     return cxstring::createEmpty();
3603f4a2713aSLionel Sambuc   }
3604f4a2713aSLionel Sambuc 
3605f4a2713aSLionel Sambuc   if (clang_isStatement(C.kind)) {
3606f4a2713aSLionel Sambuc     const Stmt *S = getCursorStmt(C);
3607f4a2713aSLionel Sambuc     if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
3608f4a2713aSLionel Sambuc       return cxstring::createRef(Label->getName());
3609f4a2713aSLionel Sambuc 
3610f4a2713aSLionel Sambuc     return cxstring::createEmpty();
3611f4a2713aSLionel Sambuc   }
3612f4a2713aSLionel Sambuc 
3613f4a2713aSLionel Sambuc   if (C.kind == CXCursor_MacroExpansion)
3614f4a2713aSLionel Sambuc     return cxstring::createRef(getCursorMacroExpansion(C).getName()
3615f4a2713aSLionel Sambuc                                                            ->getNameStart());
3616f4a2713aSLionel Sambuc 
3617f4a2713aSLionel Sambuc   if (C.kind == CXCursor_MacroDefinition)
3618f4a2713aSLionel Sambuc     return cxstring::createRef(getCursorMacroDefinition(C)->getName()
3619f4a2713aSLionel Sambuc                                                            ->getNameStart());
3620f4a2713aSLionel Sambuc 
3621f4a2713aSLionel Sambuc   if (C.kind == CXCursor_InclusionDirective)
3622f4a2713aSLionel Sambuc     return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
3623f4a2713aSLionel Sambuc 
3624f4a2713aSLionel Sambuc   if (clang_isDeclaration(C.kind))
3625f4a2713aSLionel Sambuc     return getDeclSpelling(getCursorDecl(C));
3626f4a2713aSLionel Sambuc 
3627f4a2713aSLionel Sambuc   if (C.kind == CXCursor_AnnotateAttr) {
3628f4a2713aSLionel Sambuc     const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
3629f4a2713aSLionel Sambuc     return cxstring::createDup(AA->getAnnotation());
3630f4a2713aSLionel Sambuc   }
3631f4a2713aSLionel Sambuc 
3632f4a2713aSLionel Sambuc   if (C.kind == CXCursor_AsmLabelAttr) {
3633f4a2713aSLionel Sambuc     const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
3634f4a2713aSLionel Sambuc     return cxstring::createDup(AA->getLabel());
3635f4a2713aSLionel Sambuc   }
3636f4a2713aSLionel Sambuc 
3637f4a2713aSLionel Sambuc   if (C.kind == CXCursor_PackedAttr) {
3638f4a2713aSLionel Sambuc     return cxstring::createRef("packed");
3639f4a2713aSLionel Sambuc   }
3640f4a2713aSLionel Sambuc 
3641f4a2713aSLionel Sambuc   return cxstring::createEmpty();
3642f4a2713aSLionel Sambuc }
3643f4a2713aSLionel Sambuc 
clang_Cursor_getSpellingNameRange(CXCursor C,unsigned pieceIndex,unsigned options)3644f4a2713aSLionel Sambuc CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3645f4a2713aSLionel Sambuc                                                 unsigned pieceIndex,
3646f4a2713aSLionel Sambuc                                                 unsigned options) {
3647f4a2713aSLionel Sambuc   if (clang_Cursor_isNull(C))
3648f4a2713aSLionel Sambuc     return clang_getNullRange();
3649f4a2713aSLionel Sambuc 
3650f4a2713aSLionel Sambuc   ASTContext &Ctx = getCursorContext(C);
3651f4a2713aSLionel Sambuc 
3652f4a2713aSLionel Sambuc   if (clang_isStatement(C.kind)) {
3653f4a2713aSLionel Sambuc     const Stmt *S = getCursorStmt(C);
3654f4a2713aSLionel Sambuc     if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
3655f4a2713aSLionel Sambuc       if (pieceIndex > 0)
3656f4a2713aSLionel Sambuc         return clang_getNullRange();
3657f4a2713aSLionel Sambuc       return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3658f4a2713aSLionel Sambuc     }
3659f4a2713aSLionel Sambuc 
3660f4a2713aSLionel Sambuc     return clang_getNullRange();
3661f4a2713aSLionel Sambuc   }
3662f4a2713aSLionel Sambuc 
3663f4a2713aSLionel Sambuc   if (C.kind == CXCursor_ObjCMessageExpr) {
3664f4a2713aSLionel Sambuc     if (const ObjCMessageExpr *
3665f4a2713aSLionel Sambuc           ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3666f4a2713aSLionel Sambuc       if (pieceIndex >= ME->getNumSelectorLocs())
3667f4a2713aSLionel Sambuc         return clang_getNullRange();
3668f4a2713aSLionel Sambuc       return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3669f4a2713aSLionel Sambuc     }
3670f4a2713aSLionel Sambuc   }
3671f4a2713aSLionel Sambuc 
3672f4a2713aSLionel Sambuc   if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3673f4a2713aSLionel Sambuc       C.kind == CXCursor_ObjCClassMethodDecl) {
3674f4a2713aSLionel Sambuc     if (const ObjCMethodDecl *
3675f4a2713aSLionel Sambuc           MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3676f4a2713aSLionel Sambuc       if (pieceIndex >= MD->getNumSelectorLocs())
3677f4a2713aSLionel Sambuc         return clang_getNullRange();
3678f4a2713aSLionel Sambuc       return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3679f4a2713aSLionel Sambuc     }
3680f4a2713aSLionel Sambuc   }
3681f4a2713aSLionel Sambuc 
3682f4a2713aSLionel Sambuc   if (C.kind == CXCursor_ObjCCategoryDecl ||
3683f4a2713aSLionel Sambuc       C.kind == CXCursor_ObjCCategoryImplDecl) {
3684f4a2713aSLionel Sambuc     if (pieceIndex > 0)
3685f4a2713aSLionel Sambuc       return clang_getNullRange();
3686f4a2713aSLionel Sambuc     if (const ObjCCategoryDecl *
3687f4a2713aSLionel Sambuc           CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3688f4a2713aSLionel Sambuc       return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
3689f4a2713aSLionel Sambuc     if (const ObjCCategoryImplDecl *
3690f4a2713aSLionel Sambuc           CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3691f4a2713aSLionel Sambuc       return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3692f4a2713aSLionel Sambuc   }
3693f4a2713aSLionel Sambuc 
3694f4a2713aSLionel Sambuc   if (C.kind == CXCursor_ModuleImportDecl) {
3695f4a2713aSLionel Sambuc     if (pieceIndex > 0)
3696f4a2713aSLionel Sambuc       return clang_getNullRange();
3697f4a2713aSLionel Sambuc     if (const ImportDecl *ImportD =
3698f4a2713aSLionel Sambuc             dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
3699f4a2713aSLionel Sambuc       ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3700f4a2713aSLionel Sambuc       if (!Locs.empty())
3701f4a2713aSLionel Sambuc         return cxloc::translateSourceRange(Ctx,
3702f4a2713aSLionel Sambuc                                          SourceRange(Locs.front(), Locs.back()));
3703f4a2713aSLionel Sambuc     }
3704f4a2713aSLionel Sambuc     return clang_getNullRange();
3705f4a2713aSLionel Sambuc   }
3706f4a2713aSLionel Sambuc 
3707*0a6a1f1dSLionel Sambuc   if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3708*0a6a1f1dSLionel Sambuc       C.kind == CXCursor_ConversionFunction) {
3709*0a6a1f1dSLionel Sambuc     if (pieceIndex > 0)
3710*0a6a1f1dSLionel Sambuc       return clang_getNullRange();
3711*0a6a1f1dSLionel Sambuc     if (const FunctionDecl *FD =
3712*0a6a1f1dSLionel Sambuc             dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3713*0a6a1f1dSLionel Sambuc       DeclarationNameInfo FunctionName = FD->getNameInfo();
3714*0a6a1f1dSLionel Sambuc       return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3715*0a6a1f1dSLionel Sambuc     }
3716*0a6a1f1dSLionel Sambuc     return clang_getNullRange();
3717*0a6a1f1dSLionel Sambuc   }
3718*0a6a1f1dSLionel Sambuc 
3719f4a2713aSLionel Sambuc   // FIXME: A CXCursor_InclusionDirective should give the location of the
3720f4a2713aSLionel Sambuc   // filename, but we don't keep track of this.
3721f4a2713aSLionel Sambuc 
3722f4a2713aSLionel Sambuc   // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3723f4a2713aSLionel Sambuc   // but we don't keep track of this.
3724f4a2713aSLionel Sambuc 
3725f4a2713aSLionel Sambuc   // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3726f4a2713aSLionel Sambuc   // but we don't keep track of this.
3727f4a2713aSLionel Sambuc 
3728f4a2713aSLionel Sambuc   // Default handling, give the location of the cursor.
3729f4a2713aSLionel Sambuc 
3730f4a2713aSLionel Sambuc   if (pieceIndex > 0)
3731f4a2713aSLionel Sambuc     return clang_getNullRange();
3732f4a2713aSLionel Sambuc 
3733f4a2713aSLionel Sambuc   CXSourceLocation CXLoc = clang_getCursorLocation(C);
3734f4a2713aSLionel Sambuc   SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3735f4a2713aSLionel Sambuc   return cxloc::translateSourceRange(Ctx, Loc);
3736f4a2713aSLionel Sambuc }
3737f4a2713aSLionel Sambuc 
clang_Cursor_getMangling(CXCursor C)3738*0a6a1f1dSLionel Sambuc CXString clang_Cursor_getMangling(CXCursor C) {
3739*0a6a1f1dSLionel Sambuc   if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3740*0a6a1f1dSLionel Sambuc     return cxstring::createEmpty();
3741*0a6a1f1dSLionel Sambuc 
3742*0a6a1f1dSLionel Sambuc   // Mangling only works for functions and variables.
3743*0a6a1f1dSLionel Sambuc   const Decl *D = getCursorDecl(C);
3744*0a6a1f1dSLionel Sambuc   if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3745*0a6a1f1dSLionel Sambuc     return cxstring::createEmpty();
3746*0a6a1f1dSLionel Sambuc 
3747*0a6a1f1dSLionel Sambuc   // First apply frontend mangling.
3748*0a6a1f1dSLionel Sambuc   const NamedDecl *ND = cast<NamedDecl>(D);
3749*0a6a1f1dSLionel Sambuc   ASTContext &Ctx = ND->getASTContext();
3750*0a6a1f1dSLionel Sambuc   std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
3751*0a6a1f1dSLionel Sambuc 
3752*0a6a1f1dSLionel Sambuc   std::string FrontendBuf;
3753*0a6a1f1dSLionel Sambuc   llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3754*0a6a1f1dSLionel Sambuc   MC->mangleName(ND, FrontendBufOS);
3755*0a6a1f1dSLionel Sambuc 
3756*0a6a1f1dSLionel Sambuc   // Now apply backend mangling.
3757*0a6a1f1dSLionel Sambuc   std::unique_ptr<llvm::DataLayout> DL(
3758*0a6a1f1dSLionel Sambuc       new llvm::DataLayout(Ctx.getTargetInfo().getTargetDescription()));
3759*0a6a1f1dSLionel Sambuc   llvm::Mangler BackendMangler(DL.get());
3760*0a6a1f1dSLionel Sambuc 
3761*0a6a1f1dSLionel Sambuc   std::string FinalBuf;
3762*0a6a1f1dSLionel Sambuc   llvm::raw_string_ostream FinalBufOS(FinalBuf);
3763*0a6a1f1dSLionel Sambuc   BackendMangler.getNameWithPrefix(FinalBufOS,
3764*0a6a1f1dSLionel Sambuc                                    llvm::Twine(FrontendBufOS.str()));
3765*0a6a1f1dSLionel Sambuc 
3766*0a6a1f1dSLionel Sambuc   return cxstring::createDup(FinalBufOS.str());
3767*0a6a1f1dSLionel Sambuc }
3768*0a6a1f1dSLionel Sambuc 
clang_getCursorDisplayName(CXCursor C)3769f4a2713aSLionel Sambuc CXString clang_getCursorDisplayName(CXCursor C) {
3770f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
3771f4a2713aSLionel Sambuc     return clang_getCursorSpelling(C);
3772f4a2713aSLionel Sambuc 
3773f4a2713aSLionel Sambuc   const Decl *D = getCursorDecl(C);
3774f4a2713aSLionel Sambuc   if (!D)
3775f4a2713aSLionel Sambuc     return cxstring::createEmpty();
3776f4a2713aSLionel Sambuc 
3777f4a2713aSLionel Sambuc   PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
3778f4a2713aSLionel Sambuc   if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
3779f4a2713aSLionel Sambuc     D = FunTmpl->getTemplatedDecl();
3780f4a2713aSLionel Sambuc 
3781f4a2713aSLionel Sambuc   if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
3782f4a2713aSLionel Sambuc     SmallString<64> Str;
3783f4a2713aSLionel Sambuc     llvm::raw_svector_ostream OS(Str);
3784f4a2713aSLionel Sambuc     OS << *Function;
3785f4a2713aSLionel Sambuc     if (Function->getPrimaryTemplate())
3786f4a2713aSLionel Sambuc       OS << "<>";
3787f4a2713aSLionel Sambuc     OS << "(";
3788f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3789f4a2713aSLionel Sambuc       if (I)
3790f4a2713aSLionel Sambuc         OS << ", ";
3791f4a2713aSLionel Sambuc       OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3792f4a2713aSLionel Sambuc     }
3793f4a2713aSLionel Sambuc 
3794f4a2713aSLionel Sambuc     if (Function->isVariadic()) {
3795f4a2713aSLionel Sambuc       if (Function->getNumParams())
3796f4a2713aSLionel Sambuc         OS << ", ";
3797f4a2713aSLionel Sambuc       OS << "...";
3798f4a2713aSLionel Sambuc     }
3799f4a2713aSLionel Sambuc     OS << ")";
3800f4a2713aSLionel Sambuc     return cxstring::createDup(OS.str());
3801f4a2713aSLionel Sambuc   }
3802f4a2713aSLionel Sambuc 
3803f4a2713aSLionel Sambuc   if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
3804f4a2713aSLionel Sambuc     SmallString<64> Str;
3805f4a2713aSLionel Sambuc     llvm::raw_svector_ostream OS(Str);
3806f4a2713aSLionel Sambuc     OS << *ClassTemplate;
3807f4a2713aSLionel Sambuc     OS << "<";
3808f4a2713aSLionel Sambuc     TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3809f4a2713aSLionel Sambuc     for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3810f4a2713aSLionel Sambuc       if (I)
3811f4a2713aSLionel Sambuc         OS << ", ";
3812f4a2713aSLionel Sambuc 
3813f4a2713aSLionel Sambuc       NamedDecl *Param = Params->getParam(I);
3814f4a2713aSLionel Sambuc       if (Param->getIdentifier()) {
3815f4a2713aSLionel Sambuc         OS << Param->getIdentifier()->getName();
3816f4a2713aSLionel Sambuc         continue;
3817f4a2713aSLionel Sambuc       }
3818f4a2713aSLionel Sambuc 
3819f4a2713aSLionel Sambuc       // There is no parameter name, which makes this tricky. Try to come up
3820f4a2713aSLionel Sambuc       // with something useful that isn't too long.
3821f4a2713aSLionel Sambuc       if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3822f4a2713aSLionel Sambuc         OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3823f4a2713aSLionel Sambuc       else if (NonTypeTemplateParmDecl *NTTP
3824f4a2713aSLionel Sambuc                                     = dyn_cast<NonTypeTemplateParmDecl>(Param))
3825f4a2713aSLionel Sambuc         OS << NTTP->getType().getAsString(Policy);
3826f4a2713aSLionel Sambuc       else
3827f4a2713aSLionel Sambuc         OS << "template<...> class";
3828f4a2713aSLionel Sambuc     }
3829f4a2713aSLionel Sambuc 
3830f4a2713aSLionel Sambuc     OS << ">";
3831f4a2713aSLionel Sambuc     return cxstring::createDup(OS.str());
3832f4a2713aSLionel Sambuc   }
3833f4a2713aSLionel Sambuc 
3834f4a2713aSLionel Sambuc   if (const ClassTemplateSpecializationDecl *ClassSpec
3835f4a2713aSLionel Sambuc                               = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3836f4a2713aSLionel Sambuc     // If the type was explicitly written, use that.
3837f4a2713aSLionel Sambuc     if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
3838f4a2713aSLionel Sambuc       return cxstring::createDup(TSInfo->getType().getAsString(Policy));
3839f4a2713aSLionel Sambuc 
3840f4a2713aSLionel Sambuc     SmallString<128> Str;
3841f4a2713aSLionel Sambuc     llvm::raw_svector_ostream OS(Str);
3842f4a2713aSLionel Sambuc     OS << *ClassSpec;
3843f4a2713aSLionel Sambuc     TemplateSpecializationType::PrintTemplateArgumentList(OS,
3844f4a2713aSLionel Sambuc                                       ClassSpec->getTemplateArgs().data(),
3845f4a2713aSLionel Sambuc                                       ClassSpec->getTemplateArgs().size(),
3846f4a2713aSLionel Sambuc                                                                 Policy);
3847f4a2713aSLionel Sambuc     return cxstring::createDup(OS.str());
3848f4a2713aSLionel Sambuc   }
3849f4a2713aSLionel Sambuc 
3850f4a2713aSLionel Sambuc   return clang_getCursorSpelling(C);
3851f4a2713aSLionel Sambuc }
3852f4a2713aSLionel Sambuc 
clang_getCursorKindSpelling(enum CXCursorKind Kind)3853f4a2713aSLionel Sambuc CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3854f4a2713aSLionel Sambuc   switch (Kind) {
3855f4a2713aSLionel Sambuc   case CXCursor_FunctionDecl:
3856f4a2713aSLionel Sambuc       return cxstring::createRef("FunctionDecl");
3857f4a2713aSLionel Sambuc   case CXCursor_TypedefDecl:
3858f4a2713aSLionel Sambuc       return cxstring::createRef("TypedefDecl");
3859f4a2713aSLionel Sambuc   case CXCursor_EnumDecl:
3860f4a2713aSLionel Sambuc       return cxstring::createRef("EnumDecl");
3861f4a2713aSLionel Sambuc   case CXCursor_EnumConstantDecl:
3862f4a2713aSLionel Sambuc       return cxstring::createRef("EnumConstantDecl");
3863f4a2713aSLionel Sambuc   case CXCursor_StructDecl:
3864f4a2713aSLionel Sambuc       return cxstring::createRef("StructDecl");
3865f4a2713aSLionel Sambuc   case CXCursor_UnionDecl:
3866f4a2713aSLionel Sambuc       return cxstring::createRef("UnionDecl");
3867f4a2713aSLionel Sambuc   case CXCursor_ClassDecl:
3868f4a2713aSLionel Sambuc       return cxstring::createRef("ClassDecl");
3869f4a2713aSLionel Sambuc   case CXCursor_FieldDecl:
3870f4a2713aSLionel Sambuc       return cxstring::createRef("FieldDecl");
3871f4a2713aSLionel Sambuc   case CXCursor_VarDecl:
3872f4a2713aSLionel Sambuc       return cxstring::createRef("VarDecl");
3873f4a2713aSLionel Sambuc   case CXCursor_ParmDecl:
3874f4a2713aSLionel Sambuc       return cxstring::createRef("ParmDecl");
3875f4a2713aSLionel Sambuc   case CXCursor_ObjCInterfaceDecl:
3876f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCInterfaceDecl");
3877f4a2713aSLionel Sambuc   case CXCursor_ObjCCategoryDecl:
3878f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCCategoryDecl");
3879f4a2713aSLionel Sambuc   case CXCursor_ObjCProtocolDecl:
3880f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCProtocolDecl");
3881f4a2713aSLionel Sambuc   case CXCursor_ObjCPropertyDecl:
3882f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCPropertyDecl");
3883f4a2713aSLionel Sambuc   case CXCursor_ObjCIvarDecl:
3884f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCIvarDecl");
3885f4a2713aSLionel Sambuc   case CXCursor_ObjCInstanceMethodDecl:
3886f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCInstanceMethodDecl");
3887f4a2713aSLionel Sambuc   case CXCursor_ObjCClassMethodDecl:
3888f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCClassMethodDecl");
3889f4a2713aSLionel Sambuc   case CXCursor_ObjCImplementationDecl:
3890f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCImplementationDecl");
3891f4a2713aSLionel Sambuc   case CXCursor_ObjCCategoryImplDecl:
3892f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCCategoryImplDecl");
3893f4a2713aSLionel Sambuc   case CXCursor_CXXMethod:
3894f4a2713aSLionel Sambuc       return cxstring::createRef("CXXMethod");
3895f4a2713aSLionel Sambuc   case CXCursor_UnexposedDecl:
3896f4a2713aSLionel Sambuc       return cxstring::createRef("UnexposedDecl");
3897f4a2713aSLionel Sambuc   case CXCursor_ObjCSuperClassRef:
3898f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCSuperClassRef");
3899f4a2713aSLionel Sambuc   case CXCursor_ObjCProtocolRef:
3900f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCProtocolRef");
3901f4a2713aSLionel Sambuc   case CXCursor_ObjCClassRef:
3902f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCClassRef");
3903f4a2713aSLionel Sambuc   case CXCursor_TypeRef:
3904f4a2713aSLionel Sambuc       return cxstring::createRef("TypeRef");
3905f4a2713aSLionel Sambuc   case CXCursor_TemplateRef:
3906f4a2713aSLionel Sambuc       return cxstring::createRef("TemplateRef");
3907f4a2713aSLionel Sambuc   case CXCursor_NamespaceRef:
3908f4a2713aSLionel Sambuc     return cxstring::createRef("NamespaceRef");
3909f4a2713aSLionel Sambuc   case CXCursor_MemberRef:
3910f4a2713aSLionel Sambuc     return cxstring::createRef("MemberRef");
3911f4a2713aSLionel Sambuc   case CXCursor_LabelRef:
3912f4a2713aSLionel Sambuc     return cxstring::createRef("LabelRef");
3913f4a2713aSLionel Sambuc   case CXCursor_OverloadedDeclRef:
3914f4a2713aSLionel Sambuc     return cxstring::createRef("OverloadedDeclRef");
3915f4a2713aSLionel Sambuc   case CXCursor_VariableRef:
3916f4a2713aSLionel Sambuc     return cxstring::createRef("VariableRef");
3917f4a2713aSLionel Sambuc   case CXCursor_IntegerLiteral:
3918f4a2713aSLionel Sambuc       return cxstring::createRef("IntegerLiteral");
3919f4a2713aSLionel Sambuc   case CXCursor_FloatingLiteral:
3920f4a2713aSLionel Sambuc       return cxstring::createRef("FloatingLiteral");
3921f4a2713aSLionel Sambuc   case CXCursor_ImaginaryLiteral:
3922f4a2713aSLionel Sambuc       return cxstring::createRef("ImaginaryLiteral");
3923f4a2713aSLionel Sambuc   case CXCursor_StringLiteral:
3924f4a2713aSLionel Sambuc       return cxstring::createRef("StringLiteral");
3925f4a2713aSLionel Sambuc   case CXCursor_CharacterLiteral:
3926f4a2713aSLionel Sambuc       return cxstring::createRef("CharacterLiteral");
3927f4a2713aSLionel Sambuc   case CXCursor_ParenExpr:
3928f4a2713aSLionel Sambuc       return cxstring::createRef("ParenExpr");
3929f4a2713aSLionel Sambuc   case CXCursor_UnaryOperator:
3930f4a2713aSLionel Sambuc       return cxstring::createRef("UnaryOperator");
3931f4a2713aSLionel Sambuc   case CXCursor_ArraySubscriptExpr:
3932f4a2713aSLionel Sambuc       return cxstring::createRef("ArraySubscriptExpr");
3933f4a2713aSLionel Sambuc   case CXCursor_BinaryOperator:
3934f4a2713aSLionel Sambuc       return cxstring::createRef("BinaryOperator");
3935f4a2713aSLionel Sambuc   case CXCursor_CompoundAssignOperator:
3936f4a2713aSLionel Sambuc       return cxstring::createRef("CompoundAssignOperator");
3937f4a2713aSLionel Sambuc   case CXCursor_ConditionalOperator:
3938f4a2713aSLionel Sambuc       return cxstring::createRef("ConditionalOperator");
3939f4a2713aSLionel Sambuc   case CXCursor_CStyleCastExpr:
3940f4a2713aSLionel Sambuc       return cxstring::createRef("CStyleCastExpr");
3941f4a2713aSLionel Sambuc   case CXCursor_CompoundLiteralExpr:
3942f4a2713aSLionel Sambuc       return cxstring::createRef("CompoundLiteralExpr");
3943f4a2713aSLionel Sambuc   case CXCursor_InitListExpr:
3944f4a2713aSLionel Sambuc       return cxstring::createRef("InitListExpr");
3945f4a2713aSLionel Sambuc   case CXCursor_AddrLabelExpr:
3946f4a2713aSLionel Sambuc       return cxstring::createRef("AddrLabelExpr");
3947f4a2713aSLionel Sambuc   case CXCursor_StmtExpr:
3948f4a2713aSLionel Sambuc       return cxstring::createRef("StmtExpr");
3949f4a2713aSLionel Sambuc   case CXCursor_GenericSelectionExpr:
3950f4a2713aSLionel Sambuc       return cxstring::createRef("GenericSelectionExpr");
3951f4a2713aSLionel Sambuc   case CXCursor_GNUNullExpr:
3952f4a2713aSLionel Sambuc       return cxstring::createRef("GNUNullExpr");
3953f4a2713aSLionel Sambuc   case CXCursor_CXXStaticCastExpr:
3954f4a2713aSLionel Sambuc       return cxstring::createRef("CXXStaticCastExpr");
3955f4a2713aSLionel Sambuc   case CXCursor_CXXDynamicCastExpr:
3956f4a2713aSLionel Sambuc       return cxstring::createRef("CXXDynamicCastExpr");
3957f4a2713aSLionel Sambuc   case CXCursor_CXXReinterpretCastExpr:
3958f4a2713aSLionel Sambuc       return cxstring::createRef("CXXReinterpretCastExpr");
3959f4a2713aSLionel Sambuc   case CXCursor_CXXConstCastExpr:
3960f4a2713aSLionel Sambuc       return cxstring::createRef("CXXConstCastExpr");
3961f4a2713aSLionel Sambuc   case CXCursor_CXXFunctionalCastExpr:
3962f4a2713aSLionel Sambuc       return cxstring::createRef("CXXFunctionalCastExpr");
3963f4a2713aSLionel Sambuc   case CXCursor_CXXTypeidExpr:
3964f4a2713aSLionel Sambuc       return cxstring::createRef("CXXTypeidExpr");
3965f4a2713aSLionel Sambuc   case CXCursor_CXXBoolLiteralExpr:
3966f4a2713aSLionel Sambuc       return cxstring::createRef("CXXBoolLiteralExpr");
3967f4a2713aSLionel Sambuc   case CXCursor_CXXNullPtrLiteralExpr:
3968f4a2713aSLionel Sambuc       return cxstring::createRef("CXXNullPtrLiteralExpr");
3969f4a2713aSLionel Sambuc   case CXCursor_CXXThisExpr:
3970f4a2713aSLionel Sambuc       return cxstring::createRef("CXXThisExpr");
3971f4a2713aSLionel Sambuc   case CXCursor_CXXThrowExpr:
3972f4a2713aSLionel Sambuc       return cxstring::createRef("CXXThrowExpr");
3973f4a2713aSLionel Sambuc   case CXCursor_CXXNewExpr:
3974f4a2713aSLionel Sambuc       return cxstring::createRef("CXXNewExpr");
3975f4a2713aSLionel Sambuc   case CXCursor_CXXDeleteExpr:
3976f4a2713aSLionel Sambuc       return cxstring::createRef("CXXDeleteExpr");
3977f4a2713aSLionel Sambuc   case CXCursor_UnaryExpr:
3978f4a2713aSLionel Sambuc       return cxstring::createRef("UnaryExpr");
3979f4a2713aSLionel Sambuc   case CXCursor_ObjCStringLiteral:
3980f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCStringLiteral");
3981f4a2713aSLionel Sambuc   case CXCursor_ObjCBoolLiteralExpr:
3982f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCBoolLiteralExpr");
3983f4a2713aSLionel Sambuc   case CXCursor_ObjCSelfExpr:
3984f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCSelfExpr");
3985f4a2713aSLionel Sambuc   case CXCursor_ObjCEncodeExpr:
3986f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCEncodeExpr");
3987f4a2713aSLionel Sambuc   case CXCursor_ObjCSelectorExpr:
3988f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCSelectorExpr");
3989f4a2713aSLionel Sambuc   case CXCursor_ObjCProtocolExpr:
3990f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCProtocolExpr");
3991f4a2713aSLionel Sambuc   case CXCursor_ObjCBridgedCastExpr:
3992f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCBridgedCastExpr");
3993f4a2713aSLionel Sambuc   case CXCursor_BlockExpr:
3994f4a2713aSLionel Sambuc       return cxstring::createRef("BlockExpr");
3995f4a2713aSLionel Sambuc   case CXCursor_PackExpansionExpr:
3996f4a2713aSLionel Sambuc       return cxstring::createRef("PackExpansionExpr");
3997f4a2713aSLionel Sambuc   case CXCursor_SizeOfPackExpr:
3998f4a2713aSLionel Sambuc       return cxstring::createRef("SizeOfPackExpr");
3999f4a2713aSLionel Sambuc   case CXCursor_LambdaExpr:
4000f4a2713aSLionel Sambuc     return cxstring::createRef("LambdaExpr");
4001f4a2713aSLionel Sambuc   case CXCursor_UnexposedExpr:
4002f4a2713aSLionel Sambuc       return cxstring::createRef("UnexposedExpr");
4003f4a2713aSLionel Sambuc   case CXCursor_DeclRefExpr:
4004f4a2713aSLionel Sambuc       return cxstring::createRef("DeclRefExpr");
4005f4a2713aSLionel Sambuc   case CXCursor_MemberRefExpr:
4006f4a2713aSLionel Sambuc       return cxstring::createRef("MemberRefExpr");
4007f4a2713aSLionel Sambuc   case CXCursor_CallExpr:
4008f4a2713aSLionel Sambuc       return cxstring::createRef("CallExpr");
4009f4a2713aSLionel Sambuc   case CXCursor_ObjCMessageExpr:
4010f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCMessageExpr");
4011f4a2713aSLionel Sambuc   case CXCursor_UnexposedStmt:
4012f4a2713aSLionel Sambuc       return cxstring::createRef("UnexposedStmt");
4013f4a2713aSLionel Sambuc   case CXCursor_DeclStmt:
4014f4a2713aSLionel Sambuc       return cxstring::createRef("DeclStmt");
4015f4a2713aSLionel Sambuc   case CXCursor_LabelStmt:
4016f4a2713aSLionel Sambuc       return cxstring::createRef("LabelStmt");
4017f4a2713aSLionel Sambuc   case CXCursor_CompoundStmt:
4018f4a2713aSLionel Sambuc       return cxstring::createRef("CompoundStmt");
4019f4a2713aSLionel Sambuc   case CXCursor_CaseStmt:
4020f4a2713aSLionel Sambuc       return cxstring::createRef("CaseStmt");
4021f4a2713aSLionel Sambuc   case CXCursor_DefaultStmt:
4022f4a2713aSLionel Sambuc       return cxstring::createRef("DefaultStmt");
4023f4a2713aSLionel Sambuc   case CXCursor_IfStmt:
4024f4a2713aSLionel Sambuc       return cxstring::createRef("IfStmt");
4025f4a2713aSLionel Sambuc   case CXCursor_SwitchStmt:
4026f4a2713aSLionel Sambuc       return cxstring::createRef("SwitchStmt");
4027f4a2713aSLionel Sambuc   case CXCursor_WhileStmt:
4028f4a2713aSLionel Sambuc       return cxstring::createRef("WhileStmt");
4029f4a2713aSLionel Sambuc   case CXCursor_DoStmt:
4030f4a2713aSLionel Sambuc       return cxstring::createRef("DoStmt");
4031f4a2713aSLionel Sambuc   case CXCursor_ForStmt:
4032f4a2713aSLionel Sambuc       return cxstring::createRef("ForStmt");
4033f4a2713aSLionel Sambuc   case CXCursor_GotoStmt:
4034f4a2713aSLionel Sambuc       return cxstring::createRef("GotoStmt");
4035f4a2713aSLionel Sambuc   case CXCursor_IndirectGotoStmt:
4036f4a2713aSLionel Sambuc       return cxstring::createRef("IndirectGotoStmt");
4037f4a2713aSLionel Sambuc   case CXCursor_ContinueStmt:
4038f4a2713aSLionel Sambuc       return cxstring::createRef("ContinueStmt");
4039f4a2713aSLionel Sambuc   case CXCursor_BreakStmt:
4040f4a2713aSLionel Sambuc       return cxstring::createRef("BreakStmt");
4041f4a2713aSLionel Sambuc   case CXCursor_ReturnStmt:
4042f4a2713aSLionel Sambuc       return cxstring::createRef("ReturnStmt");
4043f4a2713aSLionel Sambuc   case CXCursor_GCCAsmStmt:
4044f4a2713aSLionel Sambuc       return cxstring::createRef("GCCAsmStmt");
4045f4a2713aSLionel Sambuc   case CXCursor_MSAsmStmt:
4046f4a2713aSLionel Sambuc       return cxstring::createRef("MSAsmStmt");
4047f4a2713aSLionel Sambuc   case CXCursor_ObjCAtTryStmt:
4048f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCAtTryStmt");
4049f4a2713aSLionel Sambuc   case CXCursor_ObjCAtCatchStmt:
4050f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCAtCatchStmt");
4051f4a2713aSLionel Sambuc   case CXCursor_ObjCAtFinallyStmt:
4052f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCAtFinallyStmt");
4053f4a2713aSLionel Sambuc   case CXCursor_ObjCAtThrowStmt:
4054f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCAtThrowStmt");
4055f4a2713aSLionel Sambuc   case CXCursor_ObjCAtSynchronizedStmt:
4056f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCAtSynchronizedStmt");
4057f4a2713aSLionel Sambuc   case CXCursor_ObjCAutoreleasePoolStmt:
4058f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCAutoreleasePoolStmt");
4059f4a2713aSLionel Sambuc   case CXCursor_ObjCForCollectionStmt:
4060f4a2713aSLionel Sambuc       return cxstring::createRef("ObjCForCollectionStmt");
4061f4a2713aSLionel Sambuc   case CXCursor_CXXCatchStmt:
4062f4a2713aSLionel Sambuc       return cxstring::createRef("CXXCatchStmt");
4063f4a2713aSLionel Sambuc   case CXCursor_CXXTryStmt:
4064f4a2713aSLionel Sambuc       return cxstring::createRef("CXXTryStmt");
4065f4a2713aSLionel Sambuc   case CXCursor_CXXForRangeStmt:
4066f4a2713aSLionel Sambuc       return cxstring::createRef("CXXForRangeStmt");
4067f4a2713aSLionel Sambuc   case CXCursor_SEHTryStmt:
4068f4a2713aSLionel Sambuc       return cxstring::createRef("SEHTryStmt");
4069f4a2713aSLionel Sambuc   case CXCursor_SEHExceptStmt:
4070f4a2713aSLionel Sambuc       return cxstring::createRef("SEHExceptStmt");
4071f4a2713aSLionel Sambuc   case CXCursor_SEHFinallyStmt:
4072f4a2713aSLionel Sambuc       return cxstring::createRef("SEHFinallyStmt");
4073*0a6a1f1dSLionel Sambuc   case CXCursor_SEHLeaveStmt:
4074*0a6a1f1dSLionel Sambuc       return cxstring::createRef("SEHLeaveStmt");
4075f4a2713aSLionel Sambuc   case CXCursor_NullStmt:
4076f4a2713aSLionel Sambuc       return cxstring::createRef("NullStmt");
4077f4a2713aSLionel Sambuc   case CXCursor_InvalidFile:
4078f4a2713aSLionel Sambuc       return cxstring::createRef("InvalidFile");
4079f4a2713aSLionel Sambuc   case CXCursor_InvalidCode:
4080f4a2713aSLionel Sambuc     return cxstring::createRef("InvalidCode");
4081f4a2713aSLionel Sambuc   case CXCursor_NoDeclFound:
4082f4a2713aSLionel Sambuc       return cxstring::createRef("NoDeclFound");
4083f4a2713aSLionel Sambuc   case CXCursor_NotImplemented:
4084f4a2713aSLionel Sambuc       return cxstring::createRef("NotImplemented");
4085f4a2713aSLionel Sambuc   case CXCursor_TranslationUnit:
4086f4a2713aSLionel Sambuc       return cxstring::createRef("TranslationUnit");
4087f4a2713aSLionel Sambuc   case CXCursor_UnexposedAttr:
4088f4a2713aSLionel Sambuc       return cxstring::createRef("UnexposedAttr");
4089f4a2713aSLionel Sambuc   case CXCursor_IBActionAttr:
4090f4a2713aSLionel Sambuc       return cxstring::createRef("attribute(ibaction)");
4091f4a2713aSLionel Sambuc   case CXCursor_IBOutletAttr:
4092f4a2713aSLionel Sambuc      return cxstring::createRef("attribute(iboutlet)");
4093f4a2713aSLionel Sambuc   case CXCursor_IBOutletCollectionAttr:
4094f4a2713aSLionel Sambuc       return cxstring::createRef("attribute(iboutletcollection)");
4095f4a2713aSLionel Sambuc   case CXCursor_CXXFinalAttr:
4096f4a2713aSLionel Sambuc       return cxstring::createRef("attribute(final)");
4097f4a2713aSLionel Sambuc   case CXCursor_CXXOverrideAttr:
4098f4a2713aSLionel Sambuc       return cxstring::createRef("attribute(override)");
4099f4a2713aSLionel Sambuc   case CXCursor_AnnotateAttr:
4100f4a2713aSLionel Sambuc     return cxstring::createRef("attribute(annotate)");
4101f4a2713aSLionel Sambuc   case CXCursor_AsmLabelAttr:
4102f4a2713aSLionel Sambuc     return cxstring::createRef("asm label");
4103f4a2713aSLionel Sambuc   case CXCursor_PackedAttr:
4104f4a2713aSLionel Sambuc     return cxstring::createRef("attribute(packed)");
4105*0a6a1f1dSLionel Sambuc   case CXCursor_PureAttr:
4106*0a6a1f1dSLionel Sambuc     return cxstring::createRef("attribute(pure)");
4107*0a6a1f1dSLionel Sambuc   case CXCursor_ConstAttr:
4108*0a6a1f1dSLionel Sambuc     return cxstring::createRef("attribute(const)");
4109*0a6a1f1dSLionel Sambuc   case CXCursor_NoDuplicateAttr:
4110*0a6a1f1dSLionel Sambuc     return cxstring::createRef("attribute(noduplicate)");
4111*0a6a1f1dSLionel Sambuc   case CXCursor_CUDAConstantAttr:
4112*0a6a1f1dSLionel Sambuc     return cxstring::createRef("attribute(constant)");
4113*0a6a1f1dSLionel Sambuc   case CXCursor_CUDADeviceAttr:
4114*0a6a1f1dSLionel Sambuc     return cxstring::createRef("attribute(device)");
4115*0a6a1f1dSLionel Sambuc   case CXCursor_CUDAGlobalAttr:
4116*0a6a1f1dSLionel Sambuc     return cxstring::createRef("attribute(global)");
4117*0a6a1f1dSLionel Sambuc   case CXCursor_CUDAHostAttr:
4118*0a6a1f1dSLionel Sambuc     return cxstring::createRef("attribute(host)");
4119*0a6a1f1dSLionel Sambuc   case CXCursor_CUDASharedAttr:
4120*0a6a1f1dSLionel Sambuc     return cxstring::createRef("attribute(shared)");
4121f4a2713aSLionel Sambuc   case CXCursor_PreprocessingDirective:
4122f4a2713aSLionel Sambuc     return cxstring::createRef("preprocessing directive");
4123f4a2713aSLionel Sambuc   case CXCursor_MacroDefinition:
4124f4a2713aSLionel Sambuc     return cxstring::createRef("macro definition");
4125f4a2713aSLionel Sambuc   case CXCursor_MacroExpansion:
4126f4a2713aSLionel Sambuc     return cxstring::createRef("macro expansion");
4127f4a2713aSLionel Sambuc   case CXCursor_InclusionDirective:
4128f4a2713aSLionel Sambuc     return cxstring::createRef("inclusion directive");
4129f4a2713aSLionel Sambuc   case CXCursor_Namespace:
4130f4a2713aSLionel Sambuc     return cxstring::createRef("Namespace");
4131f4a2713aSLionel Sambuc   case CXCursor_LinkageSpec:
4132f4a2713aSLionel Sambuc     return cxstring::createRef("LinkageSpec");
4133f4a2713aSLionel Sambuc   case CXCursor_CXXBaseSpecifier:
4134f4a2713aSLionel Sambuc     return cxstring::createRef("C++ base class specifier");
4135f4a2713aSLionel Sambuc   case CXCursor_Constructor:
4136f4a2713aSLionel Sambuc     return cxstring::createRef("CXXConstructor");
4137f4a2713aSLionel Sambuc   case CXCursor_Destructor:
4138f4a2713aSLionel Sambuc     return cxstring::createRef("CXXDestructor");
4139f4a2713aSLionel Sambuc   case CXCursor_ConversionFunction:
4140f4a2713aSLionel Sambuc     return cxstring::createRef("CXXConversion");
4141f4a2713aSLionel Sambuc   case CXCursor_TemplateTypeParameter:
4142f4a2713aSLionel Sambuc     return cxstring::createRef("TemplateTypeParameter");
4143f4a2713aSLionel Sambuc   case CXCursor_NonTypeTemplateParameter:
4144f4a2713aSLionel Sambuc     return cxstring::createRef("NonTypeTemplateParameter");
4145f4a2713aSLionel Sambuc   case CXCursor_TemplateTemplateParameter:
4146f4a2713aSLionel Sambuc     return cxstring::createRef("TemplateTemplateParameter");
4147f4a2713aSLionel Sambuc   case CXCursor_FunctionTemplate:
4148f4a2713aSLionel Sambuc     return cxstring::createRef("FunctionTemplate");
4149f4a2713aSLionel Sambuc   case CXCursor_ClassTemplate:
4150f4a2713aSLionel Sambuc     return cxstring::createRef("ClassTemplate");
4151f4a2713aSLionel Sambuc   case CXCursor_ClassTemplatePartialSpecialization:
4152f4a2713aSLionel Sambuc     return cxstring::createRef("ClassTemplatePartialSpecialization");
4153f4a2713aSLionel Sambuc   case CXCursor_NamespaceAlias:
4154f4a2713aSLionel Sambuc     return cxstring::createRef("NamespaceAlias");
4155f4a2713aSLionel Sambuc   case CXCursor_UsingDirective:
4156f4a2713aSLionel Sambuc     return cxstring::createRef("UsingDirective");
4157f4a2713aSLionel Sambuc   case CXCursor_UsingDeclaration:
4158f4a2713aSLionel Sambuc     return cxstring::createRef("UsingDeclaration");
4159f4a2713aSLionel Sambuc   case CXCursor_TypeAliasDecl:
4160f4a2713aSLionel Sambuc     return cxstring::createRef("TypeAliasDecl");
4161f4a2713aSLionel Sambuc   case CXCursor_ObjCSynthesizeDecl:
4162f4a2713aSLionel Sambuc     return cxstring::createRef("ObjCSynthesizeDecl");
4163f4a2713aSLionel Sambuc   case CXCursor_ObjCDynamicDecl:
4164f4a2713aSLionel Sambuc     return cxstring::createRef("ObjCDynamicDecl");
4165f4a2713aSLionel Sambuc   case CXCursor_CXXAccessSpecifier:
4166f4a2713aSLionel Sambuc     return cxstring::createRef("CXXAccessSpecifier");
4167f4a2713aSLionel Sambuc   case CXCursor_ModuleImportDecl:
4168f4a2713aSLionel Sambuc     return cxstring::createRef("ModuleImport");
4169f4a2713aSLionel Sambuc   case CXCursor_OMPParallelDirective:
4170f4a2713aSLionel Sambuc     return cxstring::createRef("OMPParallelDirective");
4171*0a6a1f1dSLionel Sambuc   case CXCursor_OMPSimdDirective:
4172*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPSimdDirective");
4173*0a6a1f1dSLionel Sambuc   case CXCursor_OMPForDirective:
4174*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPForDirective");
4175*0a6a1f1dSLionel Sambuc   case CXCursor_OMPForSimdDirective:
4176*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPForSimdDirective");
4177*0a6a1f1dSLionel Sambuc   case CXCursor_OMPSectionsDirective:
4178*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPSectionsDirective");
4179*0a6a1f1dSLionel Sambuc   case CXCursor_OMPSectionDirective:
4180*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPSectionDirective");
4181*0a6a1f1dSLionel Sambuc   case CXCursor_OMPSingleDirective:
4182*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPSingleDirective");
4183*0a6a1f1dSLionel Sambuc   case CXCursor_OMPMasterDirective:
4184*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPMasterDirective");
4185*0a6a1f1dSLionel Sambuc   case CXCursor_OMPCriticalDirective:
4186*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPCriticalDirective");
4187*0a6a1f1dSLionel Sambuc   case CXCursor_OMPParallelForDirective:
4188*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPParallelForDirective");
4189*0a6a1f1dSLionel Sambuc   case CXCursor_OMPParallelForSimdDirective:
4190*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPParallelForSimdDirective");
4191*0a6a1f1dSLionel Sambuc   case CXCursor_OMPParallelSectionsDirective:
4192*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPParallelSectionsDirective");
4193*0a6a1f1dSLionel Sambuc   case CXCursor_OMPTaskDirective:
4194*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPTaskDirective");
4195*0a6a1f1dSLionel Sambuc   case CXCursor_OMPTaskyieldDirective:
4196*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPTaskyieldDirective");
4197*0a6a1f1dSLionel Sambuc   case CXCursor_OMPBarrierDirective:
4198*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPBarrierDirective");
4199*0a6a1f1dSLionel Sambuc   case CXCursor_OMPTaskwaitDirective:
4200*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPTaskwaitDirective");
4201*0a6a1f1dSLionel Sambuc   case CXCursor_OMPFlushDirective:
4202*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPFlushDirective");
4203*0a6a1f1dSLionel Sambuc   case CXCursor_OMPOrderedDirective:
4204*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPOrderedDirective");
4205*0a6a1f1dSLionel Sambuc   case CXCursor_OMPAtomicDirective:
4206*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPAtomicDirective");
4207*0a6a1f1dSLionel Sambuc   case CXCursor_OMPTargetDirective:
4208*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPTargetDirective");
4209*0a6a1f1dSLionel Sambuc   case CXCursor_OMPTeamsDirective:
4210*0a6a1f1dSLionel Sambuc     return cxstring::createRef("OMPTeamsDirective");
4211f4a2713aSLionel Sambuc   }
4212f4a2713aSLionel Sambuc 
4213f4a2713aSLionel Sambuc   llvm_unreachable("Unhandled CXCursorKind");
4214f4a2713aSLionel Sambuc }
4215f4a2713aSLionel Sambuc 
4216f4a2713aSLionel Sambuc struct GetCursorData {
4217f4a2713aSLionel Sambuc   SourceLocation TokenBeginLoc;
4218f4a2713aSLionel Sambuc   bool PointsAtMacroArgExpansion;
4219f4a2713aSLionel Sambuc   bool VisitedObjCPropertyImplDecl;
4220f4a2713aSLionel Sambuc   SourceLocation VisitedDeclaratorDeclStartLoc;
4221f4a2713aSLionel Sambuc   CXCursor &BestCursor;
4222f4a2713aSLionel Sambuc 
GetCursorDataGetCursorData4223f4a2713aSLionel Sambuc   GetCursorData(SourceManager &SM,
4224f4a2713aSLionel Sambuc                 SourceLocation tokenBegin, CXCursor &outputCursor)
4225f4a2713aSLionel Sambuc     : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4226f4a2713aSLionel Sambuc     PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4227f4a2713aSLionel Sambuc     VisitedObjCPropertyImplDecl = false;
4228f4a2713aSLionel Sambuc   }
4229f4a2713aSLionel Sambuc };
4230f4a2713aSLionel Sambuc 
GetCursorVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)4231f4a2713aSLionel Sambuc static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4232f4a2713aSLionel Sambuc                                                 CXCursor parent,
4233f4a2713aSLionel Sambuc                                                 CXClientData client_data) {
4234f4a2713aSLionel Sambuc   GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4235f4a2713aSLionel Sambuc   CXCursor *BestCursor = &Data->BestCursor;
4236f4a2713aSLionel Sambuc 
4237f4a2713aSLionel Sambuc   // If we point inside a macro argument we should provide info of what the
4238f4a2713aSLionel Sambuc   // token is so use the actual cursor, don't replace it with a macro expansion
4239f4a2713aSLionel Sambuc   // cursor.
4240f4a2713aSLionel Sambuc   if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4241f4a2713aSLionel Sambuc     return CXChildVisit_Recurse;
4242f4a2713aSLionel Sambuc 
4243f4a2713aSLionel Sambuc   if (clang_isDeclaration(cursor.kind)) {
4244f4a2713aSLionel Sambuc     // Avoid having the implicit methods override the property decls.
4245f4a2713aSLionel Sambuc     if (const ObjCMethodDecl *MD
4246f4a2713aSLionel Sambuc           = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4247f4a2713aSLionel Sambuc       if (MD->isImplicit())
4248f4a2713aSLionel Sambuc         return CXChildVisit_Break;
4249f4a2713aSLionel Sambuc 
4250f4a2713aSLionel Sambuc     } else if (const ObjCInterfaceDecl *ID
4251f4a2713aSLionel Sambuc                  = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4252f4a2713aSLionel Sambuc       // Check that when we have multiple @class references in the same line,
4253f4a2713aSLionel Sambuc       // that later ones do not override the previous ones.
4254f4a2713aSLionel Sambuc       // If we have:
4255f4a2713aSLionel Sambuc       // @class Foo, Bar;
4256f4a2713aSLionel Sambuc       // source ranges for both start at '@', so 'Bar' will end up overriding
4257f4a2713aSLionel Sambuc       // 'Foo' even though the cursor location was at 'Foo'.
4258f4a2713aSLionel Sambuc       if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4259f4a2713aSLionel Sambuc           BestCursor->kind == CXCursor_ObjCClassRef)
4260f4a2713aSLionel Sambuc         if (const ObjCInterfaceDecl *PrevID
4261f4a2713aSLionel Sambuc              = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4262f4a2713aSLionel Sambuc          if (PrevID != ID &&
4263f4a2713aSLionel Sambuc              !PrevID->isThisDeclarationADefinition() &&
4264f4a2713aSLionel Sambuc              !ID->isThisDeclarationADefinition())
4265f4a2713aSLionel Sambuc            return CXChildVisit_Break;
4266f4a2713aSLionel Sambuc         }
4267f4a2713aSLionel Sambuc 
4268f4a2713aSLionel Sambuc     } else if (const DeclaratorDecl *DD
4269f4a2713aSLionel Sambuc                     = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4270f4a2713aSLionel Sambuc       SourceLocation StartLoc = DD->getSourceRange().getBegin();
4271f4a2713aSLionel Sambuc       // Check that when we have multiple declarators in the same line,
4272f4a2713aSLionel Sambuc       // that later ones do not override the previous ones.
4273f4a2713aSLionel Sambuc       // If we have:
4274f4a2713aSLionel Sambuc       // int Foo, Bar;
4275f4a2713aSLionel Sambuc       // source ranges for both start at 'int', so 'Bar' will end up overriding
4276f4a2713aSLionel Sambuc       // 'Foo' even though the cursor location was at 'Foo'.
4277f4a2713aSLionel Sambuc       if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4278f4a2713aSLionel Sambuc         return CXChildVisit_Break;
4279f4a2713aSLionel Sambuc       Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4280f4a2713aSLionel Sambuc 
4281f4a2713aSLionel Sambuc     } else if (const ObjCPropertyImplDecl *PropImp
4282f4a2713aSLionel Sambuc               = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4283f4a2713aSLionel Sambuc       (void)PropImp;
4284f4a2713aSLionel Sambuc       // Check that when we have multiple @synthesize in the same line,
4285f4a2713aSLionel Sambuc       // that later ones do not override the previous ones.
4286f4a2713aSLionel Sambuc       // If we have:
4287f4a2713aSLionel Sambuc       // @synthesize Foo, Bar;
4288f4a2713aSLionel Sambuc       // source ranges for both start at '@', so 'Bar' will end up overriding
4289f4a2713aSLionel Sambuc       // 'Foo' even though the cursor location was at 'Foo'.
4290f4a2713aSLionel Sambuc       if (Data->VisitedObjCPropertyImplDecl)
4291f4a2713aSLionel Sambuc         return CXChildVisit_Break;
4292f4a2713aSLionel Sambuc       Data->VisitedObjCPropertyImplDecl = true;
4293f4a2713aSLionel Sambuc     }
4294f4a2713aSLionel Sambuc   }
4295f4a2713aSLionel Sambuc 
4296f4a2713aSLionel Sambuc   if (clang_isExpression(cursor.kind) &&
4297f4a2713aSLionel Sambuc       clang_isDeclaration(BestCursor->kind)) {
4298f4a2713aSLionel Sambuc     if (const Decl *D = getCursorDecl(*BestCursor)) {
4299f4a2713aSLionel Sambuc       // Avoid having the cursor of an expression replace the declaration cursor
4300f4a2713aSLionel Sambuc       // when the expression source range overlaps the declaration range.
4301f4a2713aSLionel Sambuc       // This can happen for C++ constructor expressions whose range generally
4302f4a2713aSLionel Sambuc       // include the variable declaration, e.g.:
4303f4a2713aSLionel Sambuc       //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4304f4a2713aSLionel Sambuc       if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4305f4a2713aSLionel Sambuc           D->getLocation() == Data->TokenBeginLoc)
4306f4a2713aSLionel Sambuc         return CXChildVisit_Break;
4307f4a2713aSLionel Sambuc     }
4308f4a2713aSLionel Sambuc   }
4309f4a2713aSLionel Sambuc 
4310f4a2713aSLionel Sambuc   // If our current best cursor is the construction of a temporary object,
4311f4a2713aSLionel Sambuc   // don't replace that cursor with a type reference, because we want
4312f4a2713aSLionel Sambuc   // clang_getCursor() to point at the constructor.
4313f4a2713aSLionel Sambuc   if (clang_isExpression(BestCursor->kind) &&
4314f4a2713aSLionel Sambuc       isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4315f4a2713aSLionel Sambuc       cursor.kind == CXCursor_TypeRef) {
4316f4a2713aSLionel Sambuc     // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4317f4a2713aSLionel Sambuc     // as having the actual point on the type reference.
4318f4a2713aSLionel Sambuc     *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4319f4a2713aSLionel Sambuc     return CXChildVisit_Recurse;
4320f4a2713aSLionel Sambuc   }
4321f4a2713aSLionel Sambuc 
4322f4a2713aSLionel Sambuc   *BestCursor = cursor;
4323f4a2713aSLionel Sambuc   return CXChildVisit_Recurse;
4324f4a2713aSLionel Sambuc }
4325f4a2713aSLionel Sambuc 
clang_getCursor(CXTranslationUnit TU,CXSourceLocation Loc)4326f4a2713aSLionel Sambuc CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
4327*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
4328*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
4329f4a2713aSLionel Sambuc     return clang_getNullCursor();
4330*0a6a1f1dSLionel Sambuc   }
4331f4a2713aSLionel Sambuc 
4332f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4333f4a2713aSLionel Sambuc   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4334f4a2713aSLionel Sambuc 
4335f4a2713aSLionel Sambuc   SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4336f4a2713aSLionel Sambuc   CXCursor Result = cxcursor::getCursor(TU, SLoc);
4337f4a2713aSLionel Sambuc 
4338f4a2713aSLionel Sambuc   LOG_FUNC_SECTION {
4339f4a2713aSLionel Sambuc     CXFile SearchFile;
4340f4a2713aSLionel Sambuc     unsigned SearchLine, SearchColumn;
4341f4a2713aSLionel Sambuc     CXFile ResultFile;
4342f4a2713aSLionel Sambuc     unsigned ResultLine, ResultColumn;
4343f4a2713aSLionel Sambuc     CXString SearchFileName, ResultFileName, KindSpelling, USR;
4344f4a2713aSLionel Sambuc     const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4345f4a2713aSLionel Sambuc     CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4346f4a2713aSLionel Sambuc 
4347*0a6a1f1dSLionel Sambuc     clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4348*0a6a1f1dSLionel Sambuc                           nullptr);
4349f4a2713aSLionel Sambuc     clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
4350*0a6a1f1dSLionel Sambuc                           &ResultColumn, nullptr);
4351f4a2713aSLionel Sambuc     SearchFileName = clang_getFileName(SearchFile);
4352f4a2713aSLionel Sambuc     ResultFileName = clang_getFileName(ResultFile);
4353f4a2713aSLionel Sambuc     KindSpelling = clang_getCursorKindSpelling(Result.kind);
4354f4a2713aSLionel Sambuc     USR = clang_getCursorUSR(Result);
4355f4a2713aSLionel Sambuc     *Log << llvm::format("(%s:%d:%d) = %s",
4356f4a2713aSLionel Sambuc                    clang_getCString(SearchFileName), SearchLine, SearchColumn,
4357f4a2713aSLionel Sambuc                    clang_getCString(KindSpelling))
4358f4a2713aSLionel Sambuc         << llvm::format("(%s:%d:%d):%s%s",
4359f4a2713aSLionel Sambuc                      clang_getCString(ResultFileName), ResultLine, ResultColumn,
4360f4a2713aSLionel Sambuc                      clang_getCString(USR), IsDef);
4361f4a2713aSLionel Sambuc     clang_disposeString(SearchFileName);
4362f4a2713aSLionel Sambuc     clang_disposeString(ResultFileName);
4363f4a2713aSLionel Sambuc     clang_disposeString(KindSpelling);
4364f4a2713aSLionel Sambuc     clang_disposeString(USR);
4365f4a2713aSLionel Sambuc 
4366f4a2713aSLionel Sambuc     CXCursor Definition = clang_getCursorDefinition(Result);
4367f4a2713aSLionel Sambuc     if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4368f4a2713aSLionel Sambuc       CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4369f4a2713aSLionel Sambuc       CXString DefinitionKindSpelling
4370f4a2713aSLionel Sambuc                                 = clang_getCursorKindSpelling(Definition.kind);
4371f4a2713aSLionel Sambuc       CXFile DefinitionFile;
4372f4a2713aSLionel Sambuc       unsigned DefinitionLine, DefinitionColumn;
4373f4a2713aSLionel Sambuc       clang_getFileLocation(DefinitionLoc, &DefinitionFile,
4374*0a6a1f1dSLionel Sambuc                             &DefinitionLine, &DefinitionColumn, nullptr);
4375f4a2713aSLionel Sambuc       CXString DefinitionFileName = clang_getFileName(DefinitionFile);
4376f4a2713aSLionel Sambuc       *Log << llvm::format("  -> %s(%s:%d:%d)",
4377f4a2713aSLionel Sambuc                      clang_getCString(DefinitionKindSpelling),
4378f4a2713aSLionel Sambuc                      clang_getCString(DefinitionFileName),
4379f4a2713aSLionel Sambuc                      DefinitionLine, DefinitionColumn);
4380f4a2713aSLionel Sambuc       clang_disposeString(DefinitionFileName);
4381f4a2713aSLionel Sambuc       clang_disposeString(DefinitionKindSpelling);
4382f4a2713aSLionel Sambuc     }
4383f4a2713aSLionel Sambuc   }
4384f4a2713aSLionel Sambuc 
4385f4a2713aSLionel Sambuc   return Result;
4386f4a2713aSLionel Sambuc }
4387f4a2713aSLionel Sambuc 
clang_getNullCursor(void)4388f4a2713aSLionel Sambuc CXCursor clang_getNullCursor(void) {
4389f4a2713aSLionel Sambuc   return MakeCXCursorInvalid(CXCursor_InvalidFile);
4390f4a2713aSLionel Sambuc }
4391f4a2713aSLionel Sambuc 
clang_equalCursors(CXCursor X,CXCursor Y)4392f4a2713aSLionel Sambuc unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
4393f4a2713aSLionel Sambuc   // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4394f4a2713aSLionel Sambuc   // can't set consistently. For example, when visiting a DeclStmt we will set
4395f4a2713aSLionel Sambuc   // it but we don't set it on the result of clang_getCursorDefinition for
4396f4a2713aSLionel Sambuc   // a reference of the same declaration.
4397f4a2713aSLionel Sambuc   // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4398f4a2713aSLionel Sambuc   // when visiting a DeclStmt currently, the AST should be enhanced to be able
4399f4a2713aSLionel Sambuc   // to provide that kind of info.
4400f4a2713aSLionel Sambuc   if (clang_isDeclaration(X.kind))
4401*0a6a1f1dSLionel Sambuc     X.data[1] = nullptr;
4402f4a2713aSLionel Sambuc   if (clang_isDeclaration(Y.kind))
4403*0a6a1f1dSLionel Sambuc     Y.data[1] = nullptr;
4404f4a2713aSLionel Sambuc 
4405f4a2713aSLionel Sambuc   return X == Y;
4406f4a2713aSLionel Sambuc }
4407f4a2713aSLionel Sambuc 
clang_hashCursor(CXCursor C)4408f4a2713aSLionel Sambuc unsigned clang_hashCursor(CXCursor C) {
4409f4a2713aSLionel Sambuc   unsigned Index = 0;
4410f4a2713aSLionel Sambuc   if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4411f4a2713aSLionel Sambuc     Index = 1;
4412f4a2713aSLionel Sambuc 
4413f4a2713aSLionel Sambuc   return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
4414f4a2713aSLionel Sambuc                                         std::make_pair(C.kind, C.data[Index]));
4415f4a2713aSLionel Sambuc }
4416f4a2713aSLionel Sambuc 
clang_isInvalid(enum CXCursorKind K)4417f4a2713aSLionel Sambuc unsigned clang_isInvalid(enum CXCursorKind K) {
4418f4a2713aSLionel Sambuc   return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4419f4a2713aSLionel Sambuc }
4420f4a2713aSLionel Sambuc 
clang_isDeclaration(enum CXCursorKind K)4421f4a2713aSLionel Sambuc unsigned clang_isDeclaration(enum CXCursorKind K) {
4422f4a2713aSLionel Sambuc   return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4423f4a2713aSLionel Sambuc          (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4424f4a2713aSLionel Sambuc }
4425f4a2713aSLionel Sambuc 
clang_isReference(enum CXCursorKind K)4426f4a2713aSLionel Sambuc unsigned clang_isReference(enum CXCursorKind K) {
4427f4a2713aSLionel Sambuc   return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4428f4a2713aSLionel Sambuc }
4429f4a2713aSLionel Sambuc 
clang_isExpression(enum CXCursorKind K)4430f4a2713aSLionel Sambuc unsigned clang_isExpression(enum CXCursorKind K) {
4431f4a2713aSLionel Sambuc   return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4432f4a2713aSLionel Sambuc }
4433f4a2713aSLionel Sambuc 
clang_isStatement(enum CXCursorKind K)4434f4a2713aSLionel Sambuc unsigned clang_isStatement(enum CXCursorKind K) {
4435f4a2713aSLionel Sambuc   return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4436f4a2713aSLionel Sambuc }
4437f4a2713aSLionel Sambuc 
clang_isAttribute(enum CXCursorKind K)4438f4a2713aSLionel Sambuc unsigned clang_isAttribute(enum CXCursorKind K) {
4439f4a2713aSLionel Sambuc     return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4440f4a2713aSLionel Sambuc }
4441f4a2713aSLionel Sambuc 
clang_isTranslationUnit(enum CXCursorKind K)4442f4a2713aSLionel Sambuc unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4443f4a2713aSLionel Sambuc   return K == CXCursor_TranslationUnit;
4444f4a2713aSLionel Sambuc }
4445f4a2713aSLionel Sambuc 
clang_isPreprocessing(enum CXCursorKind K)4446f4a2713aSLionel Sambuc unsigned clang_isPreprocessing(enum CXCursorKind K) {
4447f4a2713aSLionel Sambuc   return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4448f4a2713aSLionel Sambuc }
4449f4a2713aSLionel Sambuc 
clang_isUnexposed(enum CXCursorKind K)4450f4a2713aSLionel Sambuc unsigned clang_isUnexposed(enum CXCursorKind K) {
4451f4a2713aSLionel Sambuc   switch (K) {
4452f4a2713aSLionel Sambuc     case CXCursor_UnexposedDecl:
4453f4a2713aSLionel Sambuc     case CXCursor_UnexposedExpr:
4454f4a2713aSLionel Sambuc     case CXCursor_UnexposedStmt:
4455f4a2713aSLionel Sambuc     case CXCursor_UnexposedAttr:
4456f4a2713aSLionel Sambuc       return true;
4457f4a2713aSLionel Sambuc     default:
4458f4a2713aSLionel Sambuc       return false;
4459f4a2713aSLionel Sambuc   }
4460f4a2713aSLionel Sambuc }
4461f4a2713aSLionel Sambuc 
clang_getCursorKind(CXCursor C)4462f4a2713aSLionel Sambuc CXCursorKind clang_getCursorKind(CXCursor C) {
4463f4a2713aSLionel Sambuc   return C.kind;
4464f4a2713aSLionel Sambuc }
4465f4a2713aSLionel Sambuc 
clang_getCursorLocation(CXCursor C)4466f4a2713aSLionel Sambuc CXSourceLocation clang_getCursorLocation(CXCursor C) {
4467f4a2713aSLionel Sambuc   if (clang_isReference(C.kind)) {
4468f4a2713aSLionel Sambuc     switch (C.kind) {
4469f4a2713aSLionel Sambuc     case CXCursor_ObjCSuperClassRef: {
4470f4a2713aSLionel Sambuc       std::pair<const ObjCInterfaceDecl *, SourceLocation> P
4471f4a2713aSLionel Sambuc         = getCursorObjCSuperClassRef(C);
4472f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4473f4a2713aSLionel Sambuc     }
4474f4a2713aSLionel Sambuc 
4475f4a2713aSLionel Sambuc     case CXCursor_ObjCProtocolRef: {
4476f4a2713aSLionel Sambuc       std::pair<const ObjCProtocolDecl *, SourceLocation> P
4477f4a2713aSLionel Sambuc         = getCursorObjCProtocolRef(C);
4478f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4479f4a2713aSLionel Sambuc     }
4480f4a2713aSLionel Sambuc 
4481f4a2713aSLionel Sambuc     case CXCursor_ObjCClassRef: {
4482f4a2713aSLionel Sambuc       std::pair<const ObjCInterfaceDecl *, SourceLocation> P
4483f4a2713aSLionel Sambuc         = getCursorObjCClassRef(C);
4484f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4485f4a2713aSLionel Sambuc     }
4486f4a2713aSLionel Sambuc 
4487f4a2713aSLionel Sambuc     case CXCursor_TypeRef: {
4488f4a2713aSLionel Sambuc       std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
4489f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4490f4a2713aSLionel Sambuc     }
4491f4a2713aSLionel Sambuc 
4492f4a2713aSLionel Sambuc     case CXCursor_TemplateRef: {
4493f4a2713aSLionel Sambuc       std::pair<const TemplateDecl *, SourceLocation> P =
4494f4a2713aSLionel Sambuc           getCursorTemplateRef(C);
4495f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4496f4a2713aSLionel Sambuc     }
4497f4a2713aSLionel Sambuc 
4498f4a2713aSLionel Sambuc     case CXCursor_NamespaceRef: {
4499f4a2713aSLionel Sambuc       std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
4500f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4501f4a2713aSLionel Sambuc     }
4502f4a2713aSLionel Sambuc 
4503f4a2713aSLionel Sambuc     case CXCursor_MemberRef: {
4504f4a2713aSLionel Sambuc       std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
4505f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4506f4a2713aSLionel Sambuc     }
4507f4a2713aSLionel Sambuc 
4508f4a2713aSLionel Sambuc     case CXCursor_VariableRef: {
4509f4a2713aSLionel Sambuc       std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
4510f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4511f4a2713aSLionel Sambuc     }
4512f4a2713aSLionel Sambuc 
4513f4a2713aSLionel Sambuc     case CXCursor_CXXBaseSpecifier: {
4514f4a2713aSLionel Sambuc       const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
4515f4a2713aSLionel Sambuc       if (!BaseSpec)
4516f4a2713aSLionel Sambuc         return clang_getNullLocation();
4517f4a2713aSLionel Sambuc 
4518f4a2713aSLionel Sambuc       if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4519f4a2713aSLionel Sambuc         return cxloc::translateSourceLocation(getCursorContext(C),
4520f4a2713aSLionel Sambuc                                             TSInfo->getTypeLoc().getBeginLoc());
4521f4a2713aSLionel Sambuc 
4522f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(getCursorContext(C),
4523f4a2713aSLionel Sambuc                                         BaseSpec->getLocStart());
4524f4a2713aSLionel Sambuc     }
4525f4a2713aSLionel Sambuc 
4526f4a2713aSLionel Sambuc     case CXCursor_LabelRef: {
4527f4a2713aSLionel Sambuc       std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
4528f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4529f4a2713aSLionel Sambuc     }
4530f4a2713aSLionel Sambuc 
4531f4a2713aSLionel Sambuc     case CXCursor_OverloadedDeclRef:
4532f4a2713aSLionel Sambuc       return cxloc::translateSourceLocation(getCursorContext(C),
4533f4a2713aSLionel Sambuc                                           getCursorOverloadedDeclRef(C).second);
4534f4a2713aSLionel Sambuc 
4535f4a2713aSLionel Sambuc     default:
4536f4a2713aSLionel Sambuc       // FIXME: Need a way to enumerate all non-reference cases.
4537f4a2713aSLionel Sambuc       llvm_unreachable("Missed a reference kind");
4538f4a2713aSLionel Sambuc     }
4539f4a2713aSLionel Sambuc   }
4540f4a2713aSLionel Sambuc 
4541f4a2713aSLionel Sambuc   if (clang_isExpression(C.kind))
4542f4a2713aSLionel Sambuc     return cxloc::translateSourceLocation(getCursorContext(C),
4543f4a2713aSLionel Sambuc                                    getLocationFromExpr(getCursorExpr(C)));
4544f4a2713aSLionel Sambuc 
4545f4a2713aSLionel Sambuc   if (clang_isStatement(C.kind))
4546f4a2713aSLionel Sambuc     return cxloc::translateSourceLocation(getCursorContext(C),
4547f4a2713aSLionel Sambuc                                           getCursorStmt(C)->getLocStart());
4548f4a2713aSLionel Sambuc 
4549f4a2713aSLionel Sambuc   if (C.kind == CXCursor_PreprocessingDirective) {
4550f4a2713aSLionel Sambuc     SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4551f4a2713aSLionel Sambuc     return cxloc::translateSourceLocation(getCursorContext(C), L);
4552f4a2713aSLionel Sambuc   }
4553f4a2713aSLionel Sambuc 
4554f4a2713aSLionel Sambuc   if (C.kind == CXCursor_MacroExpansion) {
4555f4a2713aSLionel Sambuc     SourceLocation L
4556f4a2713aSLionel Sambuc       = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
4557f4a2713aSLionel Sambuc     return cxloc::translateSourceLocation(getCursorContext(C), L);
4558f4a2713aSLionel Sambuc   }
4559f4a2713aSLionel Sambuc 
4560f4a2713aSLionel Sambuc   if (C.kind == CXCursor_MacroDefinition) {
4561f4a2713aSLionel Sambuc     SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4562f4a2713aSLionel Sambuc     return cxloc::translateSourceLocation(getCursorContext(C), L);
4563f4a2713aSLionel Sambuc   }
4564f4a2713aSLionel Sambuc 
4565f4a2713aSLionel Sambuc   if (C.kind == CXCursor_InclusionDirective) {
4566f4a2713aSLionel Sambuc     SourceLocation L
4567f4a2713aSLionel Sambuc       = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4568f4a2713aSLionel Sambuc     return cxloc::translateSourceLocation(getCursorContext(C), L);
4569f4a2713aSLionel Sambuc   }
4570f4a2713aSLionel Sambuc 
4571f4a2713aSLionel Sambuc   if (clang_isAttribute(C.kind)) {
4572f4a2713aSLionel Sambuc     SourceLocation L
4573f4a2713aSLionel Sambuc       = cxcursor::getCursorAttr(C)->getLocation();
4574f4a2713aSLionel Sambuc     return cxloc::translateSourceLocation(getCursorContext(C), L);
4575f4a2713aSLionel Sambuc   }
4576f4a2713aSLionel Sambuc 
4577f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
4578f4a2713aSLionel Sambuc     return clang_getNullLocation();
4579f4a2713aSLionel Sambuc 
4580f4a2713aSLionel Sambuc   const Decl *D = getCursorDecl(C);
4581f4a2713aSLionel Sambuc   if (!D)
4582f4a2713aSLionel Sambuc     return clang_getNullLocation();
4583f4a2713aSLionel Sambuc 
4584f4a2713aSLionel Sambuc   SourceLocation Loc = D->getLocation();
4585f4a2713aSLionel Sambuc   // FIXME: Multiple variables declared in a single declaration
4586f4a2713aSLionel Sambuc   // currently lack the information needed to correctly determine their
4587f4a2713aSLionel Sambuc   // ranges when accounting for the type-specifier.  We use context
4588f4a2713aSLionel Sambuc   // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4589f4a2713aSLionel Sambuc   // and if so, whether it is the first decl.
4590f4a2713aSLionel Sambuc   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
4591f4a2713aSLionel Sambuc     if (!cxcursor::isFirstInDeclGroup(C))
4592f4a2713aSLionel Sambuc       Loc = VD->getLocation();
4593f4a2713aSLionel Sambuc   }
4594f4a2713aSLionel Sambuc 
4595f4a2713aSLionel Sambuc   // For ObjC methods, give the start location of the method name.
4596f4a2713aSLionel Sambuc   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
4597f4a2713aSLionel Sambuc     Loc = MD->getSelectorStartLoc();
4598f4a2713aSLionel Sambuc 
4599f4a2713aSLionel Sambuc   return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4600f4a2713aSLionel Sambuc }
4601f4a2713aSLionel Sambuc 
4602f4a2713aSLionel Sambuc } // end extern "C"
4603f4a2713aSLionel Sambuc 
getCursor(CXTranslationUnit TU,SourceLocation SLoc)4604f4a2713aSLionel Sambuc CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4605f4a2713aSLionel Sambuc   assert(TU);
4606f4a2713aSLionel Sambuc 
4607f4a2713aSLionel Sambuc   // Guard against an invalid SourceLocation, or we may assert in one
4608f4a2713aSLionel Sambuc   // of the following calls.
4609f4a2713aSLionel Sambuc   if (SLoc.isInvalid())
4610f4a2713aSLionel Sambuc     return clang_getNullCursor();
4611f4a2713aSLionel Sambuc 
4612f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4613f4a2713aSLionel Sambuc 
4614f4a2713aSLionel Sambuc   // Translate the given source location to make it point at the beginning of
4615f4a2713aSLionel Sambuc   // the token under the cursor.
4616f4a2713aSLionel Sambuc   SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4617f4a2713aSLionel Sambuc                                     CXXUnit->getASTContext().getLangOpts());
4618f4a2713aSLionel Sambuc 
4619f4a2713aSLionel Sambuc   CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4620f4a2713aSLionel Sambuc   if (SLoc.isValid()) {
4621f4a2713aSLionel Sambuc     GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4622f4a2713aSLionel Sambuc     CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4623f4a2713aSLionel Sambuc                             /*VisitPreprocessorLast=*/true,
4624f4a2713aSLionel Sambuc                             /*VisitIncludedEntities=*/false,
4625f4a2713aSLionel Sambuc                             SourceLocation(SLoc));
4626f4a2713aSLionel Sambuc     CursorVis.visitFileRegion();
4627f4a2713aSLionel Sambuc   }
4628f4a2713aSLionel Sambuc 
4629f4a2713aSLionel Sambuc   return Result;
4630f4a2713aSLionel Sambuc }
4631f4a2713aSLionel Sambuc 
getRawCursorExtent(CXCursor C)4632f4a2713aSLionel Sambuc static SourceRange getRawCursorExtent(CXCursor C) {
4633f4a2713aSLionel Sambuc   if (clang_isReference(C.kind)) {
4634f4a2713aSLionel Sambuc     switch (C.kind) {
4635f4a2713aSLionel Sambuc     case CXCursor_ObjCSuperClassRef:
4636f4a2713aSLionel Sambuc       return  getCursorObjCSuperClassRef(C).second;
4637f4a2713aSLionel Sambuc 
4638f4a2713aSLionel Sambuc     case CXCursor_ObjCProtocolRef:
4639f4a2713aSLionel Sambuc       return getCursorObjCProtocolRef(C).second;
4640f4a2713aSLionel Sambuc 
4641f4a2713aSLionel Sambuc     case CXCursor_ObjCClassRef:
4642f4a2713aSLionel Sambuc       return getCursorObjCClassRef(C).second;
4643f4a2713aSLionel Sambuc 
4644f4a2713aSLionel Sambuc     case CXCursor_TypeRef:
4645f4a2713aSLionel Sambuc       return getCursorTypeRef(C).second;
4646f4a2713aSLionel Sambuc 
4647f4a2713aSLionel Sambuc     case CXCursor_TemplateRef:
4648f4a2713aSLionel Sambuc       return getCursorTemplateRef(C).second;
4649f4a2713aSLionel Sambuc 
4650f4a2713aSLionel Sambuc     case CXCursor_NamespaceRef:
4651f4a2713aSLionel Sambuc       return getCursorNamespaceRef(C).second;
4652f4a2713aSLionel Sambuc 
4653f4a2713aSLionel Sambuc     case CXCursor_MemberRef:
4654f4a2713aSLionel Sambuc       return getCursorMemberRef(C).second;
4655f4a2713aSLionel Sambuc 
4656f4a2713aSLionel Sambuc     case CXCursor_CXXBaseSpecifier:
4657f4a2713aSLionel Sambuc       return getCursorCXXBaseSpecifier(C)->getSourceRange();
4658f4a2713aSLionel Sambuc 
4659f4a2713aSLionel Sambuc     case CXCursor_LabelRef:
4660f4a2713aSLionel Sambuc       return getCursorLabelRef(C).second;
4661f4a2713aSLionel Sambuc 
4662f4a2713aSLionel Sambuc     case CXCursor_OverloadedDeclRef:
4663f4a2713aSLionel Sambuc       return getCursorOverloadedDeclRef(C).second;
4664f4a2713aSLionel Sambuc 
4665f4a2713aSLionel Sambuc     case CXCursor_VariableRef:
4666f4a2713aSLionel Sambuc       return getCursorVariableRef(C).second;
4667f4a2713aSLionel Sambuc 
4668f4a2713aSLionel Sambuc     default:
4669f4a2713aSLionel Sambuc       // FIXME: Need a way to enumerate all non-reference cases.
4670f4a2713aSLionel Sambuc       llvm_unreachable("Missed a reference kind");
4671f4a2713aSLionel Sambuc     }
4672f4a2713aSLionel Sambuc   }
4673f4a2713aSLionel Sambuc 
4674f4a2713aSLionel Sambuc   if (clang_isExpression(C.kind))
4675f4a2713aSLionel Sambuc     return getCursorExpr(C)->getSourceRange();
4676f4a2713aSLionel Sambuc 
4677f4a2713aSLionel Sambuc   if (clang_isStatement(C.kind))
4678f4a2713aSLionel Sambuc     return getCursorStmt(C)->getSourceRange();
4679f4a2713aSLionel Sambuc 
4680f4a2713aSLionel Sambuc   if (clang_isAttribute(C.kind))
4681f4a2713aSLionel Sambuc     return getCursorAttr(C)->getRange();
4682f4a2713aSLionel Sambuc 
4683f4a2713aSLionel Sambuc   if (C.kind == CXCursor_PreprocessingDirective)
4684f4a2713aSLionel Sambuc     return cxcursor::getCursorPreprocessingDirective(C);
4685f4a2713aSLionel Sambuc 
4686f4a2713aSLionel Sambuc   if (C.kind == CXCursor_MacroExpansion) {
4687f4a2713aSLionel Sambuc     ASTUnit *TU = getCursorASTUnit(C);
4688f4a2713aSLionel Sambuc     SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
4689f4a2713aSLionel Sambuc     return TU->mapRangeFromPreamble(Range);
4690f4a2713aSLionel Sambuc   }
4691f4a2713aSLionel Sambuc 
4692f4a2713aSLionel Sambuc   if (C.kind == CXCursor_MacroDefinition) {
4693f4a2713aSLionel Sambuc     ASTUnit *TU = getCursorASTUnit(C);
4694f4a2713aSLionel Sambuc     SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4695f4a2713aSLionel Sambuc     return TU->mapRangeFromPreamble(Range);
4696f4a2713aSLionel Sambuc   }
4697f4a2713aSLionel Sambuc 
4698f4a2713aSLionel Sambuc   if (C.kind == CXCursor_InclusionDirective) {
4699f4a2713aSLionel Sambuc     ASTUnit *TU = getCursorASTUnit(C);
4700f4a2713aSLionel Sambuc     SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4701f4a2713aSLionel Sambuc     return TU->mapRangeFromPreamble(Range);
4702f4a2713aSLionel Sambuc   }
4703f4a2713aSLionel Sambuc 
4704f4a2713aSLionel Sambuc   if (C.kind == CXCursor_TranslationUnit) {
4705f4a2713aSLionel Sambuc     ASTUnit *TU = getCursorASTUnit(C);
4706f4a2713aSLionel Sambuc     FileID MainID = TU->getSourceManager().getMainFileID();
4707f4a2713aSLionel Sambuc     SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4708f4a2713aSLionel Sambuc     SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4709f4a2713aSLionel Sambuc     return SourceRange(Start, End);
4710f4a2713aSLionel Sambuc   }
4711f4a2713aSLionel Sambuc 
4712f4a2713aSLionel Sambuc   if (clang_isDeclaration(C.kind)) {
4713f4a2713aSLionel Sambuc     const Decl *D = cxcursor::getCursorDecl(C);
4714f4a2713aSLionel Sambuc     if (!D)
4715f4a2713aSLionel Sambuc       return SourceRange();
4716f4a2713aSLionel Sambuc 
4717f4a2713aSLionel Sambuc     SourceRange R = D->getSourceRange();
4718f4a2713aSLionel Sambuc     // FIXME: Multiple variables declared in a single declaration
4719f4a2713aSLionel Sambuc     // currently lack the information needed to correctly determine their
4720f4a2713aSLionel Sambuc     // ranges when accounting for the type-specifier.  We use context
4721f4a2713aSLionel Sambuc     // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4722f4a2713aSLionel Sambuc     // and if so, whether it is the first decl.
4723f4a2713aSLionel Sambuc     if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
4724f4a2713aSLionel Sambuc       if (!cxcursor::isFirstInDeclGroup(C))
4725f4a2713aSLionel Sambuc         R.setBegin(VD->getLocation());
4726f4a2713aSLionel Sambuc     }
4727f4a2713aSLionel Sambuc     return R;
4728f4a2713aSLionel Sambuc   }
4729f4a2713aSLionel Sambuc   return SourceRange();
4730f4a2713aSLionel Sambuc }
4731f4a2713aSLionel Sambuc 
4732f4a2713aSLionel Sambuc /// \brief Retrieves the "raw" cursor extent, which is then extended to include
4733f4a2713aSLionel Sambuc /// the decl-specifier-seq for declarations.
getFullCursorExtent(CXCursor C,SourceManager & SrcMgr)4734f4a2713aSLionel Sambuc static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4735f4a2713aSLionel Sambuc   if (clang_isDeclaration(C.kind)) {
4736f4a2713aSLionel Sambuc     const Decl *D = cxcursor::getCursorDecl(C);
4737f4a2713aSLionel Sambuc     if (!D)
4738f4a2713aSLionel Sambuc       return SourceRange();
4739f4a2713aSLionel Sambuc 
4740f4a2713aSLionel Sambuc     SourceRange R = D->getSourceRange();
4741f4a2713aSLionel Sambuc 
4742f4a2713aSLionel Sambuc     // Adjust the start of the location for declarations preceded by
4743f4a2713aSLionel Sambuc     // declaration specifiers.
4744f4a2713aSLionel Sambuc     SourceLocation StartLoc;
4745f4a2713aSLionel Sambuc     if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4746f4a2713aSLionel Sambuc       if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4747f4a2713aSLionel Sambuc         StartLoc = TI->getTypeLoc().getLocStart();
4748f4a2713aSLionel Sambuc     } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
4749f4a2713aSLionel Sambuc       if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4750f4a2713aSLionel Sambuc         StartLoc = TI->getTypeLoc().getLocStart();
4751f4a2713aSLionel Sambuc     }
4752f4a2713aSLionel Sambuc 
4753f4a2713aSLionel Sambuc     if (StartLoc.isValid() && R.getBegin().isValid() &&
4754f4a2713aSLionel Sambuc         SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4755f4a2713aSLionel Sambuc       R.setBegin(StartLoc);
4756f4a2713aSLionel Sambuc 
4757f4a2713aSLionel Sambuc     // FIXME: Multiple variables declared in a single declaration
4758f4a2713aSLionel Sambuc     // currently lack the information needed to correctly determine their
4759f4a2713aSLionel Sambuc     // ranges when accounting for the type-specifier.  We use context
4760f4a2713aSLionel Sambuc     // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4761f4a2713aSLionel Sambuc     // and if so, whether it is the first decl.
4762f4a2713aSLionel Sambuc     if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
4763f4a2713aSLionel Sambuc       if (!cxcursor::isFirstInDeclGroup(C))
4764f4a2713aSLionel Sambuc         R.setBegin(VD->getLocation());
4765f4a2713aSLionel Sambuc     }
4766f4a2713aSLionel Sambuc 
4767f4a2713aSLionel Sambuc     return R;
4768f4a2713aSLionel Sambuc   }
4769f4a2713aSLionel Sambuc 
4770f4a2713aSLionel Sambuc   return getRawCursorExtent(C);
4771f4a2713aSLionel Sambuc }
4772f4a2713aSLionel Sambuc 
4773f4a2713aSLionel Sambuc extern "C" {
4774f4a2713aSLionel Sambuc 
clang_getCursorExtent(CXCursor C)4775f4a2713aSLionel Sambuc CXSourceRange clang_getCursorExtent(CXCursor C) {
4776f4a2713aSLionel Sambuc   SourceRange R = getRawCursorExtent(C);
4777f4a2713aSLionel Sambuc   if (R.isInvalid())
4778f4a2713aSLionel Sambuc     return clang_getNullRange();
4779f4a2713aSLionel Sambuc 
4780f4a2713aSLionel Sambuc   return cxloc::translateSourceRange(getCursorContext(C), R);
4781f4a2713aSLionel Sambuc }
4782f4a2713aSLionel Sambuc 
clang_getCursorReferenced(CXCursor C)4783f4a2713aSLionel Sambuc CXCursor clang_getCursorReferenced(CXCursor C) {
4784f4a2713aSLionel Sambuc   if (clang_isInvalid(C.kind))
4785f4a2713aSLionel Sambuc     return clang_getNullCursor();
4786f4a2713aSLionel Sambuc 
4787f4a2713aSLionel Sambuc   CXTranslationUnit tu = getCursorTU(C);
4788f4a2713aSLionel Sambuc   if (clang_isDeclaration(C.kind)) {
4789f4a2713aSLionel Sambuc     const Decl *D = getCursorDecl(C);
4790f4a2713aSLionel Sambuc     if (!D)
4791f4a2713aSLionel Sambuc       return clang_getNullCursor();
4792f4a2713aSLionel Sambuc     if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
4793f4a2713aSLionel Sambuc       return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
4794f4a2713aSLionel Sambuc     if (const ObjCPropertyImplDecl *PropImpl =
4795f4a2713aSLionel Sambuc             dyn_cast<ObjCPropertyImplDecl>(D))
4796f4a2713aSLionel Sambuc       if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4797f4a2713aSLionel Sambuc         return MakeCXCursor(Property, tu);
4798f4a2713aSLionel Sambuc 
4799f4a2713aSLionel Sambuc     return C;
4800f4a2713aSLionel Sambuc   }
4801f4a2713aSLionel Sambuc 
4802f4a2713aSLionel Sambuc   if (clang_isExpression(C.kind)) {
4803f4a2713aSLionel Sambuc     const Expr *E = getCursorExpr(C);
4804f4a2713aSLionel Sambuc     const Decl *D = getDeclFromExpr(E);
4805f4a2713aSLionel Sambuc     if (D) {
4806f4a2713aSLionel Sambuc       CXCursor declCursor = MakeCXCursor(D, tu);
4807f4a2713aSLionel Sambuc       declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4808f4a2713aSLionel Sambuc                                                declCursor);
4809f4a2713aSLionel Sambuc       return declCursor;
4810f4a2713aSLionel Sambuc     }
4811f4a2713aSLionel Sambuc 
4812f4a2713aSLionel Sambuc     if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
4813f4a2713aSLionel Sambuc       return MakeCursorOverloadedDeclRef(Ovl, tu);
4814f4a2713aSLionel Sambuc 
4815f4a2713aSLionel Sambuc     return clang_getNullCursor();
4816f4a2713aSLionel Sambuc   }
4817f4a2713aSLionel Sambuc 
4818f4a2713aSLionel Sambuc   if (clang_isStatement(C.kind)) {
4819f4a2713aSLionel Sambuc     const Stmt *S = getCursorStmt(C);
4820f4a2713aSLionel Sambuc     if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
4821f4a2713aSLionel Sambuc       if (LabelDecl *label = Goto->getLabel())
4822f4a2713aSLionel Sambuc         if (LabelStmt *labelS = label->getStmt())
4823f4a2713aSLionel Sambuc         return MakeCXCursor(labelS, getCursorDecl(C), tu);
4824f4a2713aSLionel Sambuc 
4825f4a2713aSLionel Sambuc     return clang_getNullCursor();
4826f4a2713aSLionel Sambuc   }
4827f4a2713aSLionel Sambuc 
4828f4a2713aSLionel Sambuc   if (C.kind == CXCursor_MacroExpansion) {
4829f4a2713aSLionel Sambuc     if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
4830f4a2713aSLionel Sambuc       return MakeMacroDefinitionCursor(Def, tu);
4831f4a2713aSLionel Sambuc   }
4832f4a2713aSLionel Sambuc 
4833f4a2713aSLionel Sambuc   if (!clang_isReference(C.kind))
4834f4a2713aSLionel Sambuc     return clang_getNullCursor();
4835f4a2713aSLionel Sambuc 
4836f4a2713aSLionel Sambuc   switch (C.kind) {
4837f4a2713aSLionel Sambuc     case CXCursor_ObjCSuperClassRef:
4838f4a2713aSLionel Sambuc       return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4839f4a2713aSLionel Sambuc 
4840f4a2713aSLionel Sambuc     case CXCursor_ObjCProtocolRef: {
4841f4a2713aSLionel Sambuc       const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4842f4a2713aSLionel Sambuc       if (const ObjCProtocolDecl *Def = Prot->getDefinition())
4843f4a2713aSLionel Sambuc         return MakeCXCursor(Def, tu);
4844f4a2713aSLionel Sambuc 
4845f4a2713aSLionel Sambuc       return MakeCXCursor(Prot, tu);
4846f4a2713aSLionel Sambuc     }
4847f4a2713aSLionel Sambuc 
4848f4a2713aSLionel Sambuc     case CXCursor_ObjCClassRef: {
4849f4a2713aSLionel Sambuc       const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4850f4a2713aSLionel Sambuc       if (const ObjCInterfaceDecl *Def = Class->getDefinition())
4851f4a2713aSLionel Sambuc         return MakeCXCursor(Def, tu);
4852f4a2713aSLionel Sambuc 
4853f4a2713aSLionel Sambuc       return MakeCXCursor(Class, tu);
4854f4a2713aSLionel Sambuc     }
4855f4a2713aSLionel Sambuc 
4856f4a2713aSLionel Sambuc     case CXCursor_TypeRef:
4857f4a2713aSLionel Sambuc       return MakeCXCursor(getCursorTypeRef(C).first, tu );
4858f4a2713aSLionel Sambuc 
4859f4a2713aSLionel Sambuc     case CXCursor_TemplateRef:
4860f4a2713aSLionel Sambuc       return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4861f4a2713aSLionel Sambuc 
4862f4a2713aSLionel Sambuc     case CXCursor_NamespaceRef:
4863f4a2713aSLionel Sambuc       return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4864f4a2713aSLionel Sambuc 
4865f4a2713aSLionel Sambuc     case CXCursor_MemberRef:
4866f4a2713aSLionel Sambuc       return MakeCXCursor(getCursorMemberRef(C).first, tu );
4867f4a2713aSLionel Sambuc 
4868f4a2713aSLionel Sambuc     case CXCursor_CXXBaseSpecifier: {
4869f4a2713aSLionel Sambuc       const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
4870f4a2713aSLionel Sambuc       return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4871f4a2713aSLionel Sambuc                                                          tu ));
4872f4a2713aSLionel Sambuc     }
4873f4a2713aSLionel Sambuc 
4874f4a2713aSLionel Sambuc     case CXCursor_LabelRef:
4875f4a2713aSLionel Sambuc       // FIXME: We end up faking the "parent" declaration here because we
4876f4a2713aSLionel Sambuc       // don't want to make CXCursor larger.
4877f4a2713aSLionel Sambuc       return MakeCXCursor(getCursorLabelRef(C).first,
4878f4a2713aSLionel Sambuc                           cxtu::getASTUnit(tu)->getASTContext()
4879f4a2713aSLionel Sambuc                               .getTranslationUnitDecl(),
4880f4a2713aSLionel Sambuc                           tu);
4881f4a2713aSLionel Sambuc 
4882f4a2713aSLionel Sambuc     case CXCursor_OverloadedDeclRef:
4883f4a2713aSLionel Sambuc       return C;
4884f4a2713aSLionel Sambuc 
4885f4a2713aSLionel Sambuc     case CXCursor_VariableRef:
4886f4a2713aSLionel Sambuc       return MakeCXCursor(getCursorVariableRef(C).first, tu);
4887f4a2713aSLionel Sambuc 
4888f4a2713aSLionel Sambuc     default:
4889f4a2713aSLionel Sambuc       // We would prefer to enumerate all non-reference cursor kinds here.
4890f4a2713aSLionel Sambuc       llvm_unreachable("Unhandled reference cursor kind");
4891f4a2713aSLionel Sambuc   }
4892f4a2713aSLionel Sambuc }
4893f4a2713aSLionel Sambuc 
clang_getCursorDefinition(CXCursor C)4894f4a2713aSLionel Sambuc CXCursor clang_getCursorDefinition(CXCursor C) {
4895f4a2713aSLionel Sambuc   if (clang_isInvalid(C.kind))
4896f4a2713aSLionel Sambuc     return clang_getNullCursor();
4897f4a2713aSLionel Sambuc 
4898f4a2713aSLionel Sambuc   CXTranslationUnit TU = getCursorTU(C);
4899f4a2713aSLionel Sambuc 
4900f4a2713aSLionel Sambuc   bool WasReference = false;
4901f4a2713aSLionel Sambuc   if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4902f4a2713aSLionel Sambuc     C = clang_getCursorReferenced(C);
4903f4a2713aSLionel Sambuc     WasReference = true;
4904f4a2713aSLionel Sambuc   }
4905f4a2713aSLionel Sambuc 
4906f4a2713aSLionel Sambuc   if (C.kind == CXCursor_MacroExpansion)
4907f4a2713aSLionel Sambuc     return clang_getCursorReferenced(C);
4908f4a2713aSLionel Sambuc 
4909f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
4910f4a2713aSLionel Sambuc     return clang_getNullCursor();
4911f4a2713aSLionel Sambuc 
4912f4a2713aSLionel Sambuc   const Decl *D = getCursorDecl(C);
4913f4a2713aSLionel Sambuc   if (!D)
4914f4a2713aSLionel Sambuc     return clang_getNullCursor();
4915f4a2713aSLionel Sambuc 
4916f4a2713aSLionel Sambuc   switch (D->getKind()) {
4917f4a2713aSLionel Sambuc   // Declaration kinds that don't really separate the notions of
4918f4a2713aSLionel Sambuc   // declaration and definition.
4919f4a2713aSLionel Sambuc   case Decl::Namespace:
4920f4a2713aSLionel Sambuc   case Decl::Typedef:
4921f4a2713aSLionel Sambuc   case Decl::TypeAlias:
4922f4a2713aSLionel Sambuc   case Decl::TypeAliasTemplate:
4923f4a2713aSLionel Sambuc   case Decl::TemplateTypeParm:
4924f4a2713aSLionel Sambuc   case Decl::EnumConstant:
4925f4a2713aSLionel Sambuc   case Decl::Field:
4926f4a2713aSLionel Sambuc   case Decl::MSProperty:
4927f4a2713aSLionel Sambuc   case Decl::IndirectField:
4928f4a2713aSLionel Sambuc   case Decl::ObjCIvar:
4929f4a2713aSLionel Sambuc   case Decl::ObjCAtDefsField:
4930f4a2713aSLionel Sambuc   case Decl::ImplicitParam:
4931f4a2713aSLionel Sambuc   case Decl::ParmVar:
4932f4a2713aSLionel Sambuc   case Decl::NonTypeTemplateParm:
4933f4a2713aSLionel Sambuc   case Decl::TemplateTemplateParm:
4934f4a2713aSLionel Sambuc   case Decl::ObjCCategoryImpl:
4935f4a2713aSLionel Sambuc   case Decl::ObjCImplementation:
4936f4a2713aSLionel Sambuc   case Decl::AccessSpec:
4937f4a2713aSLionel Sambuc   case Decl::LinkageSpec:
4938f4a2713aSLionel Sambuc   case Decl::ObjCPropertyImpl:
4939f4a2713aSLionel Sambuc   case Decl::FileScopeAsm:
4940f4a2713aSLionel Sambuc   case Decl::StaticAssert:
4941f4a2713aSLionel Sambuc   case Decl::Block:
4942f4a2713aSLionel Sambuc   case Decl::Captured:
4943f4a2713aSLionel Sambuc   case Decl::Label:  // FIXME: Is this right??
4944f4a2713aSLionel Sambuc   case Decl::ClassScopeFunctionSpecialization:
4945f4a2713aSLionel Sambuc   case Decl::Import:
4946f4a2713aSLionel Sambuc   case Decl::OMPThreadPrivate:
4947f4a2713aSLionel Sambuc     return C;
4948f4a2713aSLionel Sambuc 
4949f4a2713aSLionel Sambuc   // Declaration kinds that don't make any sense here, but are
4950f4a2713aSLionel Sambuc   // nonetheless harmless.
4951f4a2713aSLionel Sambuc   case Decl::Empty:
4952f4a2713aSLionel Sambuc   case Decl::TranslationUnit:
4953f4a2713aSLionel Sambuc     break;
4954f4a2713aSLionel Sambuc 
4955f4a2713aSLionel Sambuc   // Declaration kinds for which the definition is not resolvable.
4956f4a2713aSLionel Sambuc   case Decl::UnresolvedUsingTypename:
4957f4a2713aSLionel Sambuc   case Decl::UnresolvedUsingValue:
4958f4a2713aSLionel Sambuc     break;
4959f4a2713aSLionel Sambuc 
4960f4a2713aSLionel Sambuc   case Decl::UsingDirective:
4961f4a2713aSLionel Sambuc     return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4962f4a2713aSLionel Sambuc                         TU);
4963f4a2713aSLionel Sambuc 
4964f4a2713aSLionel Sambuc   case Decl::NamespaceAlias:
4965f4a2713aSLionel Sambuc     return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4966f4a2713aSLionel Sambuc 
4967f4a2713aSLionel Sambuc   case Decl::Enum:
4968f4a2713aSLionel Sambuc   case Decl::Record:
4969f4a2713aSLionel Sambuc   case Decl::CXXRecord:
4970f4a2713aSLionel Sambuc   case Decl::ClassTemplateSpecialization:
4971f4a2713aSLionel Sambuc   case Decl::ClassTemplatePartialSpecialization:
4972f4a2713aSLionel Sambuc     if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4973f4a2713aSLionel Sambuc       return MakeCXCursor(Def, TU);
4974f4a2713aSLionel Sambuc     return clang_getNullCursor();
4975f4a2713aSLionel Sambuc 
4976f4a2713aSLionel Sambuc   case Decl::Function:
4977f4a2713aSLionel Sambuc   case Decl::CXXMethod:
4978f4a2713aSLionel Sambuc   case Decl::CXXConstructor:
4979f4a2713aSLionel Sambuc   case Decl::CXXDestructor:
4980f4a2713aSLionel Sambuc   case Decl::CXXConversion: {
4981*0a6a1f1dSLionel Sambuc     const FunctionDecl *Def = nullptr;
4982f4a2713aSLionel Sambuc     if (cast<FunctionDecl>(D)->getBody(Def))
4983f4a2713aSLionel Sambuc       return MakeCXCursor(Def, TU);
4984f4a2713aSLionel Sambuc     return clang_getNullCursor();
4985f4a2713aSLionel Sambuc   }
4986f4a2713aSLionel Sambuc 
4987f4a2713aSLionel Sambuc   case Decl::Var:
4988f4a2713aSLionel Sambuc   case Decl::VarTemplateSpecialization:
4989f4a2713aSLionel Sambuc   case Decl::VarTemplatePartialSpecialization: {
4990f4a2713aSLionel Sambuc     // Ask the variable if it has a definition.
4991f4a2713aSLionel Sambuc     if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
4992f4a2713aSLionel Sambuc       return MakeCXCursor(Def, TU);
4993f4a2713aSLionel Sambuc     return clang_getNullCursor();
4994f4a2713aSLionel Sambuc   }
4995f4a2713aSLionel Sambuc 
4996f4a2713aSLionel Sambuc   case Decl::FunctionTemplate: {
4997*0a6a1f1dSLionel Sambuc     const FunctionDecl *Def = nullptr;
4998f4a2713aSLionel Sambuc     if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4999f4a2713aSLionel Sambuc       return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5000f4a2713aSLionel Sambuc     return clang_getNullCursor();
5001f4a2713aSLionel Sambuc   }
5002f4a2713aSLionel Sambuc 
5003f4a2713aSLionel Sambuc   case Decl::ClassTemplate: {
5004f4a2713aSLionel Sambuc     if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5005f4a2713aSLionel Sambuc                                                             ->getDefinition())
5006f4a2713aSLionel Sambuc       return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5007f4a2713aSLionel Sambuc                           TU);
5008f4a2713aSLionel Sambuc     return clang_getNullCursor();
5009f4a2713aSLionel Sambuc   }
5010f4a2713aSLionel Sambuc 
5011f4a2713aSLionel Sambuc   case Decl::VarTemplate: {
5012f4a2713aSLionel Sambuc     if (VarDecl *Def =
5013f4a2713aSLionel Sambuc             cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5014f4a2713aSLionel Sambuc       return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5015f4a2713aSLionel Sambuc     return clang_getNullCursor();
5016f4a2713aSLionel Sambuc   }
5017f4a2713aSLionel Sambuc 
5018f4a2713aSLionel Sambuc   case Decl::Using:
5019f4a2713aSLionel Sambuc     return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5020f4a2713aSLionel Sambuc                                        D->getLocation(), TU);
5021f4a2713aSLionel Sambuc 
5022f4a2713aSLionel Sambuc   case Decl::UsingShadow:
5023f4a2713aSLionel Sambuc     return clang_getCursorDefinition(
5024f4a2713aSLionel Sambuc                        MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5025f4a2713aSLionel Sambuc                                     TU));
5026f4a2713aSLionel Sambuc 
5027f4a2713aSLionel Sambuc   case Decl::ObjCMethod: {
5028f4a2713aSLionel Sambuc     const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
5029f4a2713aSLionel Sambuc     if (Method->isThisDeclarationADefinition())
5030f4a2713aSLionel Sambuc       return C;
5031f4a2713aSLionel Sambuc 
5032f4a2713aSLionel Sambuc     // Dig out the method definition in the associated
5033f4a2713aSLionel Sambuc     // @implementation, if we have it.
5034f4a2713aSLionel Sambuc     // FIXME: The ASTs should make finding the definition easier.
5035f4a2713aSLionel Sambuc     if (const ObjCInterfaceDecl *Class
5036f4a2713aSLionel Sambuc                        = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5037f4a2713aSLionel Sambuc       if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5038f4a2713aSLionel Sambuc         if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5039f4a2713aSLionel Sambuc                                                   Method->isInstanceMethod()))
5040f4a2713aSLionel Sambuc           if (Def->isThisDeclarationADefinition())
5041f4a2713aSLionel Sambuc             return MakeCXCursor(Def, TU);
5042f4a2713aSLionel Sambuc 
5043f4a2713aSLionel Sambuc     return clang_getNullCursor();
5044f4a2713aSLionel Sambuc   }
5045f4a2713aSLionel Sambuc 
5046f4a2713aSLionel Sambuc   case Decl::ObjCCategory:
5047f4a2713aSLionel Sambuc     if (ObjCCategoryImplDecl *Impl
5048f4a2713aSLionel Sambuc                                = cast<ObjCCategoryDecl>(D)->getImplementation())
5049f4a2713aSLionel Sambuc       return MakeCXCursor(Impl, TU);
5050f4a2713aSLionel Sambuc     return clang_getNullCursor();
5051f4a2713aSLionel Sambuc 
5052f4a2713aSLionel Sambuc   case Decl::ObjCProtocol:
5053f4a2713aSLionel Sambuc     if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
5054f4a2713aSLionel Sambuc       return MakeCXCursor(Def, TU);
5055f4a2713aSLionel Sambuc     return clang_getNullCursor();
5056f4a2713aSLionel Sambuc 
5057f4a2713aSLionel Sambuc   case Decl::ObjCInterface: {
5058f4a2713aSLionel Sambuc     // There are two notions of a "definition" for an Objective-C
5059f4a2713aSLionel Sambuc     // class: the interface and its implementation. When we resolved a
5060f4a2713aSLionel Sambuc     // reference to an Objective-C class, produce the @interface as
5061f4a2713aSLionel Sambuc     // the definition; when we were provided with the interface,
5062f4a2713aSLionel Sambuc     // produce the @implementation as the definition.
5063f4a2713aSLionel Sambuc     const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
5064f4a2713aSLionel Sambuc     if (WasReference) {
5065f4a2713aSLionel Sambuc       if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
5066f4a2713aSLionel Sambuc         return MakeCXCursor(Def, TU);
5067f4a2713aSLionel Sambuc     } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5068f4a2713aSLionel Sambuc       return MakeCXCursor(Impl, TU);
5069f4a2713aSLionel Sambuc     return clang_getNullCursor();
5070f4a2713aSLionel Sambuc   }
5071f4a2713aSLionel Sambuc 
5072f4a2713aSLionel Sambuc   case Decl::ObjCProperty:
5073f4a2713aSLionel Sambuc     // FIXME: We don't really know where to find the
5074f4a2713aSLionel Sambuc     // ObjCPropertyImplDecls that implement this property.
5075f4a2713aSLionel Sambuc     return clang_getNullCursor();
5076f4a2713aSLionel Sambuc 
5077f4a2713aSLionel Sambuc   case Decl::ObjCCompatibleAlias:
5078f4a2713aSLionel Sambuc     if (const ObjCInterfaceDecl *Class
5079f4a2713aSLionel Sambuc           = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
5080f4a2713aSLionel Sambuc       if (const ObjCInterfaceDecl *Def = Class->getDefinition())
5081f4a2713aSLionel Sambuc         return MakeCXCursor(Def, TU);
5082f4a2713aSLionel Sambuc 
5083f4a2713aSLionel Sambuc     return clang_getNullCursor();
5084f4a2713aSLionel Sambuc 
5085f4a2713aSLionel Sambuc   case Decl::Friend:
5086f4a2713aSLionel Sambuc     if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5087f4a2713aSLionel Sambuc       return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5088f4a2713aSLionel Sambuc     return clang_getNullCursor();
5089f4a2713aSLionel Sambuc 
5090f4a2713aSLionel Sambuc   case Decl::FriendTemplate:
5091f4a2713aSLionel Sambuc     if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5092f4a2713aSLionel Sambuc       return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5093f4a2713aSLionel Sambuc     return clang_getNullCursor();
5094f4a2713aSLionel Sambuc   }
5095f4a2713aSLionel Sambuc 
5096f4a2713aSLionel Sambuc   return clang_getNullCursor();
5097f4a2713aSLionel Sambuc }
5098f4a2713aSLionel Sambuc 
clang_isCursorDefinition(CXCursor C)5099f4a2713aSLionel Sambuc unsigned clang_isCursorDefinition(CXCursor C) {
5100f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
5101f4a2713aSLionel Sambuc     return 0;
5102f4a2713aSLionel Sambuc 
5103f4a2713aSLionel Sambuc   return clang_getCursorDefinition(C) == C;
5104f4a2713aSLionel Sambuc }
5105f4a2713aSLionel Sambuc 
clang_getCanonicalCursor(CXCursor C)5106f4a2713aSLionel Sambuc CXCursor clang_getCanonicalCursor(CXCursor C) {
5107f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
5108f4a2713aSLionel Sambuc     return C;
5109f4a2713aSLionel Sambuc 
5110f4a2713aSLionel Sambuc   if (const Decl *D = getCursorDecl(C)) {
5111f4a2713aSLionel Sambuc     if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
5112f4a2713aSLionel Sambuc       if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5113f4a2713aSLionel Sambuc         return MakeCXCursor(CatD, getCursorTU(C));
5114f4a2713aSLionel Sambuc 
5115f4a2713aSLionel Sambuc     if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5116f4a2713aSLionel Sambuc       if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
5117f4a2713aSLionel Sambuc         return MakeCXCursor(IFD, getCursorTU(C));
5118f4a2713aSLionel Sambuc 
5119f4a2713aSLionel Sambuc     return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5120f4a2713aSLionel Sambuc   }
5121f4a2713aSLionel Sambuc 
5122f4a2713aSLionel Sambuc   return C;
5123f4a2713aSLionel Sambuc }
5124f4a2713aSLionel Sambuc 
clang_Cursor_getObjCSelectorIndex(CXCursor cursor)5125f4a2713aSLionel Sambuc int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5126f4a2713aSLionel Sambuc   return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5127f4a2713aSLionel Sambuc }
5128f4a2713aSLionel Sambuc 
clang_getNumOverloadedDecls(CXCursor C)5129f4a2713aSLionel Sambuc unsigned clang_getNumOverloadedDecls(CXCursor C) {
5130f4a2713aSLionel Sambuc   if (C.kind != CXCursor_OverloadedDeclRef)
5131f4a2713aSLionel Sambuc     return 0;
5132f4a2713aSLionel Sambuc 
5133f4a2713aSLionel Sambuc   OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
5134f4a2713aSLionel Sambuc   if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
5135f4a2713aSLionel Sambuc     return E->getNumDecls();
5136f4a2713aSLionel Sambuc 
5137f4a2713aSLionel Sambuc   if (OverloadedTemplateStorage *S
5138f4a2713aSLionel Sambuc                               = Storage.dyn_cast<OverloadedTemplateStorage*>())
5139f4a2713aSLionel Sambuc     return S->size();
5140f4a2713aSLionel Sambuc 
5141f4a2713aSLionel Sambuc   const Decl *D = Storage.get<const Decl *>();
5142f4a2713aSLionel Sambuc   if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
5143f4a2713aSLionel Sambuc     return Using->shadow_size();
5144f4a2713aSLionel Sambuc 
5145f4a2713aSLionel Sambuc   return 0;
5146f4a2713aSLionel Sambuc }
5147f4a2713aSLionel Sambuc 
clang_getOverloadedDecl(CXCursor cursor,unsigned index)5148f4a2713aSLionel Sambuc CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5149f4a2713aSLionel Sambuc   if (cursor.kind != CXCursor_OverloadedDeclRef)
5150f4a2713aSLionel Sambuc     return clang_getNullCursor();
5151f4a2713aSLionel Sambuc 
5152f4a2713aSLionel Sambuc   if (index >= clang_getNumOverloadedDecls(cursor))
5153f4a2713aSLionel Sambuc     return clang_getNullCursor();
5154f4a2713aSLionel Sambuc 
5155f4a2713aSLionel Sambuc   CXTranslationUnit TU = getCursorTU(cursor);
5156f4a2713aSLionel Sambuc   OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
5157f4a2713aSLionel Sambuc   if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
5158f4a2713aSLionel Sambuc     return MakeCXCursor(E->decls_begin()[index], TU);
5159f4a2713aSLionel Sambuc 
5160f4a2713aSLionel Sambuc   if (OverloadedTemplateStorage *S
5161f4a2713aSLionel Sambuc                               = Storage.dyn_cast<OverloadedTemplateStorage*>())
5162f4a2713aSLionel Sambuc     return MakeCXCursor(S->begin()[index], TU);
5163f4a2713aSLionel Sambuc 
5164f4a2713aSLionel Sambuc   const Decl *D = Storage.get<const Decl *>();
5165f4a2713aSLionel Sambuc   if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
5166f4a2713aSLionel Sambuc     // FIXME: This is, unfortunately, linear time.
5167f4a2713aSLionel Sambuc     UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5168f4a2713aSLionel Sambuc     std::advance(Pos, index);
5169f4a2713aSLionel Sambuc     return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5170f4a2713aSLionel Sambuc   }
5171f4a2713aSLionel Sambuc 
5172f4a2713aSLionel Sambuc   return clang_getNullCursor();
5173f4a2713aSLionel Sambuc }
5174f4a2713aSLionel Sambuc 
clang_getDefinitionSpellingAndExtent(CXCursor C,const char ** startBuf,const char ** endBuf,unsigned * startLine,unsigned * startColumn,unsigned * endLine,unsigned * endColumn)5175f4a2713aSLionel Sambuc void clang_getDefinitionSpellingAndExtent(CXCursor C,
5176f4a2713aSLionel Sambuc                                           const char **startBuf,
5177f4a2713aSLionel Sambuc                                           const char **endBuf,
5178f4a2713aSLionel Sambuc                                           unsigned *startLine,
5179f4a2713aSLionel Sambuc                                           unsigned *startColumn,
5180f4a2713aSLionel Sambuc                                           unsigned *endLine,
5181f4a2713aSLionel Sambuc                                           unsigned *endColumn) {
5182f4a2713aSLionel Sambuc   assert(getCursorDecl(C) && "CXCursor has null decl");
5183f4a2713aSLionel Sambuc   const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
5184f4a2713aSLionel Sambuc   CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5185f4a2713aSLionel Sambuc 
5186f4a2713aSLionel Sambuc   SourceManager &SM = FD->getASTContext().getSourceManager();
5187f4a2713aSLionel Sambuc   *startBuf = SM.getCharacterData(Body->getLBracLoc());
5188f4a2713aSLionel Sambuc   *endBuf = SM.getCharacterData(Body->getRBracLoc());
5189f4a2713aSLionel Sambuc   *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5190f4a2713aSLionel Sambuc   *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5191f4a2713aSLionel Sambuc   *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5192f4a2713aSLionel Sambuc   *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5193f4a2713aSLionel Sambuc }
5194f4a2713aSLionel Sambuc 
5195f4a2713aSLionel Sambuc 
clang_getCursorReferenceNameRange(CXCursor C,unsigned NameFlags,unsigned PieceIndex)5196f4a2713aSLionel Sambuc CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5197f4a2713aSLionel Sambuc                                                 unsigned PieceIndex) {
5198f4a2713aSLionel Sambuc   RefNamePieces Pieces;
5199f4a2713aSLionel Sambuc 
5200f4a2713aSLionel Sambuc   switch (C.kind) {
5201f4a2713aSLionel Sambuc   case CXCursor_MemberRefExpr:
5202f4a2713aSLionel Sambuc     if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
5203f4a2713aSLionel Sambuc       Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5204f4a2713aSLionel Sambuc                            E->getQualifierLoc().getSourceRange());
5205f4a2713aSLionel Sambuc     break;
5206f4a2713aSLionel Sambuc 
5207f4a2713aSLionel Sambuc   case CXCursor_DeclRefExpr:
5208f4a2713aSLionel Sambuc     if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
5209f4a2713aSLionel Sambuc       Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5210f4a2713aSLionel Sambuc                            E->getQualifierLoc().getSourceRange(),
5211f4a2713aSLionel Sambuc                            E->getOptionalExplicitTemplateArgs());
5212f4a2713aSLionel Sambuc     break;
5213f4a2713aSLionel Sambuc 
5214f4a2713aSLionel Sambuc   case CXCursor_CallExpr:
5215f4a2713aSLionel Sambuc     if (const CXXOperatorCallExpr *OCE =
5216f4a2713aSLionel Sambuc         dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
5217f4a2713aSLionel Sambuc       const Expr *Callee = OCE->getCallee();
5218f4a2713aSLionel Sambuc       if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
5219f4a2713aSLionel Sambuc         Callee = ICE->getSubExpr();
5220f4a2713aSLionel Sambuc 
5221f4a2713aSLionel Sambuc       if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
5222f4a2713aSLionel Sambuc         Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5223f4a2713aSLionel Sambuc                              DRE->getQualifierLoc().getSourceRange());
5224f4a2713aSLionel Sambuc     }
5225f4a2713aSLionel Sambuc     break;
5226f4a2713aSLionel Sambuc 
5227f4a2713aSLionel Sambuc   default:
5228f4a2713aSLionel Sambuc     break;
5229f4a2713aSLionel Sambuc   }
5230f4a2713aSLionel Sambuc 
5231f4a2713aSLionel Sambuc   if (Pieces.empty()) {
5232f4a2713aSLionel Sambuc     if (PieceIndex == 0)
5233f4a2713aSLionel Sambuc       return clang_getCursorExtent(C);
5234f4a2713aSLionel Sambuc   } else if (PieceIndex < Pieces.size()) {
5235f4a2713aSLionel Sambuc       SourceRange R = Pieces[PieceIndex];
5236f4a2713aSLionel Sambuc       if (R.isValid())
5237f4a2713aSLionel Sambuc         return cxloc::translateSourceRange(getCursorContext(C), R);
5238f4a2713aSLionel Sambuc   }
5239f4a2713aSLionel Sambuc 
5240f4a2713aSLionel Sambuc   return clang_getNullRange();
5241f4a2713aSLionel Sambuc }
5242f4a2713aSLionel Sambuc 
clang_enableStackTraces(void)5243f4a2713aSLionel Sambuc void clang_enableStackTraces(void) {
5244f4a2713aSLionel Sambuc   llvm::sys::PrintStackTraceOnErrorSignal();
5245f4a2713aSLionel Sambuc }
5246f4a2713aSLionel Sambuc 
clang_executeOnThread(void (* fn)(void *),void * user_data,unsigned stack_size)5247f4a2713aSLionel Sambuc void clang_executeOnThread(void (*fn)(void*), void *user_data,
5248f4a2713aSLionel Sambuc                            unsigned stack_size) {
5249f4a2713aSLionel Sambuc   llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5250f4a2713aSLionel Sambuc }
5251f4a2713aSLionel Sambuc 
5252f4a2713aSLionel Sambuc } // end: extern "C"
5253f4a2713aSLionel Sambuc 
5254f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
5255f4a2713aSLionel Sambuc // Token-based Operations.
5256f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
5257f4a2713aSLionel Sambuc 
5258f4a2713aSLionel Sambuc /* CXToken layout:
5259f4a2713aSLionel Sambuc  *   int_data[0]: a CXTokenKind
5260f4a2713aSLionel Sambuc  *   int_data[1]: starting token location
5261f4a2713aSLionel Sambuc  *   int_data[2]: token length
5262f4a2713aSLionel Sambuc  *   int_data[3]: reserved
5263f4a2713aSLionel Sambuc  *   ptr_data: for identifiers and keywords, an IdentifierInfo*.
5264f4a2713aSLionel Sambuc  *   otherwise unused.
5265f4a2713aSLionel Sambuc  */
5266f4a2713aSLionel Sambuc extern "C" {
5267f4a2713aSLionel Sambuc 
clang_getTokenKind(CXToken CXTok)5268f4a2713aSLionel Sambuc CXTokenKind clang_getTokenKind(CXToken CXTok) {
5269f4a2713aSLionel Sambuc   return static_cast<CXTokenKind>(CXTok.int_data[0]);
5270f4a2713aSLionel Sambuc }
5271f4a2713aSLionel Sambuc 
clang_getTokenSpelling(CXTranslationUnit TU,CXToken CXTok)5272f4a2713aSLionel Sambuc CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5273f4a2713aSLionel Sambuc   switch (clang_getTokenKind(CXTok)) {
5274f4a2713aSLionel Sambuc   case CXToken_Identifier:
5275f4a2713aSLionel Sambuc   case CXToken_Keyword:
5276f4a2713aSLionel Sambuc     // We know we have an IdentifierInfo*, so use that.
5277f4a2713aSLionel Sambuc     return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
5278f4a2713aSLionel Sambuc                             ->getNameStart());
5279f4a2713aSLionel Sambuc 
5280f4a2713aSLionel Sambuc   case CXToken_Literal: {
5281f4a2713aSLionel Sambuc     // We have stashed the starting pointer in the ptr_data field. Use it.
5282f4a2713aSLionel Sambuc     const char *Text = static_cast<const char *>(CXTok.ptr_data);
5283f4a2713aSLionel Sambuc     return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
5284f4a2713aSLionel Sambuc   }
5285f4a2713aSLionel Sambuc 
5286f4a2713aSLionel Sambuc   case CXToken_Punctuation:
5287f4a2713aSLionel Sambuc   case CXToken_Comment:
5288f4a2713aSLionel Sambuc     break;
5289f4a2713aSLionel Sambuc   }
5290f4a2713aSLionel Sambuc 
5291*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
5292*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
5293*0a6a1f1dSLionel Sambuc     return cxstring::createEmpty();
5294*0a6a1f1dSLionel Sambuc   }
5295*0a6a1f1dSLionel Sambuc 
5296f4a2713aSLionel Sambuc   // We have to find the starting buffer pointer the hard way, by
5297f4a2713aSLionel Sambuc   // deconstructing the source location.
5298f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5299f4a2713aSLionel Sambuc   if (!CXXUnit)
5300f4a2713aSLionel Sambuc     return cxstring::createEmpty();
5301f4a2713aSLionel Sambuc 
5302f4a2713aSLionel Sambuc   SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5303f4a2713aSLionel Sambuc   std::pair<FileID, unsigned> LocInfo
5304f4a2713aSLionel Sambuc     = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5305f4a2713aSLionel Sambuc   bool Invalid = false;
5306f4a2713aSLionel Sambuc   StringRef Buffer
5307f4a2713aSLionel Sambuc     = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5308f4a2713aSLionel Sambuc   if (Invalid)
5309f4a2713aSLionel Sambuc     return cxstring::createEmpty();
5310f4a2713aSLionel Sambuc 
5311f4a2713aSLionel Sambuc   return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
5312f4a2713aSLionel Sambuc }
5313f4a2713aSLionel Sambuc 
clang_getTokenLocation(CXTranslationUnit TU,CXToken CXTok)5314f4a2713aSLionel Sambuc CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
5315*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
5316*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
5317*0a6a1f1dSLionel Sambuc     return clang_getNullLocation();
5318*0a6a1f1dSLionel Sambuc   }
5319*0a6a1f1dSLionel Sambuc 
5320f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5321f4a2713aSLionel Sambuc   if (!CXXUnit)
5322f4a2713aSLionel Sambuc     return clang_getNullLocation();
5323f4a2713aSLionel Sambuc 
5324f4a2713aSLionel Sambuc   return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5325f4a2713aSLionel Sambuc                         SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5326f4a2713aSLionel Sambuc }
5327f4a2713aSLionel Sambuc 
clang_getTokenExtent(CXTranslationUnit TU,CXToken CXTok)5328f4a2713aSLionel Sambuc CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
5329*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
5330*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
5331*0a6a1f1dSLionel Sambuc     return clang_getNullRange();
5332*0a6a1f1dSLionel Sambuc   }
5333*0a6a1f1dSLionel Sambuc 
5334f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5335f4a2713aSLionel Sambuc   if (!CXXUnit)
5336f4a2713aSLionel Sambuc     return clang_getNullRange();
5337f4a2713aSLionel Sambuc 
5338f4a2713aSLionel Sambuc   return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5339f4a2713aSLionel Sambuc                         SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5340f4a2713aSLionel Sambuc }
5341f4a2713aSLionel Sambuc 
getTokens(ASTUnit * CXXUnit,SourceRange Range,SmallVectorImpl<CXToken> & CXTokens)5342f4a2713aSLionel Sambuc static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5343f4a2713aSLionel Sambuc                       SmallVectorImpl<CXToken> &CXTokens) {
5344f4a2713aSLionel Sambuc   SourceManager &SourceMgr = CXXUnit->getSourceManager();
5345f4a2713aSLionel Sambuc   std::pair<FileID, unsigned> BeginLocInfo
5346f4a2713aSLionel Sambuc     = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
5347f4a2713aSLionel Sambuc   std::pair<FileID, unsigned> EndLocInfo
5348f4a2713aSLionel Sambuc     = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
5349f4a2713aSLionel Sambuc 
5350f4a2713aSLionel Sambuc   // Cannot tokenize across files.
5351f4a2713aSLionel Sambuc   if (BeginLocInfo.first != EndLocInfo.first)
5352f4a2713aSLionel Sambuc     return;
5353f4a2713aSLionel Sambuc 
5354f4a2713aSLionel Sambuc   // Create a lexer
5355f4a2713aSLionel Sambuc   bool Invalid = false;
5356f4a2713aSLionel Sambuc   StringRef Buffer
5357f4a2713aSLionel Sambuc     = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5358f4a2713aSLionel Sambuc   if (Invalid)
5359f4a2713aSLionel Sambuc     return;
5360f4a2713aSLionel Sambuc 
5361f4a2713aSLionel Sambuc   Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5362f4a2713aSLionel Sambuc             CXXUnit->getASTContext().getLangOpts(),
5363f4a2713aSLionel Sambuc             Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5364f4a2713aSLionel Sambuc   Lex.SetCommentRetentionState(true);
5365f4a2713aSLionel Sambuc 
5366f4a2713aSLionel Sambuc   // Lex tokens until we hit the end of the range.
5367f4a2713aSLionel Sambuc   const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5368f4a2713aSLionel Sambuc   Token Tok;
5369f4a2713aSLionel Sambuc   bool previousWasAt = false;
5370f4a2713aSLionel Sambuc   do {
5371f4a2713aSLionel Sambuc     // Lex the next token
5372f4a2713aSLionel Sambuc     Lex.LexFromRawLexer(Tok);
5373f4a2713aSLionel Sambuc     if (Tok.is(tok::eof))
5374f4a2713aSLionel Sambuc       break;
5375f4a2713aSLionel Sambuc 
5376f4a2713aSLionel Sambuc     // Initialize the CXToken.
5377f4a2713aSLionel Sambuc     CXToken CXTok;
5378f4a2713aSLionel Sambuc 
5379f4a2713aSLionel Sambuc     //   - Common fields
5380f4a2713aSLionel Sambuc     CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5381f4a2713aSLionel Sambuc     CXTok.int_data[2] = Tok.getLength();
5382f4a2713aSLionel Sambuc     CXTok.int_data[3] = 0;
5383f4a2713aSLionel Sambuc 
5384f4a2713aSLionel Sambuc     //   - Kind-specific fields
5385f4a2713aSLionel Sambuc     if (Tok.isLiteral()) {
5386f4a2713aSLionel Sambuc       CXTok.int_data[0] = CXToken_Literal;
5387f4a2713aSLionel Sambuc       CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
5388f4a2713aSLionel Sambuc     } else if (Tok.is(tok::raw_identifier)) {
5389f4a2713aSLionel Sambuc       // Lookup the identifier to determine whether we have a keyword.
5390f4a2713aSLionel Sambuc       IdentifierInfo *II
5391f4a2713aSLionel Sambuc         = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5392f4a2713aSLionel Sambuc 
5393f4a2713aSLionel Sambuc       if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5394f4a2713aSLionel Sambuc         CXTok.int_data[0] = CXToken_Keyword;
5395f4a2713aSLionel Sambuc       }
5396f4a2713aSLionel Sambuc       else {
5397f4a2713aSLionel Sambuc         CXTok.int_data[0] = Tok.is(tok::identifier)
5398f4a2713aSLionel Sambuc           ? CXToken_Identifier
5399f4a2713aSLionel Sambuc           : CXToken_Keyword;
5400f4a2713aSLionel Sambuc       }
5401f4a2713aSLionel Sambuc       CXTok.ptr_data = II;
5402f4a2713aSLionel Sambuc     } else if (Tok.is(tok::comment)) {
5403f4a2713aSLionel Sambuc       CXTok.int_data[0] = CXToken_Comment;
5404*0a6a1f1dSLionel Sambuc       CXTok.ptr_data = nullptr;
5405f4a2713aSLionel Sambuc     } else {
5406f4a2713aSLionel Sambuc       CXTok.int_data[0] = CXToken_Punctuation;
5407*0a6a1f1dSLionel Sambuc       CXTok.ptr_data = nullptr;
5408f4a2713aSLionel Sambuc     }
5409f4a2713aSLionel Sambuc     CXTokens.push_back(CXTok);
5410f4a2713aSLionel Sambuc     previousWasAt = Tok.is(tok::at);
5411f4a2713aSLionel Sambuc   } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5412f4a2713aSLionel Sambuc }
5413f4a2713aSLionel Sambuc 
clang_tokenize(CXTranslationUnit TU,CXSourceRange Range,CXToken ** Tokens,unsigned * NumTokens)5414f4a2713aSLionel Sambuc void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5415f4a2713aSLionel Sambuc                     CXToken **Tokens, unsigned *NumTokens) {
5416f4a2713aSLionel Sambuc   LOG_FUNC_SECTION {
5417f4a2713aSLionel Sambuc     *Log << TU << ' ' << Range;
5418f4a2713aSLionel Sambuc   }
5419f4a2713aSLionel Sambuc 
5420f4a2713aSLionel Sambuc   if (Tokens)
5421*0a6a1f1dSLionel Sambuc     *Tokens = nullptr;
5422f4a2713aSLionel Sambuc   if (NumTokens)
5423f4a2713aSLionel Sambuc     *NumTokens = 0;
5424f4a2713aSLionel Sambuc 
5425*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
5426*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
5427f4a2713aSLionel Sambuc     return;
5428*0a6a1f1dSLionel Sambuc   }
5429f4a2713aSLionel Sambuc 
5430f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5431f4a2713aSLionel Sambuc   if (!CXXUnit || !Tokens || !NumTokens)
5432f4a2713aSLionel Sambuc     return;
5433f4a2713aSLionel Sambuc 
5434f4a2713aSLionel Sambuc   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5435f4a2713aSLionel Sambuc 
5436f4a2713aSLionel Sambuc   SourceRange R = cxloc::translateCXSourceRange(Range);
5437f4a2713aSLionel Sambuc   if (R.isInvalid())
5438f4a2713aSLionel Sambuc     return;
5439f4a2713aSLionel Sambuc 
5440f4a2713aSLionel Sambuc   SmallVector<CXToken, 32> CXTokens;
5441f4a2713aSLionel Sambuc   getTokens(CXXUnit, R, CXTokens);
5442f4a2713aSLionel Sambuc 
5443f4a2713aSLionel Sambuc   if (CXTokens.empty())
5444f4a2713aSLionel Sambuc     return;
5445f4a2713aSLionel Sambuc 
5446f4a2713aSLionel Sambuc   *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5447f4a2713aSLionel Sambuc   memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5448f4a2713aSLionel Sambuc   *NumTokens = CXTokens.size();
5449f4a2713aSLionel Sambuc }
5450f4a2713aSLionel Sambuc 
clang_disposeTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens)5451f4a2713aSLionel Sambuc void clang_disposeTokens(CXTranslationUnit TU,
5452f4a2713aSLionel Sambuc                          CXToken *Tokens, unsigned NumTokens) {
5453f4a2713aSLionel Sambuc   free(Tokens);
5454f4a2713aSLionel Sambuc }
5455f4a2713aSLionel Sambuc 
5456f4a2713aSLionel Sambuc } // end: extern "C"
5457f4a2713aSLionel Sambuc 
5458f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
5459f4a2713aSLionel Sambuc // Token annotation APIs.
5460f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
5461f4a2713aSLionel Sambuc 
5462f4a2713aSLionel Sambuc static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5463f4a2713aSLionel Sambuc                                                      CXCursor parent,
5464f4a2713aSLionel Sambuc                                                      CXClientData client_data);
5465f4a2713aSLionel Sambuc static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5466f4a2713aSLionel Sambuc                                               CXClientData client_data);
5467f4a2713aSLionel Sambuc 
5468f4a2713aSLionel Sambuc namespace {
5469f4a2713aSLionel Sambuc class AnnotateTokensWorker {
5470f4a2713aSLionel Sambuc   CXToken *Tokens;
5471f4a2713aSLionel Sambuc   CXCursor *Cursors;
5472f4a2713aSLionel Sambuc   unsigned NumTokens;
5473f4a2713aSLionel Sambuc   unsigned TokIdx;
5474f4a2713aSLionel Sambuc   unsigned PreprocessingTokIdx;
5475f4a2713aSLionel Sambuc   CursorVisitor AnnotateVis;
5476f4a2713aSLionel Sambuc   SourceManager &SrcMgr;
5477f4a2713aSLionel Sambuc   bool HasContextSensitiveKeywords;
5478f4a2713aSLionel Sambuc 
5479f4a2713aSLionel Sambuc   struct PostChildrenInfo {
5480f4a2713aSLionel Sambuc     CXCursor Cursor;
5481f4a2713aSLionel Sambuc     SourceRange CursorRange;
5482f4a2713aSLionel Sambuc     unsigned BeforeReachingCursorIdx;
5483f4a2713aSLionel Sambuc     unsigned BeforeChildrenTokenIdx;
5484f4a2713aSLionel Sambuc   };
5485f4a2713aSLionel Sambuc   SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
5486f4a2713aSLionel Sambuc 
getTok(unsigned Idx)5487*0a6a1f1dSLionel Sambuc   CXToken &getTok(unsigned Idx) {
5488*0a6a1f1dSLionel Sambuc     assert(Idx < NumTokens);
5489*0a6a1f1dSLionel Sambuc     return Tokens[Idx];
5490*0a6a1f1dSLionel Sambuc   }
getTok(unsigned Idx) const5491*0a6a1f1dSLionel Sambuc   const CXToken &getTok(unsigned Idx) const {
5492*0a6a1f1dSLionel Sambuc     assert(Idx < NumTokens);
5493*0a6a1f1dSLionel Sambuc     return Tokens[Idx];
5494*0a6a1f1dSLionel Sambuc   }
MoreTokens() const5495f4a2713aSLionel Sambuc   bool MoreTokens() const { return TokIdx < NumTokens; }
NextToken() const5496f4a2713aSLionel Sambuc   unsigned NextToken() const { return TokIdx; }
AdvanceToken()5497f4a2713aSLionel Sambuc   void AdvanceToken() { ++TokIdx; }
GetTokenLoc(unsigned tokI)5498f4a2713aSLionel Sambuc   SourceLocation GetTokenLoc(unsigned tokI) {
5499*0a6a1f1dSLionel Sambuc     return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
5500f4a2713aSLionel Sambuc   }
isFunctionMacroToken(unsigned tokI) const5501f4a2713aSLionel Sambuc   bool isFunctionMacroToken(unsigned tokI) const {
5502*0a6a1f1dSLionel Sambuc     return getTok(tokI).int_data[3] != 0;
5503f4a2713aSLionel Sambuc   }
getFunctionMacroTokenLoc(unsigned tokI) const5504f4a2713aSLionel Sambuc   SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5505*0a6a1f1dSLionel Sambuc     return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
5506f4a2713aSLionel Sambuc   }
5507f4a2713aSLionel Sambuc 
5508f4a2713aSLionel Sambuc   void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
5509f4a2713aSLionel Sambuc   bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
5510f4a2713aSLionel Sambuc                                              SourceRange);
5511f4a2713aSLionel Sambuc 
5512f4a2713aSLionel Sambuc public:
AnnotateTokensWorker(CXToken * tokens,CXCursor * cursors,unsigned numTokens,CXTranslationUnit TU,SourceRange RegionOfInterest)5513f4a2713aSLionel Sambuc   AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
5514f4a2713aSLionel Sambuc                        CXTranslationUnit TU, SourceRange RegionOfInterest)
5515f4a2713aSLionel Sambuc     : Tokens(tokens), Cursors(cursors),
5516f4a2713aSLionel Sambuc       NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
5517f4a2713aSLionel Sambuc       AnnotateVis(TU,
5518f4a2713aSLionel Sambuc                   AnnotateTokensVisitor, this,
5519f4a2713aSLionel Sambuc                   /*VisitPreprocessorLast=*/true,
5520f4a2713aSLionel Sambuc                   /*VisitIncludedEntities=*/false,
5521f4a2713aSLionel Sambuc                   RegionOfInterest,
5522f4a2713aSLionel Sambuc                   /*VisitDeclsOnly=*/false,
5523f4a2713aSLionel Sambuc                   AnnotateTokensPostChildrenVisitor),
5524f4a2713aSLionel Sambuc       SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
5525f4a2713aSLionel Sambuc       HasContextSensitiveKeywords(false) { }
5526f4a2713aSLionel Sambuc 
VisitChildren(CXCursor C)5527f4a2713aSLionel Sambuc   void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5528f4a2713aSLionel Sambuc   enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5529f4a2713aSLionel Sambuc   bool postVisitChildren(CXCursor cursor);
5530f4a2713aSLionel Sambuc   void AnnotateTokens();
5531f4a2713aSLionel Sambuc 
5532f4a2713aSLionel Sambuc   /// \brief Determine whether the annotator saw any cursors that have
5533f4a2713aSLionel Sambuc   /// context-sensitive keywords.
hasContextSensitiveKeywords() const5534f4a2713aSLionel Sambuc   bool hasContextSensitiveKeywords() const {
5535f4a2713aSLionel Sambuc     return HasContextSensitiveKeywords;
5536f4a2713aSLionel Sambuc   }
5537f4a2713aSLionel Sambuc 
~AnnotateTokensWorker()5538f4a2713aSLionel Sambuc   ~AnnotateTokensWorker() {
5539f4a2713aSLionel Sambuc     assert(PostChildrenInfos.empty());
5540f4a2713aSLionel Sambuc   }
5541f4a2713aSLionel Sambuc };
5542f4a2713aSLionel Sambuc }
5543f4a2713aSLionel Sambuc 
AnnotateTokens()5544f4a2713aSLionel Sambuc void AnnotateTokensWorker::AnnotateTokens() {
5545f4a2713aSLionel Sambuc   // Walk the AST within the region of interest, annotating tokens
5546f4a2713aSLionel Sambuc   // along the way.
5547f4a2713aSLionel Sambuc   AnnotateVis.visitFileRegion();
5548f4a2713aSLionel Sambuc }
5549f4a2713aSLionel Sambuc 
updateCursorAnnotation(CXCursor & Cursor,const CXCursor & updateC)5550f4a2713aSLionel Sambuc static inline void updateCursorAnnotation(CXCursor &Cursor,
5551f4a2713aSLionel Sambuc                                           const CXCursor &updateC) {
5552f4a2713aSLionel Sambuc   if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
5553f4a2713aSLionel Sambuc     return;
5554f4a2713aSLionel Sambuc   Cursor = updateC;
5555f4a2713aSLionel Sambuc }
5556f4a2713aSLionel Sambuc 
5557f4a2713aSLionel Sambuc /// \brief It annotates and advances tokens with a cursor until the comparison
5558f4a2713aSLionel Sambuc //// between the cursor location and the source range is the same as
5559f4a2713aSLionel Sambuc /// \arg compResult.
5560f4a2713aSLionel Sambuc ///
5561f4a2713aSLionel Sambuc /// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5562f4a2713aSLionel Sambuc /// Pass RangeOverlap to annotate tokens inside a range.
annotateAndAdvanceTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)5563f4a2713aSLionel Sambuc void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5564f4a2713aSLionel Sambuc                                                RangeComparisonResult compResult,
5565f4a2713aSLionel Sambuc                                                SourceRange range) {
5566f4a2713aSLionel Sambuc   while (MoreTokens()) {
5567f4a2713aSLionel Sambuc     const unsigned I = NextToken();
5568f4a2713aSLionel Sambuc     if (isFunctionMacroToken(I))
5569f4a2713aSLionel Sambuc       if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5570f4a2713aSLionel Sambuc         return;
5571f4a2713aSLionel Sambuc 
5572f4a2713aSLionel Sambuc     SourceLocation TokLoc = GetTokenLoc(I);
5573f4a2713aSLionel Sambuc     if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5574f4a2713aSLionel Sambuc       updateCursorAnnotation(Cursors[I], updateC);
5575f4a2713aSLionel Sambuc       AdvanceToken();
5576f4a2713aSLionel Sambuc       continue;
5577f4a2713aSLionel Sambuc     }
5578f4a2713aSLionel Sambuc     break;
5579f4a2713aSLionel Sambuc   }
5580f4a2713aSLionel Sambuc }
5581f4a2713aSLionel Sambuc 
5582f4a2713aSLionel Sambuc /// \brief Special annotation handling for macro argument tokens.
5583f4a2713aSLionel Sambuc /// \returns true if it advanced beyond all macro tokens, false otherwise.
annotateAndAdvanceFunctionMacroTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)5584f4a2713aSLionel Sambuc bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
5585f4a2713aSLionel Sambuc                                                CXCursor updateC,
5586f4a2713aSLionel Sambuc                                                RangeComparisonResult compResult,
5587f4a2713aSLionel Sambuc                                                SourceRange range) {
5588f4a2713aSLionel Sambuc   assert(MoreTokens());
5589f4a2713aSLionel Sambuc   assert(isFunctionMacroToken(NextToken()) &&
5590f4a2713aSLionel Sambuc          "Should be called only for macro arg tokens");
5591f4a2713aSLionel Sambuc 
5592f4a2713aSLionel Sambuc   // This works differently than annotateAndAdvanceTokens; because expanded
5593f4a2713aSLionel Sambuc   // macro arguments can have arbitrary translation-unit source order, we do not
5594f4a2713aSLionel Sambuc   // advance the token index one by one until a token fails the range test.
5595f4a2713aSLionel Sambuc   // We only advance once past all of the macro arg tokens if all of them
5596f4a2713aSLionel Sambuc   // pass the range test. If one of them fails we keep the token index pointing
5597f4a2713aSLionel Sambuc   // at the start of the macro arg tokens so that the failing token will be
5598f4a2713aSLionel Sambuc   // annotated by a subsequent annotation try.
5599f4a2713aSLionel Sambuc 
5600f4a2713aSLionel Sambuc   bool atLeastOneCompFail = false;
5601f4a2713aSLionel Sambuc 
5602f4a2713aSLionel Sambuc   unsigned I = NextToken();
5603f4a2713aSLionel Sambuc   for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5604f4a2713aSLionel Sambuc     SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5605f4a2713aSLionel Sambuc     if (TokLoc.isFileID())
5606f4a2713aSLionel Sambuc       continue; // not macro arg token, it's parens or comma.
5607f4a2713aSLionel Sambuc     if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5608f4a2713aSLionel Sambuc       if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5609f4a2713aSLionel Sambuc         Cursors[I] = updateC;
5610f4a2713aSLionel Sambuc     } else
5611f4a2713aSLionel Sambuc       atLeastOneCompFail = true;
5612f4a2713aSLionel Sambuc   }
5613f4a2713aSLionel Sambuc 
5614f4a2713aSLionel Sambuc   if (atLeastOneCompFail)
5615f4a2713aSLionel Sambuc     return false;
5616f4a2713aSLionel Sambuc 
5617f4a2713aSLionel Sambuc   TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5618f4a2713aSLionel Sambuc   return true;
5619f4a2713aSLionel Sambuc }
5620f4a2713aSLionel Sambuc 
5621f4a2713aSLionel Sambuc enum CXChildVisitResult
Visit(CXCursor cursor,CXCursor parent)5622f4a2713aSLionel Sambuc AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
5623f4a2713aSLionel Sambuc   SourceRange cursorRange = getRawCursorExtent(cursor);
5624f4a2713aSLionel Sambuc   if (cursorRange.isInvalid())
5625f4a2713aSLionel Sambuc     return CXChildVisit_Recurse;
5626f4a2713aSLionel Sambuc 
5627f4a2713aSLionel Sambuc   if (!HasContextSensitiveKeywords) {
5628f4a2713aSLionel Sambuc     // Objective-C properties can have context-sensitive keywords.
5629f4a2713aSLionel Sambuc     if (cursor.kind == CXCursor_ObjCPropertyDecl) {
5630f4a2713aSLionel Sambuc       if (const ObjCPropertyDecl *Property
5631f4a2713aSLionel Sambuc                   = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5632f4a2713aSLionel Sambuc         HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5633f4a2713aSLionel Sambuc     }
5634f4a2713aSLionel Sambuc     // Objective-C methods can have context-sensitive keywords.
5635f4a2713aSLionel Sambuc     else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5636f4a2713aSLionel Sambuc              cursor.kind == CXCursor_ObjCClassMethodDecl) {
5637f4a2713aSLionel Sambuc       if (const ObjCMethodDecl *Method
5638f4a2713aSLionel Sambuc             = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5639f4a2713aSLionel Sambuc         if (Method->getObjCDeclQualifier())
5640f4a2713aSLionel Sambuc           HasContextSensitiveKeywords = true;
5641f4a2713aSLionel Sambuc         else {
5642*0a6a1f1dSLionel Sambuc           for (const auto *P : Method->params()) {
5643*0a6a1f1dSLionel Sambuc             if (P->getObjCDeclQualifier()) {
5644f4a2713aSLionel Sambuc               HasContextSensitiveKeywords = true;
5645f4a2713aSLionel Sambuc               break;
5646f4a2713aSLionel Sambuc             }
5647f4a2713aSLionel Sambuc           }
5648f4a2713aSLionel Sambuc         }
5649f4a2713aSLionel Sambuc       }
5650f4a2713aSLionel Sambuc     }
5651f4a2713aSLionel Sambuc     // C++ methods can have context-sensitive keywords.
5652f4a2713aSLionel Sambuc     else if (cursor.kind == CXCursor_CXXMethod) {
5653f4a2713aSLionel Sambuc       if (const CXXMethodDecl *Method
5654f4a2713aSLionel Sambuc                   = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5655f4a2713aSLionel Sambuc         if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5656f4a2713aSLionel Sambuc           HasContextSensitiveKeywords = true;
5657f4a2713aSLionel Sambuc       }
5658f4a2713aSLionel Sambuc     }
5659f4a2713aSLionel Sambuc     // C++ classes can have context-sensitive keywords.
5660f4a2713aSLionel Sambuc     else if (cursor.kind == CXCursor_StructDecl ||
5661f4a2713aSLionel Sambuc              cursor.kind == CXCursor_ClassDecl ||
5662f4a2713aSLionel Sambuc              cursor.kind == CXCursor_ClassTemplate ||
5663f4a2713aSLionel Sambuc              cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
5664f4a2713aSLionel Sambuc       if (const Decl *D = getCursorDecl(cursor))
5665f4a2713aSLionel Sambuc         if (D->hasAttr<FinalAttr>())
5666f4a2713aSLionel Sambuc           HasContextSensitiveKeywords = true;
5667f4a2713aSLionel Sambuc     }
5668f4a2713aSLionel Sambuc   }
5669f4a2713aSLionel Sambuc 
5670f4a2713aSLionel Sambuc   // Don't override a property annotation with its getter/setter method.
5671f4a2713aSLionel Sambuc   if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5672f4a2713aSLionel Sambuc       parent.kind == CXCursor_ObjCPropertyDecl)
5673f4a2713aSLionel Sambuc     return CXChildVisit_Continue;
5674f4a2713aSLionel Sambuc 
5675f4a2713aSLionel Sambuc   if (clang_isPreprocessing(cursor.kind)) {
5676f4a2713aSLionel Sambuc     // Items in the preprocessing record are kept separate from items in
5677f4a2713aSLionel Sambuc     // declarations, so we keep a separate token index.
5678f4a2713aSLionel Sambuc     unsigned SavedTokIdx = TokIdx;
5679f4a2713aSLionel Sambuc     TokIdx = PreprocessingTokIdx;
5680f4a2713aSLionel Sambuc 
5681f4a2713aSLionel Sambuc     // Skip tokens up until we catch up to the beginning of the preprocessing
5682f4a2713aSLionel Sambuc     // entry.
5683f4a2713aSLionel Sambuc     while (MoreTokens()) {
5684f4a2713aSLionel Sambuc       const unsigned I = NextToken();
5685f4a2713aSLionel Sambuc       SourceLocation TokLoc = GetTokenLoc(I);
5686f4a2713aSLionel Sambuc       switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5687f4a2713aSLionel Sambuc       case RangeBefore:
5688f4a2713aSLionel Sambuc         AdvanceToken();
5689f4a2713aSLionel Sambuc         continue;
5690f4a2713aSLionel Sambuc       case RangeAfter:
5691f4a2713aSLionel Sambuc       case RangeOverlap:
5692f4a2713aSLionel Sambuc         break;
5693f4a2713aSLionel Sambuc       }
5694f4a2713aSLionel Sambuc       break;
5695f4a2713aSLionel Sambuc     }
5696f4a2713aSLionel Sambuc 
5697f4a2713aSLionel Sambuc     // Look at all of the tokens within this range.
5698f4a2713aSLionel Sambuc     while (MoreTokens()) {
5699f4a2713aSLionel Sambuc       const unsigned I = NextToken();
5700f4a2713aSLionel Sambuc       SourceLocation TokLoc = GetTokenLoc(I);
5701f4a2713aSLionel Sambuc       switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5702f4a2713aSLionel Sambuc       case RangeBefore:
5703f4a2713aSLionel Sambuc         llvm_unreachable("Infeasible");
5704f4a2713aSLionel Sambuc       case RangeAfter:
5705f4a2713aSLionel Sambuc         break;
5706f4a2713aSLionel Sambuc       case RangeOverlap:
5707f4a2713aSLionel Sambuc         // For macro expansions, just note where the beginning of the macro
5708f4a2713aSLionel Sambuc         // expansion occurs.
5709f4a2713aSLionel Sambuc         if (cursor.kind == CXCursor_MacroExpansion) {
5710f4a2713aSLionel Sambuc           if (TokLoc == cursorRange.getBegin())
5711f4a2713aSLionel Sambuc             Cursors[I] = cursor;
5712f4a2713aSLionel Sambuc           AdvanceToken();
5713f4a2713aSLionel Sambuc           break;
5714f4a2713aSLionel Sambuc         }
5715f4a2713aSLionel Sambuc         // We may have already annotated macro names inside macro definitions.
5716f4a2713aSLionel Sambuc         if (Cursors[I].kind != CXCursor_MacroExpansion)
5717f4a2713aSLionel Sambuc           Cursors[I] = cursor;
5718f4a2713aSLionel Sambuc         AdvanceToken();
5719f4a2713aSLionel Sambuc         continue;
5720f4a2713aSLionel Sambuc       }
5721f4a2713aSLionel Sambuc       break;
5722f4a2713aSLionel Sambuc     }
5723f4a2713aSLionel Sambuc 
5724f4a2713aSLionel Sambuc     // Save the preprocessing token index; restore the non-preprocessing
5725f4a2713aSLionel Sambuc     // token index.
5726f4a2713aSLionel Sambuc     PreprocessingTokIdx = TokIdx;
5727f4a2713aSLionel Sambuc     TokIdx = SavedTokIdx;
5728f4a2713aSLionel Sambuc     return CXChildVisit_Recurse;
5729f4a2713aSLionel Sambuc   }
5730f4a2713aSLionel Sambuc 
5731f4a2713aSLionel Sambuc   if (cursorRange.isInvalid())
5732f4a2713aSLionel Sambuc     return CXChildVisit_Continue;
5733f4a2713aSLionel Sambuc 
5734f4a2713aSLionel Sambuc   unsigned BeforeReachingCursorIdx = NextToken();
5735f4a2713aSLionel Sambuc   const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
5736f4a2713aSLionel Sambuc   const enum CXCursorKind K = clang_getCursorKind(parent);
5737f4a2713aSLionel Sambuc   const CXCursor updateC =
5738f4a2713aSLionel Sambuc     (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5739f4a2713aSLionel Sambuc      // Attributes are annotated out-of-order, skip tokens until we reach it.
5740f4a2713aSLionel Sambuc      clang_isAttribute(cursor.kind))
5741f4a2713aSLionel Sambuc      ? clang_getNullCursor() : parent;
5742f4a2713aSLionel Sambuc 
5743f4a2713aSLionel Sambuc   annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5744f4a2713aSLionel Sambuc 
5745f4a2713aSLionel Sambuc   // Avoid having the cursor of an expression "overwrite" the annotation of the
5746f4a2713aSLionel Sambuc   // variable declaration that it belongs to.
5747f4a2713aSLionel Sambuc   // This can happen for C++ constructor expressions whose range generally
5748f4a2713aSLionel Sambuc   // include the variable declaration, e.g.:
5749f4a2713aSLionel Sambuc   //  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5750*0a6a1f1dSLionel Sambuc   if (clang_isExpression(cursorK) && MoreTokens()) {
5751f4a2713aSLionel Sambuc     const Expr *E = getCursorExpr(cursor);
5752f4a2713aSLionel Sambuc     if (const Decl *D = getCursorParentDecl(cursor)) {
5753f4a2713aSLionel Sambuc       const unsigned I = NextToken();
5754f4a2713aSLionel Sambuc       if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5755f4a2713aSLionel Sambuc           E->getLocStart() == D->getLocation() &&
5756f4a2713aSLionel Sambuc           E->getLocStart() == GetTokenLoc(I)) {
5757f4a2713aSLionel Sambuc         updateCursorAnnotation(Cursors[I], updateC);
5758f4a2713aSLionel Sambuc         AdvanceToken();
5759f4a2713aSLionel Sambuc       }
5760f4a2713aSLionel Sambuc     }
5761f4a2713aSLionel Sambuc   }
5762f4a2713aSLionel Sambuc 
5763f4a2713aSLionel Sambuc   // Before recursing into the children keep some state that we are going
5764f4a2713aSLionel Sambuc   // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5765f4a2713aSLionel Sambuc   // extra work after the child nodes are visited.
5766f4a2713aSLionel Sambuc   // Note that we don't call VisitChildren here to avoid traversing statements
5767f4a2713aSLionel Sambuc   // code-recursively which can blow the stack.
5768f4a2713aSLionel Sambuc 
5769f4a2713aSLionel Sambuc   PostChildrenInfo Info;
5770f4a2713aSLionel Sambuc   Info.Cursor = cursor;
5771f4a2713aSLionel Sambuc   Info.CursorRange = cursorRange;
5772f4a2713aSLionel Sambuc   Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
5773f4a2713aSLionel Sambuc   Info.BeforeChildrenTokenIdx = NextToken();
5774f4a2713aSLionel Sambuc   PostChildrenInfos.push_back(Info);
5775f4a2713aSLionel Sambuc 
5776f4a2713aSLionel Sambuc   return CXChildVisit_Recurse;
5777f4a2713aSLionel Sambuc }
5778f4a2713aSLionel Sambuc 
postVisitChildren(CXCursor cursor)5779f4a2713aSLionel Sambuc bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5780f4a2713aSLionel Sambuc   if (PostChildrenInfos.empty())
5781f4a2713aSLionel Sambuc     return false;
5782f4a2713aSLionel Sambuc   const PostChildrenInfo &Info = PostChildrenInfos.back();
5783f4a2713aSLionel Sambuc   if (!clang_equalCursors(Info.Cursor, cursor))
5784f4a2713aSLionel Sambuc     return false;
5785f4a2713aSLionel Sambuc 
5786f4a2713aSLionel Sambuc   const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5787f4a2713aSLionel Sambuc   const unsigned AfterChildren = NextToken();
5788f4a2713aSLionel Sambuc   SourceRange cursorRange = Info.CursorRange;
5789f4a2713aSLionel Sambuc 
5790f4a2713aSLionel Sambuc   // Scan the tokens that are at the end of the cursor, but are not captured
5791f4a2713aSLionel Sambuc   // but the child cursors.
5792f4a2713aSLionel Sambuc   annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5793f4a2713aSLionel Sambuc 
5794f4a2713aSLionel Sambuc   // Scan the tokens that are at the beginning of the cursor, but are not
5795f4a2713aSLionel Sambuc   // capture by the child cursors.
5796f4a2713aSLionel Sambuc   for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5797f4a2713aSLionel Sambuc     if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5798f4a2713aSLionel Sambuc       break;
5799f4a2713aSLionel Sambuc 
5800f4a2713aSLionel Sambuc     Cursors[I] = cursor;
5801f4a2713aSLionel Sambuc   }
5802f4a2713aSLionel Sambuc 
5803f4a2713aSLionel Sambuc   // Attributes are annotated out-of-order, rewind TokIdx to when we first
5804f4a2713aSLionel Sambuc   // encountered the attribute cursor.
5805f4a2713aSLionel Sambuc   if (clang_isAttribute(cursor.kind))
5806f4a2713aSLionel Sambuc     TokIdx = Info.BeforeReachingCursorIdx;
5807f4a2713aSLionel Sambuc 
5808f4a2713aSLionel Sambuc   PostChildrenInfos.pop_back();
5809f4a2713aSLionel Sambuc   return false;
5810f4a2713aSLionel Sambuc }
5811f4a2713aSLionel Sambuc 
AnnotateTokensVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)5812f4a2713aSLionel Sambuc static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5813f4a2713aSLionel Sambuc                                                      CXCursor parent,
5814f4a2713aSLionel Sambuc                                                      CXClientData client_data) {
5815f4a2713aSLionel Sambuc   return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5816f4a2713aSLionel Sambuc }
5817f4a2713aSLionel Sambuc 
AnnotateTokensPostChildrenVisitor(CXCursor cursor,CXClientData client_data)5818f4a2713aSLionel Sambuc static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5819f4a2713aSLionel Sambuc                                               CXClientData client_data) {
5820f4a2713aSLionel Sambuc   return static_cast<AnnotateTokensWorker*>(client_data)->
5821f4a2713aSLionel Sambuc                                                       postVisitChildren(cursor);
5822f4a2713aSLionel Sambuc }
5823f4a2713aSLionel Sambuc 
5824f4a2713aSLionel Sambuc namespace {
5825f4a2713aSLionel Sambuc 
5826f4a2713aSLionel Sambuc /// \brief Uses the macro expansions in the preprocessing record to find
5827f4a2713aSLionel Sambuc /// and mark tokens that are macro arguments. This info is used by the
5828f4a2713aSLionel Sambuc /// AnnotateTokensWorker.
5829f4a2713aSLionel Sambuc class MarkMacroArgTokensVisitor {
5830f4a2713aSLionel Sambuc   SourceManager &SM;
5831f4a2713aSLionel Sambuc   CXToken *Tokens;
5832f4a2713aSLionel Sambuc   unsigned NumTokens;
5833f4a2713aSLionel Sambuc   unsigned CurIdx;
5834f4a2713aSLionel Sambuc 
5835f4a2713aSLionel Sambuc public:
MarkMacroArgTokensVisitor(SourceManager & SM,CXToken * tokens,unsigned numTokens)5836f4a2713aSLionel Sambuc   MarkMacroArgTokensVisitor(SourceManager &SM,
5837f4a2713aSLionel Sambuc                             CXToken *tokens, unsigned numTokens)
5838f4a2713aSLionel Sambuc     : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5839f4a2713aSLionel Sambuc 
visit(CXCursor cursor,CXCursor parent)5840f4a2713aSLionel Sambuc   CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5841f4a2713aSLionel Sambuc     if (cursor.kind != CXCursor_MacroExpansion)
5842f4a2713aSLionel Sambuc       return CXChildVisit_Continue;
5843f4a2713aSLionel Sambuc 
5844f4a2713aSLionel Sambuc     SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
5845f4a2713aSLionel Sambuc     if (macroRange.getBegin() == macroRange.getEnd())
5846f4a2713aSLionel Sambuc       return CXChildVisit_Continue; // it's not a function macro.
5847f4a2713aSLionel Sambuc 
5848f4a2713aSLionel Sambuc     for (; CurIdx < NumTokens; ++CurIdx) {
5849f4a2713aSLionel Sambuc       if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5850f4a2713aSLionel Sambuc                                         macroRange.getBegin()))
5851f4a2713aSLionel Sambuc         break;
5852f4a2713aSLionel Sambuc     }
5853f4a2713aSLionel Sambuc 
5854f4a2713aSLionel Sambuc     if (CurIdx == NumTokens)
5855f4a2713aSLionel Sambuc       return CXChildVisit_Break;
5856f4a2713aSLionel Sambuc 
5857f4a2713aSLionel Sambuc     for (; CurIdx < NumTokens; ++CurIdx) {
5858f4a2713aSLionel Sambuc       SourceLocation tokLoc = getTokenLoc(CurIdx);
5859f4a2713aSLionel Sambuc       if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5860f4a2713aSLionel Sambuc         break;
5861f4a2713aSLionel Sambuc 
5862f4a2713aSLionel Sambuc       setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5863f4a2713aSLionel Sambuc     }
5864f4a2713aSLionel Sambuc 
5865f4a2713aSLionel Sambuc     if (CurIdx == NumTokens)
5866f4a2713aSLionel Sambuc       return CXChildVisit_Break;
5867f4a2713aSLionel Sambuc 
5868f4a2713aSLionel Sambuc     return CXChildVisit_Continue;
5869f4a2713aSLionel Sambuc   }
5870f4a2713aSLionel Sambuc 
5871f4a2713aSLionel Sambuc private:
getTok(unsigned Idx)5872*0a6a1f1dSLionel Sambuc   CXToken &getTok(unsigned Idx) {
5873*0a6a1f1dSLionel Sambuc     assert(Idx < NumTokens);
5874*0a6a1f1dSLionel Sambuc     return Tokens[Idx];
5875*0a6a1f1dSLionel Sambuc   }
getTok(unsigned Idx) const5876*0a6a1f1dSLionel Sambuc   const CXToken &getTok(unsigned Idx) const {
5877*0a6a1f1dSLionel Sambuc     assert(Idx < NumTokens);
5878*0a6a1f1dSLionel Sambuc     return Tokens[Idx];
5879*0a6a1f1dSLionel Sambuc   }
5880*0a6a1f1dSLionel Sambuc 
getTokenLoc(unsigned tokI)5881f4a2713aSLionel Sambuc   SourceLocation getTokenLoc(unsigned tokI) {
5882*0a6a1f1dSLionel Sambuc     return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
5883f4a2713aSLionel Sambuc   }
5884f4a2713aSLionel Sambuc 
setFunctionMacroTokenLoc(unsigned tokI,SourceLocation loc)5885f4a2713aSLionel Sambuc   void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5886f4a2713aSLionel Sambuc     // The third field is reserved and currently not used. Use it here
5887f4a2713aSLionel Sambuc     // to mark macro arg expanded tokens with their expanded locations.
5888*0a6a1f1dSLionel Sambuc     getTok(tokI).int_data[3] = loc.getRawEncoding();
5889f4a2713aSLionel Sambuc   }
5890f4a2713aSLionel Sambuc };
5891f4a2713aSLionel Sambuc 
5892f4a2713aSLionel Sambuc } // end anonymous namespace
5893f4a2713aSLionel Sambuc 
5894f4a2713aSLionel Sambuc static CXChildVisitResult
MarkMacroArgTokensVisitorDelegate(CXCursor cursor,CXCursor parent,CXClientData client_data)5895f4a2713aSLionel Sambuc MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5896f4a2713aSLionel Sambuc                                   CXClientData client_data) {
5897f4a2713aSLionel Sambuc   return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5898f4a2713aSLionel Sambuc                                                                      parent);
5899f4a2713aSLionel Sambuc }
5900f4a2713aSLionel Sambuc 
5901f4a2713aSLionel Sambuc namespace {
5902f4a2713aSLionel Sambuc   struct clang_annotateTokens_Data {
5903f4a2713aSLionel Sambuc     CXTranslationUnit TU;
5904f4a2713aSLionel Sambuc     ASTUnit *CXXUnit;
5905f4a2713aSLionel Sambuc     CXToken *Tokens;
5906f4a2713aSLionel Sambuc     unsigned NumTokens;
5907f4a2713aSLionel Sambuc     CXCursor *Cursors;
5908f4a2713aSLionel Sambuc   };
5909f4a2713aSLionel Sambuc }
5910f4a2713aSLionel Sambuc 
5911f4a2713aSLionel Sambuc /// \brief Used by \c annotatePreprocessorTokens.
5912f4a2713aSLionel Sambuc /// \returns true if lexing was finished, false otherwise.
lexNext(Lexer & Lex,Token & Tok,unsigned & NextIdx,unsigned NumTokens)5913f4a2713aSLionel Sambuc static bool lexNext(Lexer &Lex, Token &Tok,
5914f4a2713aSLionel Sambuc                    unsigned &NextIdx, unsigned NumTokens) {
5915f4a2713aSLionel Sambuc   if (NextIdx >= NumTokens)
5916f4a2713aSLionel Sambuc     return true;
5917f4a2713aSLionel Sambuc 
5918f4a2713aSLionel Sambuc   ++NextIdx;
5919f4a2713aSLionel Sambuc   Lex.LexFromRawLexer(Tok);
5920f4a2713aSLionel Sambuc   if (Tok.is(tok::eof))
5921f4a2713aSLionel Sambuc     return true;
5922f4a2713aSLionel Sambuc 
5923f4a2713aSLionel Sambuc   return false;
5924f4a2713aSLionel Sambuc }
5925f4a2713aSLionel Sambuc 
annotatePreprocessorTokens(CXTranslationUnit TU,SourceRange RegionOfInterest,CXCursor * Cursors,CXToken * Tokens,unsigned NumTokens)5926f4a2713aSLionel Sambuc static void annotatePreprocessorTokens(CXTranslationUnit TU,
5927f4a2713aSLionel Sambuc                                        SourceRange RegionOfInterest,
5928f4a2713aSLionel Sambuc                                        CXCursor *Cursors,
5929f4a2713aSLionel Sambuc                                        CXToken *Tokens,
5930f4a2713aSLionel Sambuc                                        unsigned NumTokens) {
5931f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5932f4a2713aSLionel Sambuc 
5933f4a2713aSLionel Sambuc   Preprocessor &PP = CXXUnit->getPreprocessor();
5934f4a2713aSLionel Sambuc   SourceManager &SourceMgr = CXXUnit->getSourceManager();
5935f4a2713aSLionel Sambuc   std::pair<FileID, unsigned> BeginLocInfo
5936f4a2713aSLionel Sambuc     = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
5937f4a2713aSLionel Sambuc   std::pair<FileID, unsigned> EndLocInfo
5938f4a2713aSLionel Sambuc     = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
5939f4a2713aSLionel Sambuc 
5940f4a2713aSLionel Sambuc   if (BeginLocInfo.first != EndLocInfo.first)
5941f4a2713aSLionel Sambuc     return;
5942f4a2713aSLionel Sambuc 
5943f4a2713aSLionel Sambuc   StringRef Buffer;
5944f4a2713aSLionel Sambuc   bool Invalid = false;
5945f4a2713aSLionel Sambuc   Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5946f4a2713aSLionel Sambuc   if (Buffer.empty() || Invalid)
5947f4a2713aSLionel Sambuc     return;
5948f4a2713aSLionel Sambuc 
5949f4a2713aSLionel Sambuc   Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5950f4a2713aSLionel Sambuc             CXXUnit->getASTContext().getLangOpts(),
5951f4a2713aSLionel Sambuc             Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5952f4a2713aSLionel Sambuc             Buffer.end());
5953f4a2713aSLionel Sambuc   Lex.SetCommentRetentionState(true);
5954f4a2713aSLionel Sambuc 
5955f4a2713aSLionel Sambuc   unsigned NextIdx = 0;
5956f4a2713aSLionel Sambuc   // Lex tokens in raw mode until we hit the end of the range, to avoid
5957f4a2713aSLionel Sambuc   // entering #includes or expanding macros.
5958f4a2713aSLionel Sambuc   while (true) {
5959f4a2713aSLionel Sambuc     Token Tok;
5960f4a2713aSLionel Sambuc     if (lexNext(Lex, Tok, NextIdx, NumTokens))
5961f4a2713aSLionel Sambuc       break;
5962f4a2713aSLionel Sambuc     unsigned TokIdx = NextIdx-1;
5963f4a2713aSLionel Sambuc     assert(Tok.getLocation() ==
5964f4a2713aSLionel Sambuc              SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
5965f4a2713aSLionel Sambuc 
5966f4a2713aSLionel Sambuc   reprocess:
5967f4a2713aSLionel Sambuc     if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
5968f4a2713aSLionel Sambuc       // We have found a preprocessing directive. Annotate the tokens
5969f4a2713aSLionel Sambuc       // appropriately.
5970f4a2713aSLionel Sambuc       //
5971f4a2713aSLionel Sambuc       // FIXME: Some simple tests here could identify macro definitions and
5972f4a2713aSLionel Sambuc       // #undefs, to provide specific cursor kinds for those.
5973f4a2713aSLionel Sambuc 
5974f4a2713aSLionel Sambuc       SourceLocation BeginLoc = Tok.getLocation();
5975f4a2713aSLionel Sambuc       if (lexNext(Lex, Tok, NextIdx, NumTokens))
5976f4a2713aSLionel Sambuc         break;
5977f4a2713aSLionel Sambuc 
5978*0a6a1f1dSLionel Sambuc       MacroInfo *MI = nullptr;
5979*0a6a1f1dSLionel Sambuc       if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
5980f4a2713aSLionel Sambuc         if (lexNext(Lex, Tok, NextIdx, NumTokens))
5981f4a2713aSLionel Sambuc           break;
5982f4a2713aSLionel Sambuc 
5983f4a2713aSLionel Sambuc         if (Tok.is(tok::raw_identifier)) {
5984*0a6a1f1dSLionel Sambuc           IdentifierInfo &II =
5985*0a6a1f1dSLionel Sambuc               PP.getIdentifierTable().get(Tok.getRawIdentifier());
5986f4a2713aSLionel Sambuc           SourceLocation MappedTokLoc =
5987f4a2713aSLionel Sambuc               CXXUnit->mapLocationToPreamble(Tok.getLocation());
5988f4a2713aSLionel Sambuc           MI = getMacroInfo(II, MappedTokLoc, TU);
5989f4a2713aSLionel Sambuc         }
5990f4a2713aSLionel Sambuc       }
5991f4a2713aSLionel Sambuc 
5992f4a2713aSLionel Sambuc       bool finished = false;
5993f4a2713aSLionel Sambuc       do {
5994f4a2713aSLionel Sambuc         if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5995f4a2713aSLionel Sambuc           finished = true;
5996f4a2713aSLionel Sambuc           break;
5997f4a2713aSLionel Sambuc         }
5998f4a2713aSLionel Sambuc         // If we are in a macro definition, check if the token was ever a
5999f4a2713aSLionel Sambuc         // macro name and annotate it if that's the case.
6000f4a2713aSLionel Sambuc         if (MI) {
6001f4a2713aSLionel Sambuc           SourceLocation SaveLoc = Tok.getLocation();
6002f4a2713aSLionel Sambuc           Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6003f4a2713aSLionel Sambuc           MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
6004f4a2713aSLionel Sambuc           Tok.setLocation(SaveLoc);
6005f4a2713aSLionel Sambuc           if (MacroDef)
6006f4a2713aSLionel Sambuc             Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
6007f4a2713aSLionel Sambuc                                                          Tok.getLocation(), TU);
6008f4a2713aSLionel Sambuc         }
6009f4a2713aSLionel Sambuc       } while (!Tok.isAtStartOfLine());
6010f4a2713aSLionel Sambuc 
6011f4a2713aSLionel Sambuc       unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6012f4a2713aSLionel Sambuc       assert(TokIdx <= LastIdx);
6013f4a2713aSLionel Sambuc       SourceLocation EndLoc =
6014f4a2713aSLionel Sambuc           SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6015f4a2713aSLionel Sambuc       CXCursor Cursor =
6016f4a2713aSLionel Sambuc           MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6017f4a2713aSLionel Sambuc 
6018f4a2713aSLionel Sambuc       for (; TokIdx <= LastIdx; ++TokIdx)
6019f4a2713aSLionel Sambuc         updateCursorAnnotation(Cursors[TokIdx], Cursor);
6020f4a2713aSLionel Sambuc 
6021f4a2713aSLionel Sambuc       if (finished)
6022f4a2713aSLionel Sambuc         break;
6023f4a2713aSLionel Sambuc       goto reprocess;
6024f4a2713aSLionel Sambuc     }
6025f4a2713aSLionel Sambuc   }
6026f4a2713aSLionel Sambuc }
6027f4a2713aSLionel Sambuc 
6028f4a2713aSLionel Sambuc // This gets run a separate thread to avoid stack blowout.
clang_annotateTokensImpl(void * UserData)6029f4a2713aSLionel Sambuc static void clang_annotateTokensImpl(void *UserData) {
6030f4a2713aSLionel Sambuc   CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
6031f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
6032f4a2713aSLionel Sambuc   CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
6033f4a2713aSLionel Sambuc   const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
6034f4a2713aSLionel Sambuc   CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
6035f4a2713aSLionel Sambuc 
6036f4a2713aSLionel Sambuc   CIndexer *CXXIdx = TU->CIdx;
6037f4a2713aSLionel Sambuc   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6038f4a2713aSLionel Sambuc     setThreadBackgroundPriority();
6039f4a2713aSLionel Sambuc 
6040f4a2713aSLionel Sambuc   // Determine the region of interest, which contains all of the tokens.
6041f4a2713aSLionel Sambuc   SourceRange RegionOfInterest;
6042f4a2713aSLionel Sambuc   RegionOfInterest.setBegin(
6043f4a2713aSLionel Sambuc     cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6044f4a2713aSLionel Sambuc   RegionOfInterest.setEnd(
6045f4a2713aSLionel Sambuc     cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6046f4a2713aSLionel Sambuc                                                          Tokens[NumTokens-1])));
6047f4a2713aSLionel Sambuc 
6048f4a2713aSLionel Sambuc   // Relex the tokens within the source range to look for preprocessing
6049f4a2713aSLionel Sambuc   // directives.
6050f4a2713aSLionel Sambuc   annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
6051f4a2713aSLionel Sambuc 
6052f4a2713aSLionel Sambuc   // If begin location points inside a macro argument, set it to the expansion
6053f4a2713aSLionel Sambuc   // location so we can have the full context when annotating semantically.
6054f4a2713aSLionel Sambuc   {
6055f4a2713aSLionel Sambuc     SourceManager &SM = CXXUnit->getSourceManager();
6056f4a2713aSLionel Sambuc     SourceLocation Loc =
6057f4a2713aSLionel Sambuc         SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6058f4a2713aSLionel Sambuc     if (Loc.isMacroID())
6059f4a2713aSLionel Sambuc       RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6060f4a2713aSLionel Sambuc   }
6061f4a2713aSLionel Sambuc 
6062f4a2713aSLionel Sambuc   if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6063f4a2713aSLionel Sambuc     // Search and mark tokens that are macro argument expansions.
6064f4a2713aSLionel Sambuc     MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6065f4a2713aSLionel Sambuc                                       Tokens, NumTokens);
6066f4a2713aSLionel Sambuc     CursorVisitor MacroArgMarker(TU,
6067f4a2713aSLionel Sambuc                                  MarkMacroArgTokensVisitorDelegate, &Visitor,
6068f4a2713aSLionel Sambuc                                  /*VisitPreprocessorLast=*/true,
6069f4a2713aSLionel Sambuc                                  /*VisitIncludedEntities=*/false,
6070f4a2713aSLionel Sambuc                                  RegionOfInterest);
6071f4a2713aSLionel Sambuc     MacroArgMarker.visitPreprocessedEntitiesInRegion();
6072f4a2713aSLionel Sambuc   }
6073f4a2713aSLionel Sambuc 
6074f4a2713aSLionel Sambuc   // Annotate all of the source locations in the region of interest that map to
6075f4a2713aSLionel Sambuc   // a specific cursor.
6076f4a2713aSLionel Sambuc   AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
6077f4a2713aSLionel Sambuc 
6078f4a2713aSLionel Sambuc   // FIXME: We use a ridiculous stack size here because the data-recursion
6079f4a2713aSLionel Sambuc   // algorithm uses a large stack frame than the non-data recursive version,
6080f4a2713aSLionel Sambuc   // and AnnotationTokensWorker currently transforms the data-recursion
6081f4a2713aSLionel Sambuc   // algorithm back into a traditional recursion by explicitly calling
6082f4a2713aSLionel Sambuc   // VisitChildren().  We will need to remove this explicit recursive call.
6083f4a2713aSLionel Sambuc   W.AnnotateTokens();
6084f4a2713aSLionel Sambuc 
6085f4a2713aSLionel Sambuc   // If we ran into any entities that involve context-sensitive keywords,
6086f4a2713aSLionel Sambuc   // take another pass through the tokens to mark them as such.
6087f4a2713aSLionel Sambuc   if (W.hasContextSensitiveKeywords()) {
6088f4a2713aSLionel Sambuc     for (unsigned I = 0; I != NumTokens; ++I) {
6089f4a2713aSLionel Sambuc       if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6090f4a2713aSLionel Sambuc         continue;
6091f4a2713aSLionel Sambuc 
6092f4a2713aSLionel Sambuc       if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6093f4a2713aSLionel Sambuc         IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6094f4a2713aSLionel Sambuc         if (const ObjCPropertyDecl *Property
6095f4a2713aSLionel Sambuc             = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6096f4a2713aSLionel Sambuc           if (Property->getPropertyAttributesAsWritten() != 0 &&
6097f4a2713aSLionel Sambuc               llvm::StringSwitch<bool>(II->getName())
6098f4a2713aSLionel Sambuc               .Case("readonly", true)
6099f4a2713aSLionel Sambuc               .Case("assign", true)
6100f4a2713aSLionel Sambuc               .Case("unsafe_unretained", true)
6101f4a2713aSLionel Sambuc               .Case("readwrite", true)
6102f4a2713aSLionel Sambuc               .Case("retain", true)
6103f4a2713aSLionel Sambuc               .Case("copy", true)
6104f4a2713aSLionel Sambuc               .Case("nonatomic", true)
6105f4a2713aSLionel Sambuc               .Case("atomic", true)
6106f4a2713aSLionel Sambuc               .Case("getter", true)
6107f4a2713aSLionel Sambuc               .Case("setter", true)
6108f4a2713aSLionel Sambuc               .Case("strong", true)
6109f4a2713aSLionel Sambuc               .Case("weak", true)
6110f4a2713aSLionel Sambuc               .Default(false))
6111f4a2713aSLionel Sambuc             Tokens[I].int_data[0] = CXToken_Keyword;
6112f4a2713aSLionel Sambuc         }
6113f4a2713aSLionel Sambuc         continue;
6114f4a2713aSLionel Sambuc       }
6115f4a2713aSLionel Sambuc 
6116f4a2713aSLionel Sambuc       if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6117f4a2713aSLionel Sambuc           Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6118f4a2713aSLionel Sambuc         IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6119f4a2713aSLionel Sambuc         if (llvm::StringSwitch<bool>(II->getName())
6120f4a2713aSLionel Sambuc             .Case("in", true)
6121f4a2713aSLionel Sambuc             .Case("out", true)
6122f4a2713aSLionel Sambuc             .Case("inout", true)
6123f4a2713aSLionel Sambuc             .Case("oneway", true)
6124f4a2713aSLionel Sambuc             .Case("bycopy", true)
6125f4a2713aSLionel Sambuc             .Case("byref", true)
6126f4a2713aSLionel Sambuc             .Default(false))
6127f4a2713aSLionel Sambuc           Tokens[I].int_data[0] = CXToken_Keyword;
6128f4a2713aSLionel Sambuc         continue;
6129f4a2713aSLionel Sambuc       }
6130f4a2713aSLionel Sambuc 
6131f4a2713aSLionel Sambuc       if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6132f4a2713aSLionel Sambuc           Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6133f4a2713aSLionel Sambuc         Tokens[I].int_data[0] = CXToken_Keyword;
6134f4a2713aSLionel Sambuc         continue;
6135f4a2713aSLionel Sambuc       }
6136f4a2713aSLionel Sambuc     }
6137f4a2713aSLionel Sambuc   }
6138f4a2713aSLionel Sambuc }
6139f4a2713aSLionel Sambuc 
6140f4a2713aSLionel Sambuc extern "C" {
6141f4a2713aSLionel Sambuc 
clang_annotateTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens,CXCursor * Cursors)6142f4a2713aSLionel Sambuc void clang_annotateTokens(CXTranslationUnit TU,
6143f4a2713aSLionel Sambuc                           CXToken *Tokens, unsigned NumTokens,
6144f4a2713aSLionel Sambuc                           CXCursor *Cursors) {
6145*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
6146*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
6147*0a6a1f1dSLionel Sambuc     return;
6148*0a6a1f1dSLionel Sambuc   }
6149*0a6a1f1dSLionel Sambuc   if (NumTokens == 0 || !Tokens || !Cursors) {
6150f4a2713aSLionel Sambuc     LOG_FUNC_SECTION { *Log << "<null input>"; }
6151f4a2713aSLionel Sambuc     return;
6152f4a2713aSLionel Sambuc   }
6153f4a2713aSLionel Sambuc 
6154f4a2713aSLionel Sambuc   LOG_FUNC_SECTION {
6155f4a2713aSLionel Sambuc     *Log << TU << ' ';
6156f4a2713aSLionel Sambuc     CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6157f4a2713aSLionel Sambuc     CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6158f4a2713aSLionel Sambuc     *Log << clang_getRange(bloc, eloc);
6159f4a2713aSLionel Sambuc   }
6160f4a2713aSLionel Sambuc 
6161f4a2713aSLionel Sambuc   // Any token we don't specifically annotate will have a NULL cursor.
6162f4a2713aSLionel Sambuc   CXCursor C = clang_getNullCursor();
6163f4a2713aSLionel Sambuc   for (unsigned I = 0; I != NumTokens; ++I)
6164f4a2713aSLionel Sambuc     Cursors[I] = C;
6165f4a2713aSLionel Sambuc 
6166f4a2713aSLionel Sambuc   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6167f4a2713aSLionel Sambuc   if (!CXXUnit)
6168f4a2713aSLionel Sambuc     return;
6169f4a2713aSLionel Sambuc 
6170f4a2713aSLionel Sambuc   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6171f4a2713aSLionel Sambuc 
6172f4a2713aSLionel Sambuc   clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
6173f4a2713aSLionel Sambuc   llvm::CrashRecoveryContext CRC;
6174f4a2713aSLionel Sambuc   if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
6175f4a2713aSLionel Sambuc                  GetSafetyThreadStackSize() * 2)) {
6176f4a2713aSLionel Sambuc     fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6177f4a2713aSLionel Sambuc   }
6178f4a2713aSLionel Sambuc }
6179f4a2713aSLionel Sambuc 
6180f4a2713aSLionel Sambuc } // end: extern "C"
6181f4a2713aSLionel Sambuc 
6182f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6183f4a2713aSLionel Sambuc // Operations for querying linkage of a cursor.
6184f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6185f4a2713aSLionel Sambuc 
6186f4a2713aSLionel Sambuc extern "C" {
clang_getCursorLinkage(CXCursor cursor)6187f4a2713aSLionel Sambuc CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6188f4a2713aSLionel Sambuc   if (!clang_isDeclaration(cursor.kind))
6189f4a2713aSLionel Sambuc     return CXLinkage_Invalid;
6190f4a2713aSLionel Sambuc 
6191f4a2713aSLionel Sambuc   const Decl *D = cxcursor::getCursorDecl(cursor);
6192f4a2713aSLionel Sambuc   if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6193f4a2713aSLionel Sambuc     switch (ND->getLinkageInternal()) {
6194f4a2713aSLionel Sambuc       case NoLinkage:
6195f4a2713aSLionel Sambuc       case VisibleNoLinkage: return CXLinkage_NoLinkage;
6196f4a2713aSLionel Sambuc       case InternalLinkage: return CXLinkage_Internal;
6197f4a2713aSLionel Sambuc       case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6198f4a2713aSLionel Sambuc       case ExternalLinkage: return CXLinkage_External;
6199f4a2713aSLionel Sambuc     };
6200f4a2713aSLionel Sambuc 
6201f4a2713aSLionel Sambuc   return CXLinkage_Invalid;
6202f4a2713aSLionel Sambuc }
6203f4a2713aSLionel Sambuc } // end: extern "C"
6204f4a2713aSLionel Sambuc 
6205f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6206f4a2713aSLionel Sambuc // Operations for querying language of a cursor.
6207f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6208f4a2713aSLionel Sambuc 
getDeclLanguage(const Decl * D)6209f4a2713aSLionel Sambuc static CXLanguageKind getDeclLanguage(const Decl *D) {
6210f4a2713aSLionel Sambuc   if (!D)
6211f4a2713aSLionel Sambuc     return CXLanguage_C;
6212f4a2713aSLionel Sambuc 
6213f4a2713aSLionel Sambuc   switch (D->getKind()) {
6214f4a2713aSLionel Sambuc     default:
6215f4a2713aSLionel Sambuc       break;
6216f4a2713aSLionel Sambuc     case Decl::ImplicitParam:
6217f4a2713aSLionel Sambuc     case Decl::ObjCAtDefsField:
6218f4a2713aSLionel Sambuc     case Decl::ObjCCategory:
6219f4a2713aSLionel Sambuc     case Decl::ObjCCategoryImpl:
6220f4a2713aSLionel Sambuc     case Decl::ObjCCompatibleAlias:
6221f4a2713aSLionel Sambuc     case Decl::ObjCImplementation:
6222f4a2713aSLionel Sambuc     case Decl::ObjCInterface:
6223f4a2713aSLionel Sambuc     case Decl::ObjCIvar:
6224f4a2713aSLionel Sambuc     case Decl::ObjCMethod:
6225f4a2713aSLionel Sambuc     case Decl::ObjCProperty:
6226f4a2713aSLionel Sambuc     case Decl::ObjCPropertyImpl:
6227f4a2713aSLionel Sambuc     case Decl::ObjCProtocol:
6228f4a2713aSLionel Sambuc       return CXLanguage_ObjC;
6229f4a2713aSLionel Sambuc     case Decl::CXXConstructor:
6230f4a2713aSLionel Sambuc     case Decl::CXXConversion:
6231f4a2713aSLionel Sambuc     case Decl::CXXDestructor:
6232f4a2713aSLionel Sambuc     case Decl::CXXMethod:
6233f4a2713aSLionel Sambuc     case Decl::CXXRecord:
6234f4a2713aSLionel Sambuc     case Decl::ClassTemplate:
6235f4a2713aSLionel Sambuc     case Decl::ClassTemplatePartialSpecialization:
6236f4a2713aSLionel Sambuc     case Decl::ClassTemplateSpecialization:
6237f4a2713aSLionel Sambuc     case Decl::Friend:
6238f4a2713aSLionel Sambuc     case Decl::FriendTemplate:
6239f4a2713aSLionel Sambuc     case Decl::FunctionTemplate:
6240f4a2713aSLionel Sambuc     case Decl::LinkageSpec:
6241f4a2713aSLionel Sambuc     case Decl::Namespace:
6242f4a2713aSLionel Sambuc     case Decl::NamespaceAlias:
6243f4a2713aSLionel Sambuc     case Decl::NonTypeTemplateParm:
6244f4a2713aSLionel Sambuc     case Decl::StaticAssert:
6245f4a2713aSLionel Sambuc     case Decl::TemplateTemplateParm:
6246f4a2713aSLionel Sambuc     case Decl::TemplateTypeParm:
6247f4a2713aSLionel Sambuc     case Decl::UnresolvedUsingTypename:
6248f4a2713aSLionel Sambuc     case Decl::UnresolvedUsingValue:
6249f4a2713aSLionel Sambuc     case Decl::Using:
6250f4a2713aSLionel Sambuc     case Decl::UsingDirective:
6251f4a2713aSLionel Sambuc     case Decl::UsingShadow:
6252f4a2713aSLionel Sambuc       return CXLanguage_CPlusPlus;
6253f4a2713aSLionel Sambuc   }
6254f4a2713aSLionel Sambuc 
6255f4a2713aSLionel Sambuc   return CXLanguage_C;
6256f4a2713aSLionel Sambuc }
6257f4a2713aSLionel Sambuc 
6258f4a2713aSLionel Sambuc extern "C" {
6259f4a2713aSLionel Sambuc 
getCursorAvailabilityForDecl(const Decl * D)6260f4a2713aSLionel Sambuc static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6261f4a2713aSLionel Sambuc   if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6262f4a2713aSLionel Sambuc     return CXAvailability_Available;
6263f4a2713aSLionel Sambuc 
6264f4a2713aSLionel Sambuc   switch (D->getAvailability()) {
6265f4a2713aSLionel Sambuc   case AR_Available:
6266f4a2713aSLionel Sambuc   case AR_NotYetIntroduced:
6267f4a2713aSLionel Sambuc     if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6268f4a2713aSLionel Sambuc       return getCursorAvailabilityForDecl(
6269f4a2713aSLionel Sambuc           cast<Decl>(EnumConst->getDeclContext()));
6270f4a2713aSLionel Sambuc     return CXAvailability_Available;
6271f4a2713aSLionel Sambuc 
6272f4a2713aSLionel Sambuc   case AR_Deprecated:
6273f4a2713aSLionel Sambuc     return CXAvailability_Deprecated;
6274f4a2713aSLionel Sambuc 
6275f4a2713aSLionel Sambuc   case AR_Unavailable:
6276f4a2713aSLionel Sambuc     return CXAvailability_NotAvailable;
6277f4a2713aSLionel Sambuc   }
6278f4a2713aSLionel Sambuc 
6279f4a2713aSLionel Sambuc   llvm_unreachable("Unknown availability kind!");
6280f4a2713aSLionel Sambuc }
6281f4a2713aSLionel Sambuc 
clang_getCursorAvailability(CXCursor cursor)6282f4a2713aSLionel Sambuc enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6283f4a2713aSLionel Sambuc   if (clang_isDeclaration(cursor.kind))
6284f4a2713aSLionel Sambuc     if (const Decl *D = cxcursor::getCursorDecl(cursor))
6285f4a2713aSLionel Sambuc       return getCursorAvailabilityForDecl(D);
6286f4a2713aSLionel Sambuc 
6287f4a2713aSLionel Sambuc   return CXAvailability_Available;
6288f4a2713aSLionel Sambuc }
6289f4a2713aSLionel Sambuc 
convertVersion(VersionTuple In)6290f4a2713aSLionel Sambuc static CXVersion convertVersion(VersionTuple In) {
6291f4a2713aSLionel Sambuc   CXVersion Out = { -1, -1, -1 };
6292f4a2713aSLionel Sambuc   if (In.empty())
6293f4a2713aSLionel Sambuc     return Out;
6294f4a2713aSLionel Sambuc 
6295f4a2713aSLionel Sambuc   Out.Major = In.getMajor();
6296f4a2713aSLionel Sambuc 
6297f4a2713aSLionel Sambuc   Optional<unsigned> Minor = In.getMinor();
6298f4a2713aSLionel Sambuc   if (Minor.hasValue())
6299f4a2713aSLionel Sambuc     Out.Minor = *Minor;
6300f4a2713aSLionel Sambuc   else
6301f4a2713aSLionel Sambuc     return Out;
6302f4a2713aSLionel Sambuc 
6303f4a2713aSLionel Sambuc   Optional<unsigned> Subminor = In.getSubminor();
6304f4a2713aSLionel Sambuc   if (Subminor.hasValue())
6305f4a2713aSLionel Sambuc     Out.Subminor = *Subminor;
6306f4a2713aSLionel Sambuc 
6307f4a2713aSLionel Sambuc   return Out;
6308f4a2713aSLionel Sambuc }
6309f4a2713aSLionel Sambuc 
getCursorPlatformAvailabilityForDecl(const Decl * D,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,CXPlatformAvailability * availability,int availability_size)6310f4a2713aSLionel Sambuc static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6311f4a2713aSLionel Sambuc                                                 int *always_deprecated,
6312f4a2713aSLionel Sambuc                                                 CXString *deprecated_message,
6313f4a2713aSLionel Sambuc                                                 int *always_unavailable,
6314f4a2713aSLionel Sambuc                                                 CXString *unavailable_message,
6315f4a2713aSLionel Sambuc                                            CXPlatformAvailability *availability,
6316f4a2713aSLionel Sambuc                                                 int availability_size) {
6317f4a2713aSLionel Sambuc   bool HadAvailAttr = false;
6318f4a2713aSLionel Sambuc   int N = 0;
6319*0a6a1f1dSLionel Sambuc   for (auto A : D->attrs()) {
6320*0a6a1f1dSLionel Sambuc     if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
6321f4a2713aSLionel Sambuc       HadAvailAttr = true;
6322f4a2713aSLionel Sambuc       if (always_deprecated)
6323f4a2713aSLionel Sambuc         *always_deprecated = 1;
6324*0a6a1f1dSLionel Sambuc       if (deprecated_message) {
6325*0a6a1f1dSLionel Sambuc         clang_disposeString(*deprecated_message);
6326f4a2713aSLionel Sambuc         *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6327*0a6a1f1dSLionel Sambuc       }
6328f4a2713aSLionel Sambuc       continue;
6329f4a2713aSLionel Sambuc     }
6330f4a2713aSLionel Sambuc 
6331*0a6a1f1dSLionel Sambuc     if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
6332f4a2713aSLionel Sambuc       HadAvailAttr = true;
6333f4a2713aSLionel Sambuc       if (always_unavailable)
6334f4a2713aSLionel Sambuc         *always_unavailable = 1;
6335f4a2713aSLionel Sambuc       if (unavailable_message) {
6336*0a6a1f1dSLionel Sambuc         clang_disposeString(*unavailable_message);
6337f4a2713aSLionel Sambuc         *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6338f4a2713aSLionel Sambuc       }
6339f4a2713aSLionel Sambuc       continue;
6340f4a2713aSLionel Sambuc     }
6341f4a2713aSLionel Sambuc 
6342*0a6a1f1dSLionel Sambuc     if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
6343f4a2713aSLionel Sambuc       HadAvailAttr = true;
6344f4a2713aSLionel Sambuc       if (N < availability_size) {
6345f4a2713aSLionel Sambuc         availability[N].Platform
6346f4a2713aSLionel Sambuc           = cxstring::createDup(Avail->getPlatform()->getName());
6347f4a2713aSLionel Sambuc         availability[N].Introduced = convertVersion(Avail->getIntroduced());
6348f4a2713aSLionel Sambuc         availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6349f4a2713aSLionel Sambuc         availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6350f4a2713aSLionel Sambuc         availability[N].Unavailable = Avail->getUnavailable();
6351f4a2713aSLionel Sambuc         availability[N].Message = cxstring::createDup(Avail->getMessage());
6352f4a2713aSLionel Sambuc       }
6353f4a2713aSLionel Sambuc       ++N;
6354f4a2713aSLionel Sambuc     }
6355f4a2713aSLionel Sambuc   }
6356f4a2713aSLionel Sambuc 
6357f4a2713aSLionel Sambuc   if (!HadAvailAttr)
6358f4a2713aSLionel Sambuc     if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6359f4a2713aSLionel Sambuc       return getCursorPlatformAvailabilityForDecl(
6360f4a2713aSLionel Sambuc                                         cast<Decl>(EnumConst->getDeclContext()),
6361f4a2713aSLionel Sambuc                                                   always_deprecated,
6362f4a2713aSLionel Sambuc                                                   deprecated_message,
6363f4a2713aSLionel Sambuc                                                   always_unavailable,
6364f4a2713aSLionel Sambuc                                                   unavailable_message,
6365f4a2713aSLionel Sambuc                                                   availability,
6366f4a2713aSLionel Sambuc                                                   availability_size);
6367f4a2713aSLionel Sambuc 
6368f4a2713aSLionel Sambuc   return N;
6369f4a2713aSLionel Sambuc }
6370f4a2713aSLionel Sambuc 
clang_getCursorPlatformAvailability(CXCursor cursor,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,CXPlatformAvailability * availability,int availability_size)6371f4a2713aSLionel Sambuc int clang_getCursorPlatformAvailability(CXCursor cursor,
6372f4a2713aSLionel Sambuc                                         int *always_deprecated,
6373f4a2713aSLionel Sambuc                                         CXString *deprecated_message,
6374f4a2713aSLionel Sambuc                                         int *always_unavailable,
6375f4a2713aSLionel Sambuc                                         CXString *unavailable_message,
6376f4a2713aSLionel Sambuc                                         CXPlatformAvailability *availability,
6377f4a2713aSLionel Sambuc                                         int availability_size) {
6378f4a2713aSLionel Sambuc   if (always_deprecated)
6379f4a2713aSLionel Sambuc     *always_deprecated = 0;
6380f4a2713aSLionel Sambuc   if (deprecated_message)
6381f4a2713aSLionel Sambuc     *deprecated_message = cxstring::createEmpty();
6382f4a2713aSLionel Sambuc   if (always_unavailable)
6383f4a2713aSLionel Sambuc     *always_unavailable = 0;
6384f4a2713aSLionel Sambuc   if (unavailable_message)
6385f4a2713aSLionel Sambuc     *unavailable_message = cxstring::createEmpty();
6386f4a2713aSLionel Sambuc 
6387f4a2713aSLionel Sambuc   if (!clang_isDeclaration(cursor.kind))
6388f4a2713aSLionel Sambuc     return 0;
6389f4a2713aSLionel Sambuc 
6390f4a2713aSLionel Sambuc   const Decl *D = cxcursor::getCursorDecl(cursor);
6391f4a2713aSLionel Sambuc   if (!D)
6392f4a2713aSLionel Sambuc     return 0;
6393f4a2713aSLionel Sambuc 
6394f4a2713aSLionel Sambuc   return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6395f4a2713aSLionel Sambuc                                               deprecated_message,
6396f4a2713aSLionel Sambuc                                               always_unavailable,
6397f4a2713aSLionel Sambuc                                               unavailable_message,
6398f4a2713aSLionel Sambuc                                               availability,
6399f4a2713aSLionel Sambuc                                               availability_size);
6400f4a2713aSLionel Sambuc }
6401f4a2713aSLionel Sambuc 
clang_disposeCXPlatformAvailability(CXPlatformAvailability * availability)6402f4a2713aSLionel Sambuc void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6403f4a2713aSLionel Sambuc   clang_disposeString(availability->Platform);
6404f4a2713aSLionel Sambuc   clang_disposeString(availability->Message);
6405f4a2713aSLionel Sambuc }
6406f4a2713aSLionel Sambuc 
clang_getCursorLanguage(CXCursor cursor)6407f4a2713aSLionel Sambuc CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6408f4a2713aSLionel Sambuc   if (clang_isDeclaration(cursor.kind))
6409f4a2713aSLionel Sambuc     return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6410f4a2713aSLionel Sambuc 
6411f4a2713aSLionel Sambuc   return CXLanguage_Invalid;
6412f4a2713aSLionel Sambuc }
6413f4a2713aSLionel Sambuc 
6414f4a2713aSLionel Sambuc  /// \brief If the given cursor is the "templated" declaration
6415f4a2713aSLionel Sambuc  /// descibing a class or function template, return the class or
6416f4a2713aSLionel Sambuc  /// function template.
maybeGetTemplateCursor(const Decl * D)6417f4a2713aSLionel Sambuc static const Decl *maybeGetTemplateCursor(const Decl *D) {
6418f4a2713aSLionel Sambuc   if (!D)
6419*0a6a1f1dSLionel Sambuc     return nullptr;
6420f4a2713aSLionel Sambuc 
6421f4a2713aSLionel Sambuc   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6422f4a2713aSLionel Sambuc     if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6423f4a2713aSLionel Sambuc       return FunTmpl;
6424f4a2713aSLionel Sambuc 
6425f4a2713aSLionel Sambuc   if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
6426f4a2713aSLionel Sambuc     if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6427f4a2713aSLionel Sambuc       return ClassTmpl;
6428f4a2713aSLionel Sambuc 
6429f4a2713aSLionel Sambuc   return D;
6430f4a2713aSLionel Sambuc }
6431f4a2713aSLionel Sambuc 
6432*0a6a1f1dSLionel Sambuc 
clang_Cursor_getStorageClass(CXCursor C)6433*0a6a1f1dSLionel Sambuc enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6434*0a6a1f1dSLionel Sambuc   StorageClass sc = SC_None;
6435*0a6a1f1dSLionel Sambuc   const Decl *D = getCursorDecl(C);
6436*0a6a1f1dSLionel Sambuc   if (D) {
6437*0a6a1f1dSLionel Sambuc     if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6438*0a6a1f1dSLionel Sambuc       sc = FD->getStorageClass();
6439*0a6a1f1dSLionel Sambuc     } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6440*0a6a1f1dSLionel Sambuc       sc = VD->getStorageClass();
6441*0a6a1f1dSLionel Sambuc     } else {
6442*0a6a1f1dSLionel Sambuc       return CX_SC_Invalid;
6443*0a6a1f1dSLionel Sambuc     }
6444*0a6a1f1dSLionel Sambuc   } else {
6445*0a6a1f1dSLionel Sambuc     return CX_SC_Invalid;
6446*0a6a1f1dSLionel Sambuc   }
6447*0a6a1f1dSLionel Sambuc   switch (sc) {
6448*0a6a1f1dSLionel Sambuc   case SC_None:
6449*0a6a1f1dSLionel Sambuc     return CX_SC_None;
6450*0a6a1f1dSLionel Sambuc   case SC_Extern:
6451*0a6a1f1dSLionel Sambuc     return CX_SC_Extern;
6452*0a6a1f1dSLionel Sambuc   case SC_Static:
6453*0a6a1f1dSLionel Sambuc     return CX_SC_Static;
6454*0a6a1f1dSLionel Sambuc   case SC_PrivateExtern:
6455*0a6a1f1dSLionel Sambuc     return CX_SC_PrivateExtern;
6456*0a6a1f1dSLionel Sambuc   case SC_OpenCLWorkGroupLocal:
6457*0a6a1f1dSLionel Sambuc     return CX_SC_OpenCLWorkGroupLocal;
6458*0a6a1f1dSLionel Sambuc   case SC_Auto:
6459*0a6a1f1dSLionel Sambuc     return CX_SC_Auto;
6460*0a6a1f1dSLionel Sambuc   case SC_Register:
6461*0a6a1f1dSLionel Sambuc     return CX_SC_Register;
6462*0a6a1f1dSLionel Sambuc   }
6463*0a6a1f1dSLionel Sambuc   llvm_unreachable("Unhandled storage class!");
6464*0a6a1f1dSLionel Sambuc }
6465*0a6a1f1dSLionel Sambuc 
clang_getCursorSemanticParent(CXCursor cursor)6466f4a2713aSLionel Sambuc CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6467f4a2713aSLionel Sambuc   if (clang_isDeclaration(cursor.kind)) {
6468f4a2713aSLionel Sambuc     if (const Decl *D = getCursorDecl(cursor)) {
6469f4a2713aSLionel Sambuc       const DeclContext *DC = D->getDeclContext();
6470f4a2713aSLionel Sambuc       if (!DC)
6471f4a2713aSLionel Sambuc         return clang_getNullCursor();
6472f4a2713aSLionel Sambuc 
6473f4a2713aSLionel Sambuc       return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6474f4a2713aSLionel Sambuc                           getCursorTU(cursor));
6475f4a2713aSLionel Sambuc     }
6476f4a2713aSLionel Sambuc   }
6477f4a2713aSLionel Sambuc 
6478f4a2713aSLionel Sambuc   if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
6479f4a2713aSLionel Sambuc     if (const Decl *D = getCursorDecl(cursor))
6480f4a2713aSLionel Sambuc       return MakeCXCursor(D, getCursorTU(cursor));
6481f4a2713aSLionel Sambuc   }
6482f4a2713aSLionel Sambuc 
6483f4a2713aSLionel Sambuc   return clang_getNullCursor();
6484f4a2713aSLionel Sambuc }
6485f4a2713aSLionel Sambuc 
clang_getCursorLexicalParent(CXCursor cursor)6486f4a2713aSLionel Sambuc CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6487f4a2713aSLionel Sambuc   if (clang_isDeclaration(cursor.kind)) {
6488f4a2713aSLionel Sambuc     if (const Decl *D = getCursorDecl(cursor)) {
6489f4a2713aSLionel Sambuc       const DeclContext *DC = D->getLexicalDeclContext();
6490f4a2713aSLionel Sambuc       if (!DC)
6491f4a2713aSLionel Sambuc         return clang_getNullCursor();
6492f4a2713aSLionel Sambuc 
6493f4a2713aSLionel Sambuc       return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6494f4a2713aSLionel Sambuc                           getCursorTU(cursor));
6495f4a2713aSLionel Sambuc     }
6496f4a2713aSLionel Sambuc   }
6497f4a2713aSLionel Sambuc 
6498f4a2713aSLionel Sambuc   // FIXME: Note that we can't easily compute the lexical context of a
6499f4a2713aSLionel Sambuc   // statement or expression, so we return nothing.
6500f4a2713aSLionel Sambuc   return clang_getNullCursor();
6501f4a2713aSLionel Sambuc }
6502f4a2713aSLionel Sambuc 
clang_getIncludedFile(CXCursor cursor)6503f4a2713aSLionel Sambuc CXFile clang_getIncludedFile(CXCursor cursor) {
6504f4a2713aSLionel Sambuc   if (cursor.kind != CXCursor_InclusionDirective)
6505*0a6a1f1dSLionel Sambuc     return nullptr;
6506f4a2713aSLionel Sambuc 
6507f4a2713aSLionel Sambuc   const InclusionDirective *ID = getCursorInclusionDirective(cursor);
6508f4a2713aSLionel Sambuc   return const_cast<FileEntry *>(ID->getFile());
6509f4a2713aSLionel Sambuc }
6510f4a2713aSLionel Sambuc 
clang_Cursor_getObjCPropertyAttributes(CXCursor C,unsigned reserved)6511f4a2713aSLionel Sambuc unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6512f4a2713aSLionel Sambuc   if (C.kind != CXCursor_ObjCPropertyDecl)
6513f4a2713aSLionel Sambuc     return CXObjCPropertyAttr_noattr;
6514f4a2713aSLionel Sambuc 
6515f4a2713aSLionel Sambuc   unsigned Result = CXObjCPropertyAttr_noattr;
6516f4a2713aSLionel Sambuc   const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6517f4a2713aSLionel Sambuc   ObjCPropertyDecl::PropertyAttributeKind Attr =
6518f4a2713aSLionel Sambuc       PD->getPropertyAttributesAsWritten();
6519f4a2713aSLionel Sambuc 
6520f4a2713aSLionel Sambuc #define SET_CXOBJCPROP_ATTR(A) \
6521f4a2713aSLionel Sambuc   if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6522f4a2713aSLionel Sambuc     Result |= CXObjCPropertyAttr_##A
6523f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(readonly);
6524f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(getter);
6525f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(assign);
6526f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(readwrite);
6527f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(retain);
6528f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(copy);
6529f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(nonatomic);
6530f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(setter);
6531f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(atomic);
6532f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(weak);
6533f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(strong);
6534f4a2713aSLionel Sambuc   SET_CXOBJCPROP_ATTR(unsafe_unretained);
6535f4a2713aSLionel Sambuc #undef SET_CXOBJCPROP_ATTR
6536f4a2713aSLionel Sambuc 
6537f4a2713aSLionel Sambuc   return Result;
6538f4a2713aSLionel Sambuc }
6539f4a2713aSLionel Sambuc 
clang_Cursor_getObjCDeclQualifiers(CXCursor C)6540f4a2713aSLionel Sambuc unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6541f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
6542f4a2713aSLionel Sambuc     return CXObjCDeclQualifier_None;
6543f4a2713aSLionel Sambuc 
6544f4a2713aSLionel Sambuc   Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6545f4a2713aSLionel Sambuc   const Decl *D = getCursorDecl(C);
6546f4a2713aSLionel Sambuc   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6547f4a2713aSLionel Sambuc     QT = MD->getObjCDeclQualifier();
6548f4a2713aSLionel Sambuc   else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6549f4a2713aSLionel Sambuc     QT = PD->getObjCDeclQualifier();
6550f4a2713aSLionel Sambuc   if (QT == Decl::OBJC_TQ_None)
6551f4a2713aSLionel Sambuc     return CXObjCDeclQualifier_None;
6552f4a2713aSLionel Sambuc 
6553f4a2713aSLionel Sambuc   unsigned Result = CXObjCDeclQualifier_None;
6554f4a2713aSLionel Sambuc   if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6555f4a2713aSLionel Sambuc   if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6556f4a2713aSLionel Sambuc   if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6557f4a2713aSLionel Sambuc   if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6558f4a2713aSLionel Sambuc   if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6559f4a2713aSLionel Sambuc   if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6560f4a2713aSLionel Sambuc 
6561f4a2713aSLionel Sambuc   return Result;
6562f4a2713aSLionel Sambuc }
6563f4a2713aSLionel Sambuc 
clang_Cursor_isObjCOptional(CXCursor C)6564f4a2713aSLionel Sambuc unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6565f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
6566f4a2713aSLionel Sambuc     return 0;
6567f4a2713aSLionel Sambuc 
6568f4a2713aSLionel Sambuc   const Decl *D = getCursorDecl(C);
6569f4a2713aSLionel Sambuc   if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6570f4a2713aSLionel Sambuc     return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6571f4a2713aSLionel Sambuc   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6572f4a2713aSLionel Sambuc     return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6573f4a2713aSLionel Sambuc 
6574f4a2713aSLionel Sambuc   return 0;
6575f4a2713aSLionel Sambuc }
6576f4a2713aSLionel Sambuc 
clang_Cursor_isVariadic(CXCursor C)6577f4a2713aSLionel Sambuc unsigned clang_Cursor_isVariadic(CXCursor C) {
6578f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
6579f4a2713aSLionel Sambuc     return 0;
6580f4a2713aSLionel Sambuc 
6581f4a2713aSLionel Sambuc   const Decl *D = getCursorDecl(C);
6582f4a2713aSLionel Sambuc   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6583f4a2713aSLionel Sambuc     return FD->isVariadic();
6584f4a2713aSLionel Sambuc   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6585f4a2713aSLionel Sambuc     return MD->isVariadic();
6586f4a2713aSLionel Sambuc 
6587f4a2713aSLionel Sambuc   return 0;
6588f4a2713aSLionel Sambuc }
6589f4a2713aSLionel Sambuc 
clang_Cursor_getCommentRange(CXCursor C)6590f4a2713aSLionel Sambuc CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6591f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
6592f4a2713aSLionel Sambuc     return clang_getNullRange();
6593f4a2713aSLionel Sambuc 
6594f4a2713aSLionel Sambuc   const Decl *D = getCursorDecl(C);
6595f4a2713aSLionel Sambuc   ASTContext &Context = getCursorContext(C);
6596f4a2713aSLionel Sambuc   const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6597f4a2713aSLionel Sambuc   if (!RC)
6598f4a2713aSLionel Sambuc     return clang_getNullRange();
6599f4a2713aSLionel Sambuc 
6600f4a2713aSLionel Sambuc   return cxloc::translateSourceRange(Context, RC->getSourceRange());
6601f4a2713aSLionel Sambuc }
6602f4a2713aSLionel Sambuc 
clang_Cursor_getRawCommentText(CXCursor C)6603f4a2713aSLionel Sambuc CXString clang_Cursor_getRawCommentText(CXCursor C) {
6604f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
6605f4a2713aSLionel Sambuc     return cxstring::createNull();
6606f4a2713aSLionel Sambuc 
6607f4a2713aSLionel Sambuc   const Decl *D = getCursorDecl(C);
6608f4a2713aSLionel Sambuc   ASTContext &Context = getCursorContext(C);
6609f4a2713aSLionel Sambuc   const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6610f4a2713aSLionel Sambuc   StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6611f4a2713aSLionel Sambuc                            StringRef();
6612f4a2713aSLionel Sambuc 
6613f4a2713aSLionel Sambuc   // Don't duplicate the string because RawText points directly into source
6614f4a2713aSLionel Sambuc   // code.
6615f4a2713aSLionel Sambuc   return cxstring::createRef(RawText);
6616f4a2713aSLionel Sambuc }
6617f4a2713aSLionel Sambuc 
clang_Cursor_getBriefCommentText(CXCursor C)6618f4a2713aSLionel Sambuc CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6619f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
6620f4a2713aSLionel Sambuc     return cxstring::createNull();
6621f4a2713aSLionel Sambuc 
6622f4a2713aSLionel Sambuc   const Decl *D = getCursorDecl(C);
6623f4a2713aSLionel Sambuc   const ASTContext &Context = getCursorContext(C);
6624f4a2713aSLionel Sambuc   const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6625f4a2713aSLionel Sambuc 
6626f4a2713aSLionel Sambuc   if (RC) {
6627f4a2713aSLionel Sambuc     StringRef BriefText = RC->getBriefText(Context);
6628f4a2713aSLionel Sambuc 
6629f4a2713aSLionel Sambuc     // Don't duplicate the string because RawComment ensures that this memory
6630f4a2713aSLionel Sambuc     // will not go away.
6631f4a2713aSLionel Sambuc     return cxstring::createRef(BriefText);
6632f4a2713aSLionel Sambuc   }
6633f4a2713aSLionel Sambuc 
6634f4a2713aSLionel Sambuc   return cxstring::createNull();
6635f4a2713aSLionel Sambuc }
6636f4a2713aSLionel Sambuc 
clang_Cursor_getModule(CXCursor C)6637f4a2713aSLionel Sambuc CXModule clang_Cursor_getModule(CXCursor C) {
6638f4a2713aSLionel Sambuc   if (C.kind == CXCursor_ModuleImportDecl) {
6639f4a2713aSLionel Sambuc     if (const ImportDecl *ImportD =
6640f4a2713aSLionel Sambuc             dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
6641f4a2713aSLionel Sambuc       return ImportD->getImportedModule();
6642f4a2713aSLionel Sambuc   }
6643f4a2713aSLionel Sambuc 
6644*0a6a1f1dSLionel Sambuc   return nullptr;
6645*0a6a1f1dSLionel Sambuc }
6646*0a6a1f1dSLionel Sambuc 
clang_getModuleForFile(CXTranslationUnit TU,CXFile File)6647*0a6a1f1dSLionel Sambuc CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6648*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
6649*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
6650*0a6a1f1dSLionel Sambuc     return nullptr;
6651*0a6a1f1dSLionel Sambuc   }
6652*0a6a1f1dSLionel Sambuc   if (!File)
6653*0a6a1f1dSLionel Sambuc     return nullptr;
6654*0a6a1f1dSLionel Sambuc   FileEntry *FE = static_cast<FileEntry *>(File);
6655*0a6a1f1dSLionel Sambuc 
6656*0a6a1f1dSLionel Sambuc   ASTUnit &Unit = *cxtu::getASTUnit(TU);
6657*0a6a1f1dSLionel Sambuc   HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6658*0a6a1f1dSLionel Sambuc   ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6659*0a6a1f1dSLionel Sambuc 
6660*0a6a1f1dSLionel Sambuc   return Header.getModule();
6661f4a2713aSLionel Sambuc }
6662f4a2713aSLionel Sambuc 
clang_Module_getASTFile(CXModule CXMod)6663f4a2713aSLionel Sambuc CXFile clang_Module_getASTFile(CXModule CXMod) {
6664f4a2713aSLionel Sambuc   if (!CXMod)
6665*0a6a1f1dSLionel Sambuc     return nullptr;
6666f4a2713aSLionel Sambuc   Module *Mod = static_cast<Module*>(CXMod);
6667f4a2713aSLionel Sambuc   return const_cast<FileEntry *>(Mod->getASTFile());
6668f4a2713aSLionel Sambuc }
6669f4a2713aSLionel Sambuc 
clang_Module_getParent(CXModule CXMod)6670f4a2713aSLionel Sambuc CXModule clang_Module_getParent(CXModule CXMod) {
6671f4a2713aSLionel Sambuc   if (!CXMod)
6672*0a6a1f1dSLionel Sambuc     return nullptr;
6673f4a2713aSLionel Sambuc   Module *Mod = static_cast<Module*>(CXMod);
6674f4a2713aSLionel Sambuc   return Mod->Parent;
6675f4a2713aSLionel Sambuc }
6676f4a2713aSLionel Sambuc 
clang_Module_getName(CXModule CXMod)6677f4a2713aSLionel Sambuc CXString clang_Module_getName(CXModule CXMod) {
6678f4a2713aSLionel Sambuc   if (!CXMod)
6679f4a2713aSLionel Sambuc     return cxstring::createEmpty();
6680f4a2713aSLionel Sambuc   Module *Mod = static_cast<Module*>(CXMod);
6681f4a2713aSLionel Sambuc   return cxstring::createDup(Mod->Name);
6682f4a2713aSLionel Sambuc }
6683f4a2713aSLionel Sambuc 
clang_Module_getFullName(CXModule CXMod)6684f4a2713aSLionel Sambuc CXString clang_Module_getFullName(CXModule CXMod) {
6685f4a2713aSLionel Sambuc   if (!CXMod)
6686f4a2713aSLionel Sambuc     return cxstring::createEmpty();
6687f4a2713aSLionel Sambuc   Module *Mod = static_cast<Module*>(CXMod);
6688f4a2713aSLionel Sambuc   return cxstring::createDup(Mod->getFullModuleName());
6689f4a2713aSLionel Sambuc }
6690f4a2713aSLionel Sambuc 
clang_Module_isSystem(CXModule CXMod)6691*0a6a1f1dSLionel Sambuc int clang_Module_isSystem(CXModule CXMod) {
6692*0a6a1f1dSLionel Sambuc   if (!CXMod)
6693*0a6a1f1dSLionel Sambuc     return 0;
6694*0a6a1f1dSLionel Sambuc   Module *Mod = static_cast<Module*>(CXMod);
6695*0a6a1f1dSLionel Sambuc   return Mod->IsSystem;
6696*0a6a1f1dSLionel Sambuc }
6697*0a6a1f1dSLionel Sambuc 
clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,CXModule CXMod)6698f4a2713aSLionel Sambuc unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6699f4a2713aSLionel Sambuc                                             CXModule CXMod) {
6700*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
6701*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
6702*0a6a1f1dSLionel Sambuc     return 0;
6703*0a6a1f1dSLionel Sambuc   }
6704*0a6a1f1dSLionel Sambuc   if (!CXMod)
6705f4a2713aSLionel Sambuc     return 0;
6706f4a2713aSLionel Sambuc   Module *Mod = static_cast<Module*>(CXMod);
6707f4a2713aSLionel Sambuc   FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6708f4a2713aSLionel Sambuc   ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6709f4a2713aSLionel Sambuc   return TopHeaders.size();
6710f4a2713aSLionel Sambuc }
6711f4a2713aSLionel Sambuc 
clang_Module_getTopLevelHeader(CXTranslationUnit TU,CXModule CXMod,unsigned Index)6712f4a2713aSLionel Sambuc CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6713f4a2713aSLionel Sambuc                                       CXModule CXMod, unsigned Index) {
6714*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
6715*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
6716*0a6a1f1dSLionel Sambuc     return nullptr;
6717*0a6a1f1dSLionel Sambuc   }
6718*0a6a1f1dSLionel Sambuc   if (!CXMod)
6719*0a6a1f1dSLionel Sambuc     return nullptr;
6720f4a2713aSLionel Sambuc   Module *Mod = static_cast<Module*>(CXMod);
6721f4a2713aSLionel Sambuc   FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6722f4a2713aSLionel Sambuc 
6723f4a2713aSLionel Sambuc   ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6724f4a2713aSLionel Sambuc   if (Index < TopHeaders.size())
6725f4a2713aSLionel Sambuc     return const_cast<FileEntry *>(TopHeaders[Index]);
6726f4a2713aSLionel Sambuc 
6727*0a6a1f1dSLionel Sambuc   return nullptr;
6728f4a2713aSLionel Sambuc }
6729f4a2713aSLionel Sambuc 
6730f4a2713aSLionel Sambuc } // end: extern "C"
6731f4a2713aSLionel Sambuc 
6732f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6733f4a2713aSLionel Sambuc // C++ AST instrospection.
6734f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6735f4a2713aSLionel Sambuc 
6736f4a2713aSLionel Sambuc extern "C" {
clang_CXXMethod_isPureVirtual(CXCursor C)6737f4a2713aSLionel Sambuc unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6738f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
6739f4a2713aSLionel Sambuc     return 0;
6740f4a2713aSLionel Sambuc 
6741f4a2713aSLionel Sambuc   const Decl *D = cxcursor::getCursorDecl(C);
6742*0a6a1f1dSLionel Sambuc   const CXXMethodDecl *Method =
6743*0a6a1f1dSLionel Sambuc       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
6744f4a2713aSLionel Sambuc   return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6745f4a2713aSLionel Sambuc }
6746f4a2713aSLionel Sambuc 
clang_CXXMethod_isConst(CXCursor C)6747*0a6a1f1dSLionel Sambuc unsigned clang_CXXMethod_isConst(CXCursor C) {
6748*0a6a1f1dSLionel Sambuc   if (!clang_isDeclaration(C.kind))
6749*0a6a1f1dSLionel Sambuc     return 0;
6750*0a6a1f1dSLionel Sambuc 
6751*0a6a1f1dSLionel Sambuc   const Decl *D = cxcursor::getCursorDecl(C);
6752*0a6a1f1dSLionel Sambuc   const CXXMethodDecl *Method =
6753*0a6a1f1dSLionel Sambuc       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
6754*0a6a1f1dSLionel Sambuc   return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6755*0a6a1f1dSLionel Sambuc }
6756*0a6a1f1dSLionel Sambuc 
clang_CXXMethod_isStatic(CXCursor C)6757f4a2713aSLionel Sambuc unsigned clang_CXXMethod_isStatic(CXCursor C) {
6758f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
6759f4a2713aSLionel Sambuc     return 0;
6760f4a2713aSLionel Sambuc 
6761f4a2713aSLionel Sambuc   const Decl *D = cxcursor::getCursorDecl(C);
6762*0a6a1f1dSLionel Sambuc   const CXXMethodDecl *Method =
6763*0a6a1f1dSLionel Sambuc       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
6764f4a2713aSLionel Sambuc   return (Method && Method->isStatic()) ? 1 : 0;
6765f4a2713aSLionel Sambuc }
6766f4a2713aSLionel Sambuc 
clang_CXXMethod_isVirtual(CXCursor C)6767f4a2713aSLionel Sambuc unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6768f4a2713aSLionel Sambuc   if (!clang_isDeclaration(C.kind))
6769f4a2713aSLionel Sambuc     return 0;
6770f4a2713aSLionel Sambuc 
6771f4a2713aSLionel Sambuc   const Decl *D = cxcursor::getCursorDecl(C);
6772*0a6a1f1dSLionel Sambuc   const CXXMethodDecl *Method =
6773*0a6a1f1dSLionel Sambuc       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
6774f4a2713aSLionel Sambuc   return (Method && Method->isVirtual()) ? 1 : 0;
6775f4a2713aSLionel Sambuc }
6776f4a2713aSLionel Sambuc } // end: extern "C"
6777f4a2713aSLionel Sambuc 
6778f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6779f4a2713aSLionel Sambuc // Attribute introspection.
6780f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6781f4a2713aSLionel Sambuc 
6782f4a2713aSLionel Sambuc extern "C" {
clang_getIBOutletCollectionType(CXCursor C)6783f4a2713aSLionel Sambuc CXType clang_getIBOutletCollectionType(CXCursor C) {
6784f4a2713aSLionel Sambuc   if (C.kind != CXCursor_IBOutletCollectionAttr)
6785f4a2713aSLionel Sambuc     return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6786f4a2713aSLionel Sambuc 
6787f4a2713aSLionel Sambuc   const IBOutletCollectionAttr *A =
6788f4a2713aSLionel Sambuc     cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6789f4a2713aSLionel Sambuc 
6790f4a2713aSLionel Sambuc   return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6791f4a2713aSLionel Sambuc }
6792f4a2713aSLionel Sambuc } // end: extern "C"
6793f4a2713aSLionel Sambuc 
6794f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6795f4a2713aSLionel Sambuc // Inspecting memory usage.
6796f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
6797f4a2713aSLionel Sambuc 
6798f4a2713aSLionel Sambuc typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6799f4a2713aSLionel Sambuc 
createCXTUResourceUsageEntry(MemUsageEntries & entries,enum CXTUResourceUsageKind k,unsigned long amount)6800f4a2713aSLionel Sambuc static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6801f4a2713aSLionel Sambuc                                               enum CXTUResourceUsageKind k,
6802f4a2713aSLionel Sambuc                                               unsigned long amount) {
6803f4a2713aSLionel Sambuc   CXTUResourceUsageEntry entry = { k, amount };
6804f4a2713aSLionel Sambuc   entries.push_back(entry);
6805f4a2713aSLionel Sambuc }
6806f4a2713aSLionel Sambuc 
6807f4a2713aSLionel Sambuc extern "C" {
6808f4a2713aSLionel Sambuc 
clang_getTUResourceUsageName(CXTUResourceUsageKind kind)6809f4a2713aSLionel Sambuc const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6810f4a2713aSLionel Sambuc   const char *str = "";
6811f4a2713aSLionel Sambuc   switch (kind) {
6812f4a2713aSLionel Sambuc     case CXTUResourceUsage_AST:
6813f4a2713aSLionel Sambuc       str = "ASTContext: expressions, declarations, and types";
6814f4a2713aSLionel Sambuc       break;
6815f4a2713aSLionel Sambuc     case CXTUResourceUsage_Identifiers:
6816f4a2713aSLionel Sambuc       str = "ASTContext: identifiers";
6817f4a2713aSLionel Sambuc       break;
6818f4a2713aSLionel Sambuc     case CXTUResourceUsage_Selectors:
6819f4a2713aSLionel Sambuc       str = "ASTContext: selectors";
6820f4a2713aSLionel Sambuc       break;
6821f4a2713aSLionel Sambuc     case CXTUResourceUsage_GlobalCompletionResults:
6822f4a2713aSLionel Sambuc       str = "Code completion: cached global results";
6823f4a2713aSLionel Sambuc       break;
6824f4a2713aSLionel Sambuc     case CXTUResourceUsage_SourceManagerContentCache:
6825f4a2713aSLionel Sambuc       str = "SourceManager: content cache allocator";
6826f4a2713aSLionel Sambuc       break;
6827f4a2713aSLionel Sambuc     case CXTUResourceUsage_AST_SideTables:
6828f4a2713aSLionel Sambuc       str = "ASTContext: side tables";
6829f4a2713aSLionel Sambuc       break;
6830f4a2713aSLionel Sambuc     case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6831f4a2713aSLionel Sambuc       str = "SourceManager: malloc'ed memory buffers";
6832f4a2713aSLionel Sambuc       break;
6833f4a2713aSLionel Sambuc     case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6834f4a2713aSLionel Sambuc       str = "SourceManager: mmap'ed memory buffers";
6835f4a2713aSLionel Sambuc       break;
6836f4a2713aSLionel Sambuc     case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6837f4a2713aSLionel Sambuc       str = "ExternalASTSource: malloc'ed memory buffers";
6838f4a2713aSLionel Sambuc       break;
6839f4a2713aSLionel Sambuc     case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6840f4a2713aSLionel Sambuc       str = "ExternalASTSource: mmap'ed memory buffers";
6841f4a2713aSLionel Sambuc       break;
6842f4a2713aSLionel Sambuc     case CXTUResourceUsage_Preprocessor:
6843f4a2713aSLionel Sambuc       str = "Preprocessor: malloc'ed memory";
6844f4a2713aSLionel Sambuc       break;
6845f4a2713aSLionel Sambuc     case CXTUResourceUsage_PreprocessingRecord:
6846f4a2713aSLionel Sambuc       str = "Preprocessor: PreprocessingRecord";
6847f4a2713aSLionel Sambuc       break;
6848f4a2713aSLionel Sambuc     case CXTUResourceUsage_SourceManager_DataStructures:
6849f4a2713aSLionel Sambuc       str = "SourceManager: data structures and tables";
6850f4a2713aSLionel Sambuc       break;
6851f4a2713aSLionel Sambuc     case CXTUResourceUsage_Preprocessor_HeaderSearch:
6852f4a2713aSLionel Sambuc       str = "Preprocessor: header search tables";
6853f4a2713aSLionel Sambuc       break;
6854f4a2713aSLionel Sambuc   }
6855f4a2713aSLionel Sambuc   return str;
6856f4a2713aSLionel Sambuc }
6857f4a2713aSLionel Sambuc 
clang_getCXTUResourceUsage(CXTranslationUnit TU)6858f4a2713aSLionel Sambuc CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6859*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
6860*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
6861*0a6a1f1dSLionel Sambuc     CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
6862f4a2713aSLionel Sambuc     return usage;
6863f4a2713aSLionel Sambuc   }
6864f4a2713aSLionel Sambuc 
6865f4a2713aSLionel Sambuc   ASTUnit *astUnit = cxtu::getASTUnit(TU);
6866*0a6a1f1dSLionel Sambuc   std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
6867f4a2713aSLionel Sambuc   ASTContext &astContext = astUnit->getASTContext();
6868f4a2713aSLionel Sambuc 
6869f4a2713aSLionel Sambuc   // How much memory is used by AST nodes and types?
6870f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6871f4a2713aSLionel Sambuc     (unsigned long) astContext.getASTAllocatedMemory());
6872f4a2713aSLionel Sambuc 
6873f4a2713aSLionel Sambuc   // How much memory is used by identifiers?
6874f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6875f4a2713aSLionel Sambuc     (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6876f4a2713aSLionel Sambuc 
6877f4a2713aSLionel Sambuc   // How much memory is used for selectors?
6878f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6879f4a2713aSLionel Sambuc     (unsigned long) astContext.Selectors.getTotalMemory());
6880f4a2713aSLionel Sambuc 
6881f4a2713aSLionel Sambuc   // How much memory is used by ASTContext's side tables?
6882f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6883f4a2713aSLionel Sambuc     (unsigned long) astContext.getSideTableAllocatedMemory());
6884f4a2713aSLionel Sambuc 
6885f4a2713aSLionel Sambuc   // How much memory is used for caching global code completion results?
6886f4a2713aSLionel Sambuc   unsigned long completionBytes = 0;
6887f4a2713aSLionel Sambuc   if (GlobalCodeCompletionAllocator *completionAllocator =
6888*0a6a1f1dSLionel Sambuc       astUnit->getCachedCompletionAllocator().get()) {
6889f4a2713aSLionel Sambuc     completionBytes = completionAllocator->getTotalMemory();
6890f4a2713aSLionel Sambuc   }
6891f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries,
6892f4a2713aSLionel Sambuc                                CXTUResourceUsage_GlobalCompletionResults,
6893f4a2713aSLionel Sambuc                                completionBytes);
6894f4a2713aSLionel Sambuc 
6895f4a2713aSLionel Sambuc   // How much memory is being used by SourceManager's content cache?
6896f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries,
6897f4a2713aSLionel Sambuc           CXTUResourceUsage_SourceManagerContentCache,
6898f4a2713aSLionel Sambuc           (unsigned long) astContext.getSourceManager().getContentCacheSize());
6899f4a2713aSLionel Sambuc 
6900f4a2713aSLionel Sambuc   // How much memory is being used by the MemoryBuffer's in SourceManager?
6901f4a2713aSLionel Sambuc   const SourceManager::MemoryBufferSizes &srcBufs =
6902f4a2713aSLionel Sambuc     astUnit->getSourceManager().getMemoryBufferSizes();
6903f4a2713aSLionel Sambuc 
6904f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries,
6905f4a2713aSLionel Sambuc                                CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6906f4a2713aSLionel Sambuc                                (unsigned long) srcBufs.malloc_bytes);
6907f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries,
6908f4a2713aSLionel Sambuc                                CXTUResourceUsage_SourceManager_Membuffer_MMap,
6909f4a2713aSLionel Sambuc                                (unsigned long) srcBufs.mmap_bytes);
6910f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries,
6911f4a2713aSLionel Sambuc                                CXTUResourceUsage_SourceManager_DataStructures,
6912f4a2713aSLionel Sambuc                                (unsigned long) astContext.getSourceManager()
6913f4a2713aSLionel Sambuc                                 .getDataStructureSizes());
6914f4a2713aSLionel Sambuc 
6915f4a2713aSLionel Sambuc   // How much memory is being used by the ExternalASTSource?
6916f4a2713aSLionel Sambuc   if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6917f4a2713aSLionel Sambuc     const ExternalASTSource::MemoryBufferSizes &sizes =
6918f4a2713aSLionel Sambuc       esrc->getMemoryBufferSizes();
6919f4a2713aSLionel Sambuc 
6920f4a2713aSLionel Sambuc     createCXTUResourceUsageEntry(*entries,
6921f4a2713aSLionel Sambuc       CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6922f4a2713aSLionel Sambuc                                  (unsigned long) sizes.malloc_bytes);
6923f4a2713aSLionel Sambuc     createCXTUResourceUsageEntry(*entries,
6924f4a2713aSLionel Sambuc       CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6925f4a2713aSLionel Sambuc                                  (unsigned long) sizes.mmap_bytes);
6926f4a2713aSLionel Sambuc   }
6927f4a2713aSLionel Sambuc 
6928f4a2713aSLionel Sambuc   // How much memory is being used by the Preprocessor?
6929f4a2713aSLionel Sambuc   Preprocessor &pp = astUnit->getPreprocessor();
6930f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries,
6931f4a2713aSLionel Sambuc                                CXTUResourceUsage_Preprocessor,
6932f4a2713aSLionel Sambuc                                pp.getTotalMemory());
6933f4a2713aSLionel Sambuc 
6934f4a2713aSLionel Sambuc   if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6935f4a2713aSLionel Sambuc     createCXTUResourceUsageEntry(*entries,
6936f4a2713aSLionel Sambuc                                  CXTUResourceUsage_PreprocessingRecord,
6937f4a2713aSLionel Sambuc                                  pRec->getTotalMemory());
6938f4a2713aSLionel Sambuc   }
6939f4a2713aSLionel Sambuc 
6940f4a2713aSLionel Sambuc   createCXTUResourceUsageEntry(*entries,
6941f4a2713aSLionel Sambuc                                CXTUResourceUsage_Preprocessor_HeaderSearch,
6942f4a2713aSLionel Sambuc                                pp.getHeaderSearchInfo().getTotalMemory());
6943f4a2713aSLionel Sambuc 
6944f4a2713aSLionel Sambuc   CXTUResourceUsage usage = { (void*) entries.get(),
6945f4a2713aSLionel Sambuc                             (unsigned) entries->size(),
6946*0a6a1f1dSLionel Sambuc                             entries->size() ? &(*entries)[0] : nullptr };
6947*0a6a1f1dSLionel Sambuc   entries.release();
6948f4a2713aSLionel Sambuc   return usage;
6949f4a2713aSLionel Sambuc }
6950f4a2713aSLionel Sambuc 
clang_disposeCXTUResourceUsage(CXTUResourceUsage usage)6951f4a2713aSLionel Sambuc void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6952f4a2713aSLionel Sambuc   if (usage.data)
6953f4a2713aSLionel Sambuc     delete (MemUsageEntries*) usage.data;
6954f4a2713aSLionel Sambuc }
6955f4a2713aSLionel Sambuc 
clang_getSkippedRanges(CXTranslationUnit TU,CXFile file)6956*0a6a1f1dSLionel Sambuc CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6957*0a6a1f1dSLionel Sambuc   CXSourceRangeList *skipped = new CXSourceRangeList;
6958*0a6a1f1dSLionel Sambuc   skipped->count = 0;
6959*0a6a1f1dSLionel Sambuc   skipped->ranges = nullptr;
6960*0a6a1f1dSLionel Sambuc 
6961*0a6a1f1dSLionel Sambuc   if (isNotUsableTU(TU)) {
6962*0a6a1f1dSLionel Sambuc     LOG_BAD_TU(TU);
6963*0a6a1f1dSLionel Sambuc     return skipped;
6964*0a6a1f1dSLionel Sambuc   }
6965*0a6a1f1dSLionel Sambuc 
6966*0a6a1f1dSLionel Sambuc   if (!file)
6967*0a6a1f1dSLionel Sambuc     return skipped;
6968*0a6a1f1dSLionel Sambuc 
6969*0a6a1f1dSLionel Sambuc   ASTUnit *astUnit = cxtu::getASTUnit(TU);
6970*0a6a1f1dSLionel Sambuc   PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6971*0a6a1f1dSLionel Sambuc   if (!ppRec)
6972*0a6a1f1dSLionel Sambuc     return skipped;
6973*0a6a1f1dSLionel Sambuc 
6974*0a6a1f1dSLionel Sambuc   ASTContext &Ctx = astUnit->getASTContext();
6975*0a6a1f1dSLionel Sambuc   SourceManager &sm = Ctx.getSourceManager();
6976*0a6a1f1dSLionel Sambuc   FileEntry *fileEntry = static_cast<FileEntry *>(file);
6977*0a6a1f1dSLionel Sambuc   FileID wantedFileID = sm.translateFile(fileEntry);
6978*0a6a1f1dSLionel Sambuc 
6979*0a6a1f1dSLionel Sambuc   const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6980*0a6a1f1dSLionel Sambuc   std::vector<SourceRange> wantedRanges;
6981*0a6a1f1dSLionel Sambuc   for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6982*0a6a1f1dSLionel Sambuc        i != ei; ++i) {
6983*0a6a1f1dSLionel Sambuc     if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6984*0a6a1f1dSLionel Sambuc       wantedRanges.push_back(*i);
6985*0a6a1f1dSLionel Sambuc   }
6986*0a6a1f1dSLionel Sambuc 
6987*0a6a1f1dSLionel Sambuc   skipped->count = wantedRanges.size();
6988*0a6a1f1dSLionel Sambuc   skipped->ranges = new CXSourceRange[skipped->count];
6989*0a6a1f1dSLionel Sambuc   for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6990*0a6a1f1dSLionel Sambuc     skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6991*0a6a1f1dSLionel Sambuc 
6992*0a6a1f1dSLionel Sambuc   return skipped;
6993*0a6a1f1dSLionel Sambuc }
6994*0a6a1f1dSLionel Sambuc 
clang_disposeSourceRangeList(CXSourceRangeList * ranges)6995*0a6a1f1dSLionel Sambuc void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6996*0a6a1f1dSLionel Sambuc   if (ranges) {
6997*0a6a1f1dSLionel Sambuc     delete[] ranges->ranges;
6998*0a6a1f1dSLionel Sambuc     delete ranges;
6999*0a6a1f1dSLionel Sambuc   }
7000*0a6a1f1dSLionel Sambuc }
7001*0a6a1f1dSLionel Sambuc 
7002f4a2713aSLionel Sambuc } // end extern "C"
7003f4a2713aSLionel Sambuc 
PrintLibclangResourceUsage(CXTranslationUnit TU)7004f4a2713aSLionel Sambuc void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7005f4a2713aSLionel Sambuc   CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7006f4a2713aSLionel Sambuc   for (unsigned I = 0; I != Usage.numEntries; ++I)
7007f4a2713aSLionel Sambuc     fprintf(stderr, "  %s: %lu\n",
7008f4a2713aSLionel Sambuc             clang_getTUResourceUsageName(Usage.entries[I].kind),
7009f4a2713aSLionel Sambuc             Usage.entries[I].amount);
7010f4a2713aSLionel Sambuc 
7011f4a2713aSLionel Sambuc   clang_disposeCXTUResourceUsage(Usage);
7012f4a2713aSLionel Sambuc }
7013f4a2713aSLionel Sambuc 
7014f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
7015f4a2713aSLionel Sambuc // Misc. utility functions.
7016f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
7017f4a2713aSLionel Sambuc 
7018f4a2713aSLionel Sambuc /// Default to using an 8 MB stack size on "safety" threads.
7019f4a2713aSLionel Sambuc static unsigned SafetyStackThreadSize = 8 << 20;
7020f4a2713aSLionel Sambuc 
7021f4a2713aSLionel Sambuc namespace clang {
7022f4a2713aSLionel Sambuc 
RunSafely(llvm::CrashRecoveryContext & CRC,void (* Fn)(void *),void * UserData,unsigned Size)7023f4a2713aSLionel Sambuc bool RunSafely(llvm::CrashRecoveryContext &CRC,
7024f4a2713aSLionel Sambuc                void (*Fn)(void*), void *UserData,
7025f4a2713aSLionel Sambuc                unsigned Size) {
7026f4a2713aSLionel Sambuc   if (!Size)
7027f4a2713aSLionel Sambuc     Size = GetSafetyThreadStackSize();
7028f4a2713aSLionel Sambuc   if (Size)
7029f4a2713aSLionel Sambuc     return CRC.RunSafelyOnThread(Fn, UserData, Size);
7030f4a2713aSLionel Sambuc   return CRC.RunSafely(Fn, UserData);
7031f4a2713aSLionel Sambuc }
7032f4a2713aSLionel Sambuc 
GetSafetyThreadStackSize()7033f4a2713aSLionel Sambuc unsigned GetSafetyThreadStackSize() {
7034f4a2713aSLionel Sambuc   return SafetyStackThreadSize;
7035f4a2713aSLionel Sambuc }
7036f4a2713aSLionel Sambuc 
SetSafetyThreadStackSize(unsigned Value)7037f4a2713aSLionel Sambuc void SetSafetyThreadStackSize(unsigned Value) {
7038f4a2713aSLionel Sambuc   SafetyStackThreadSize = Value;
7039f4a2713aSLionel Sambuc }
7040f4a2713aSLionel Sambuc 
7041f4a2713aSLionel Sambuc }
7042f4a2713aSLionel Sambuc 
setThreadBackgroundPriority()7043f4a2713aSLionel Sambuc void clang::setThreadBackgroundPriority() {
7044f4a2713aSLionel Sambuc   if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7045f4a2713aSLionel Sambuc     return;
7046f4a2713aSLionel Sambuc 
7047*0a6a1f1dSLionel Sambuc #ifdef USE_DARWIN_THREADS
7048f4a2713aSLionel Sambuc   setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7049f4a2713aSLionel Sambuc #endif
7050f4a2713aSLionel Sambuc }
7051f4a2713aSLionel Sambuc 
printDiagsToStderr(ASTUnit * Unit)7052f4a2713aSLionel Sambuc void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7053f4a2713aSLionel Sambuc   if (!Unit)
7054f4a2713aSLionel Sambuc     return;
7055f4a2713aSLionel Sambuc 
7056f4a2713aSLionel Sambuc   for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7057f4a2713aSLionel Sambuc                                   DEnd = Unit->stored_diag_end();
7058f4a2713aSLionel Sambuc        D != DEnd; ++D) {
7059*0a6a1f1dSLionel Sambuc     CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
7060f4a2713aSLionel Sambuc     CXString Msg = clang_formatDiagnostic(&Diag,
7061f4a2713aSLionel Sambuc                                 clang_defaultDiagnosticDisplayOptions());
7062f4a2713aSLionel Sambuc     fprintf(stderr, "%s\n", clang_getCString(Msg));
7063f4a2713aSLionel Sambuc     clang_disposeString(Msg);
7064f4a2713aSLionel Sambuc   }
7065f4a2713aSLionel Sambuc #ifdef LLVM_ON_WIN32
7066f4a2713aSLionel Sambuc   // On Windows, force a flush, since there may be multiple copies of
7067f4a2713aSLionel Sambuc   // stderr and stdout in the file system, all with different buffers
7068f4a2713aSLionel Sambuc   // but writing to the same device.
7069f4a2713aSLionel Sambuc   fflush(stderr);
7070f4a2713aSLionel Sambuc #endif
7071f4a2713aSLionel Sambuc }
7072f4a2713aSLionel Sambuc 
getMacroInfo(const IdentifierInfo & II,SourceLocation MacroDefLoc,CXTranslationUnit TU)7073f4a2713aSLionel Sambuc MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7074f4a2713aSLionel Sambuc                                  SourceLocation MacroDefLoc,
7075f4a2713aSLionel Sambuc                                  CXTranslationUnit TU){
7076f4a2713aSLionel Sambuc   if (MacroDefLoc.isInvalid() || !TU)
7077*0a6a1f1dSLionel Sambuc     return nullptr;
7078f4a2713aSLionel Sambuc   if (!II.hadMacroDefinition())
7079*0a6a1f1dSLionel Sambuc     return nullptr;
7080f4a2713aSLionel Sambuc 
7081f4a2713aSLionel Sambuc   ASTUnit *Unit = cxtu::getASTUnit(TU);
7082f4a2713aSLionel Sambuc   Preprocessor &PP = Unit->getPreprocessor();
7083f4a2713aSLionel Sambuc   MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
7084f4a2713aSLionel Sambuc   if (MD) {
7085f4a2713aSLionel Sambuc     for (MacroDirective::DefInfo
7086f4a2713aSLionel Sambuc            Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7087f4a2713aSLionel Sambuc       if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7088f4a2713aSLionel Sambuc         return Def.getMacroInfo();
7089f4a2713aSLionel Sambuc     }
7090f4a2713aSLionel Sambuc   }
7091f4a2713aSLionel Sambuc 
7092*0a6a1f1dSLionel Sambuc   return nullptr;
7093f4a2713aSLionel Sambuc }
7094f4a2713aSLionel Sambuc 
getMacroInfo(const MacroDefinition * MacroDef,CXTranslationUnit TU)7095f4a2713aSLionel Sambuc const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
7096f4a2713aSLionel Sambuc                                        CXTranslationUnit TU) {
7097f4a2713aSLionel Sambuc   if (!MacroDef || !TU)
7098*0a6a1f1dSLionel Sambuc     return nullptr;
7099f4a2713aSLionel Sambuc   const IdentifierInfo *II = MacroDef->getName();
7100f4a2713aSLionel Sambuc   if (!II)
7101*0a6a1f1dSLionel Sambuc     return nullptr;
7102f4a2713aSLionel Sambuc 
7103f4a2713aSLionel Sambuc   return getMacroInfo(*II, MacroDef->getLocation(), TU);
7104f4a2713aSLionel Sambuc }
7105f4a2713aSLionel Sambuc 
checkForMacroInMacroDefinition(const MacroInfo * MI,const Token & Tok,CXTranslationUnit TU)7106f4a2713aSLionel Sambuc MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7107f4a2713aSLionel Sambuc                                                          const Token &Tok,
7108f4a2713aSLionel Sambuc                                                          CXTranslationUnit TU) {
7109f4a2713aSLionel Sambuc   if (!MI || !TU)
7110*0a6a1f1dSLionel Sambuc     return nullptr;
7111f4a2713aSLionel Sambuc   if (Tok.isNot(tok::raw_identifier))
7112*0a6a1f1dSLionel Sambuc     return nullptr;
7113f4a2713aSLionel Sambuc 
7114f4a2713aSLionel Sambuc   if (MI->getNumTokens() == 0)
7115*0a6a1f1dSLionel Sambuc     return nullptr;
7116f4a2713aSLionel Sambuc   SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7117f4a2713aSLionel Sambuc                        MI->getDefinitionEndLoc());
7118f4a2713aSLionel Sambuc   ASTUnit *Unit = cxtu::getASTUnit(TU);
7119f4a2713aSLionel Sambuc 
7120f4a2713aSLionel Sambuc   // Check that the token is inside the definition and not its argument list.
7121f4a2713aSLionel Sambuc   SourceManager &SM = Unit->getSourceManager();
7122f4a2713aSLionel Sambuc   if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
7123*0a6a1f1dSLionel Sambuc     return nullptr;
7124f4a2713aSLionel Sambuc   if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
7125*0a6a1f1dSLionel Sambuc     return nullptr;
7126f4a2713aSLionel Sambuc 
7127f4a2713aSLionel Sambuc   Preprocessor &PP = Unit->getPreprocessor();
7128f4a2713aSLionel Sambuc   PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7129f4a2713aSLionel Sambuc   if (!PPRec)
7130*0a6a1f1dSLionel Sambuc     return nullptr;
7131f4a2713aSLionel Sambuc 
7132*0a6a1f1dSLionel Sambuc   IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
7133f4a2713aSLionel Sambuc   if (!II.hadMacroDefinition())
7134*0a6a1f1dSLionel Sambuc     return nullptr;
7135f4a2713aSLionel Sambuc 
7136f4a2713aSLionel Sambuc   // Check that the identifier is not one of the macro arguments.
7137f4a2713aSLionel Sambuc   if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
7138*0a6a1f1dSLionel Sambuc     return nullptr;
7139f4a2713aSLionel Sambuc 
7140f4a2713aSLionel Sambuc   MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
7141f4a2713aSLionel Sambuc   if (!InnerMD)
7142*0a6a1f1dSLionel Sambuc     return nullptr;
7143f4a2713aSLionel Sambuc 
7144f4a2713aSLionel Sambuc   return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
7145f4a2713aSLionel Sambuc }
7146f4a2713aSLionel Sambuc 
checkForMacroInMacroDefinition(const MacroInfo * MI,SourceLocation Loc,CXTranslationUnit TU)7147f4a2713aSLionel Sambuc MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
7148f4a2713aSLionel Sambuc                                                          SourceLocation Loc,
7149f4a2713aSLionel Sambuc                                                          CXTranslationUnit TU) {
7150f4a2713aSLionel Sambuc   if (Loc.isInvalid() || !MI || !TU)
7151*0a6a1f1dSLionel Sambuc     return nullptr;
7152f4a2713aSLionel Sambuc 
7153f4a2713aSLionel Sambuc   if (MI->getNumTokens() == 0)
7154*0a6a1f1dSLionel Sambuc     return nullptr;
7155f4a2713aSLionel Sambuc   ASTUnit *Unit = cxtu::getASTUnit(TU);
7156f4a2713aSLionel Sambuc   Preprocessor &PP = Unit->getPreprocessor();
7157f4a2713aSLionel Sambuc   if (!PP.getPreprocessingRecord())
7158*0a6a1f1dSLionel Sambuc     return nullptr;
7159f4a2713aSLionel Sambuc   Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7160f4a2713aSLionel Sambuc   Token Tok;
7161f4a2713aSLionel Sambuc   if (PP.getRawToken(Loc, Tok))
7162*0a6a1f1dSLionel Sambuc     return nullptr;
7163f4a2713aSLionel Sambuc 
7164f4a2713aSLionel Sambuc   return checkForMacroInMacroDefinition(MI, Tok, TU);
7165f4a2713aSLionel Sambuc }
7166f4a2713aSLionel Sambuc 
7167f4a2713aSLionel Sambuc extern "C" {
7168f4a2713aSLionel Sambuc 
clang_getClangVersion()7169f4a2713aSLionel Sambuc CXString clang_getClangVersion() {
7170f4a2713aSLionel Sambuc   return cxstring::createDup(getClangFullVersion());
7171f4a2713aSLionel Sambuc }
7172f4a2713aSLionel Sambuc 
7173f4a2713aSLionel Sambuc } // end: extern "C"
7174f4a2713aSLionel Sambuc 
operator <<(CXTranslationUnit TU)7175f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7176f4a2713aSLionel Sambuc   if (TU) {
7177f4a2713aSLionel Sambuc     if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
7178f4a2713aSLionel Sambuc       LogOS << '<' << Unit->getMainFileName() << '>';
7179f4a2713aSLionel Sambuc       if (Unit->isMainFileAST())
7180f4a2713aSLionel Sambuc         LogOS << " (" << Unit->getASTFileName() << ')';
7181f4a2713aSLionel Sambuc       return *this;
7182f4a2713aSLionel Sambuc     }
7183*0a6a1f1dSLionel Sambuc   } else {
7184f4a2713aSLionel Sambuc     LogOS << "<NULL TU>";
7185*0a6a1f1dSLionel Sambuc   }
7186f4a2713aSLionel Sambuc   return *this;
7187f4a2713aSLionel Sambuc }
7188f4a2713aSLionel Sambuc 
operator <<(const FileEntry * FE)7189f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7190f4a2713aSLionel Sambuc   *this << FE->getName();
7191f4a2713aSLionel Sambuc   return *this;
7192f4a2713aSLionel Sambuc }
7193f4a2713aSLionel Sambuc 
operator <<(CXCursor cursor)7194f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7195f4a2713aSLionel Sambuc   CXString cursorName = clang_getCursorDisplayName(cursor);
7196f4a2713aSLionel Sambuc   *this << cursorName << "@" << clang_getCursorLocation(cursor);
7197f4a2713aSLionel Sambuc   clang_disposeString(cursorName);
7198f4a2713aSLionel Sambuc   return *this;
7199f4a2713aSLionel Sambuc }
7200f4a2713aSLionel Sambuc 
operator <<(CXSourceLocation Loc)7201f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7202f4a2713aSLionel Sambuc   CXFile File;
7203f4a2713aSLionel Sambuc   unsigned Line, Column;
7204*0a6a1f1dSLionel Sambuc   clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
7205f4a2713aSLionel Sambuc   CXString FileName = clang_getFileName(File);
7206f4a2713aSLionel Sambuc   *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7207f4a2713aSLionel Sambuc   clang_disposeString(FileName);
7208f4a2713aSLionel Sambuc   return *this;
7209f4a2713aSLionel Sambuc }
7210f4a2713aSLionel Sambuc 
operator <<(CXSourceRange range)7211f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7212f4a2713aSLionel Sambuc   CXSourceLocation BLoc = clang_getRangeStart(range);
7213f4a2713aSLionel Sambuc   CXSourceLocation ELoc = clang_getRangeEnd(range);
7214f4a2713aSLionel Sambuc 
7215f4a2713aSLionel Sambuc   CXFile BFile;
7216f4a2713aSLionel Sambuc   unsigned BLine, BColumn;
7217*0a6a1f1dSLionel Sambuc   clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
7218f4a2713aSLionel Sambuc 
7219f4a2713aSLionel Sambuc   CXFile EFile;
7220f4a2713aSLionel Sambuc   unsigned ELine, EColumn;
7221*0a6a1f1dSLionel Sambuc   clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
7222f4a2713aSLionel Sambuc 
7223f4a2713aSLionel Sambuc   CXString BFileName = clang_getFileName(BFile);
7224f4a2713aSLionel Sambuc   if (BFile == EFile) {
7225f4a2713aSLionel Sambuc     *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7226f4a2713aSLionel Sambuc                          BLine, BColumn, ELine, EColumn);
7227f4a2713aSLionel Sambuc   } else {
7228f4a2713aSLionel Sambuc     CXString EFileName = clang_getFileName(EFile);
7229f4a2713aSLionel Sambuc     *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7230f4a2713aSLionel Sambuc                           BLine, BColumn)
7231f4a2713aSLionel Sambuc           << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7232f4a2713aSLionel Sambuc                           ELine, EColumn);
7233f4a2713aSLionel Sambuc     clang_disposeString(EFileName);
7234f4a2713aSLionel Sambuc   }
7235f4a2713aSLionel Sambuc   clang_disposeString(BFileName);
7236f4a2713aSLionel Sambuc   return *this;
7237f4a2713aSLionel Sambuc }
7238f4a2713aSLionel Sambuc 
operator <<(CXString Str)7239f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(CXString Str) {
7240f4a2713aSLionel Sambuc   *this << clang_getCString(Str);
7241f4a2713aSLionel Sambuc   return *this;
7242f4a2713aSLionel Sambuc }
7243f4a2713aSLionel Sambuc 
operator <<(const llvm::format_object_base & Fmt)7244f4a2713aSLionel Sambuc Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7245f4a2713aSLionel Sambuc   LogOS << Fmt;
7246f4a2713aSLionel Sambuc   return *this;
7247f4a2713aSLionel Sambuc }
7248f4a2713aSLionel Sambuc 
7249*0a6a1f1dSLionel Sambuc static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7250*0a6a1f1dSLionel Sambuc 
~Logger()7251f4a2713aSLionel Sambuc cxindex::Logger::~Logger() {
7252f4a2713aSLionel Sambuc   LogOS.flush();
7253f4a2713aSLionel Sambuc 
7254*0a6a1f1dSLionel Sambuc   llvm::sys::ScopedLock L(*LoggingMutex);
7255f4a2713aSLionel Sambuc 
7256f4a2713aSLionel Sambuc   static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7257f4a2713aSLionel Sambuc 
7258f4a2713aSLionel Sambuc   raw_ostream &OS = llvm::errs();
7259f4a2713aSLionel Sambuc   OS << "[libclang:" << Name << ':';
7260f4a2713aSLionel Sambuc 
7261*0a6a1f1dSLionel Sambuc #ifdef USE_DARWIN_THREADS
7262*0a6a1f1dSLionel Sambuc   // TODO: Portability.
7263f4a2713aSLionel Sambuc   mach_port_t tid = pthread_mach_thread_np(pthread_self());
7264f4a2713aSLionel Sambuc   OS << tid << ':';
7265f4a2713aSLionel Sambuc #endif
7266f4a2713aSLionel Sambuc 
7267f4a2713aSLionel Sambuc   llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7268f4a2713aSLionel Sambuc   OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
7269f4a2713aSLionel Sambuc   OS << Msg.str() << '\n';
7270f4a2713aSLionel Sambuc 
7271f4a2713aSLionel Sambuc   if (Trace) {
7272f4a2713aSLionel Sambuc     llvm::sys::PrintStackTrace(stderr);
7273f4a2713aSLionel Sambuc     OS << "--------------------------------------------------\n";
7274f4a2713aSLionel Sambuc   }
7275f4a2713aSLionel Sambuc }
7276