xref: /aosp_15_r20/external/clang/tools/libclang/CIndex.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This file implements the main API hooks in the Clang-C Source Indexing
11*67e74705SXin Li // library.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li 
15*67e74705SXin Li #include "CIndexer.h"
16*67e74705SXin Li #include "CIndexDiagnostic.h"
17*67e74705SXin Li #include "CLog.h"
18*67e74705SXin Li #include "CXCursor.h"
19*67e74705SXin Li #include "CXSourceLocation.h"
20*67e74705SXin Li #include "CXString.h"
21*67e74705SXin Li #include "CXTranslationUnit.h"
22*67e74705SXin Li #include "CXType.h"
23*67e74705SXin Li #include "CursorVisitor.h"
24*67e74705SXin Li #include "clang/AST/Attr.h"
25*67e74705SXin Li #include "clang/AST/StmtVisitor.h"
26*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
27*67e74705SXin Li #include "clang/Basic/DiagnosticCategories.h"
28*67e74705SXin Li #include "clang/Basic/DiagnosticIDs.h"
29*67e74705SXin Li #include "clang/Basic/Version.h"
30*67e74705SXin Li #include "clang/Frontend/ASTUnit.h"
31*67e74705SXin Li #include "clang/Frontend/CompilerInstance.h"
32*67e74705SXin Li #include "clang/Frontend/FrontendDiagnostic.h"
33*67e74705SXin Li #include "clang/Index/CodegenNameGenerator.h"
34*67e74705SXin Li #include "clang/Index/CommentToXML.h"
35*67e74705SXin Li #include "clang/Lex/HeaderSearch.h"
36*67e74705SXin Li #include "clang/Lex/Lexer.h"
37*67e74705SXin Li #include "clang/Lex/PreprocessingRecord.h"
38*67e74705SXin Li #include "clang/Lex/Preprocessor.h"
39*67e74705SXin Li #include "clang/Serialization/SerializationDiagnostic.h"
40*67e74705SXin Li #include "llvm/ADT/Optional.h"
41*67e74705SXin Li #include "llvm/ADT/STLExtras.h"
42*67e74705SXin Li #include "llvm/ADT/StringSwitch.h"
43*67e74705SXin Li #include "llvm/Config/llvm-config.h"
44*67e74705SXin Li #include "llvm/Support/Compiler.h"
45*67e74705SXin Li #include "llvm/Support/CrashRecoveryContext.h"
46*67e74705SXin Li #include "llvm/Support/Format.h"
47*67e74705SXin Li #include "llvm/Support/ManagedStatic.h"
48*67e74705SXin Li #include "llvm/Support/MemoryBuffer.h"
49*67e74705SXin Li #include "llvm/Support/Mutex.h"
50*67e74705SXin Li #include "llvm/Support/Program.h"
51*67e74705SXin Li #include "llvm/Support/SaveAndRestore.h"
52*67e74705SXin Li #include "llvm/Support/Signals.h"
53*67e74705SXin Li #include "llvm/Support/TargetSelect.h"
54*67e74705SXin Li #include "llvm/Support/Threading.h"
55*67e74705SXin Li #include "llvm/Support/Timer.h"
56*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
57*67e74705SXin Li 
58*67e74705SXin Li #if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
59*67e74705SXin Li #define USE_DARWIN_THREADS
60*67e74705SXin Li #endif
61*67e74705SXin Li 
62*67e74705SXin Li #ifdef USE_DARWIN_THREADS
63*67e74705SXin Li #include <pthread.h>
64*67e74705SXin Li #endif
65*67e74705SXin Li 
66*67e74705SXin Li using namespace clang;
67*67e74705SXin Li using namespace clang::cxcursor;
68*67e74705SXin Li using namespace clang::cxtu;
69*67e74705SXin Li using namespace clang::cxindex;
70*67e74705SXin Li 
MakeCXTranslationUnit(CIndexer * CIdx,ASTUnit * AU)71*67e74705SXin Li CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
72*67e74705SXin Li   if (!AU)
73*67e74705SXin Li     return nullptr;
74*67e74705SXin Li   assert(CIdx);
75*67e74705SXin Li   CXTranslationUnit D = new CXTranslationUnitImpl();
76*67e74705SXin Li   D->CIdx = CIdx;
77*67e74705SXin Li   D->TheASTUnit = AU;
78*67e74705SXin Li   D->StringPool = new cxstring::CXStringPool();
79*67e74705SXin Li   D->Diagnostics = nullptr;
80*67e74705SXin Li   D->OverridenCursorsPool = createOverridenCXCursorsPool();
81*67e74705SXin Li   D->CommentToXML = nullptr;
82*67e74705SXin Li   return D;
83*67e74705SXin Li }
84*67e74705SXin Li 
isASTReadError(ASTUnit * AU)85*67e74705SXin Li bool cxtu::isASTReadError(ASTUnit *AU) {
86*67e74705SXin Li   for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
87*67e74705SXin Li                                      DEnd = AU->stored_diag_end();
88*67e74705SXin Li        D != DEnd; ++D) {
89*67e74705SXin Li     if (D->getLevel() >= DiagnosticsEngine::Error &&
90*67e74705SXin Li         DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
91*67e74705SXin Li             diag::DiagCat_AST_Deserialization_Issue)
92*67e74705SXin Li       return true;
93*67e74705SXin Li   }
94*67e74705SXin Li   return false;
95*67e74705SXin Li }
96*67e74705SXin Li 
~CXTUOwner()97*67e74705SXin Li cxtu::CXTUOwner::~CXTUOwner() {
98*67e74705SXin Li   if (TU)
99*67e74705SXin Li     clang_disposeTranslationUnit(TU);
100*67e74705SXin Li }
101*67e74705SXin Li 
102*67e74705SXin Li /// \brief Compare two source ranges to determine their relative position in
103*67e74705SXin Li /// the translation unit.
RangeCompare(SourceManager & SM,SourceRange R1,SourceRange R2)104*67e74705SXin Li static RangeComparisonResult RangeCompare(SourceManager &SM,
105*67e74705SXin Li                                           SourceRange R1,
106*67e74705SXin Li                                           SourceRange R2) {
107*67e74705SXin Li   assert(R1.isValid() && "First range is invalid?");
108*67e74705SXin Li   assert(R2.isValid() && "Second range is invalid?");
109*67e74705SXin Li   if (R1.getEnd() != R2.getBegin() &&
110*67e74705SXin Li       SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
111*67e74705SXin Li     return RangeBefore;
112*67e74705SXin Li   if (R2.getEnd() != R1.getBegin() &&
113*67e74705SXin Li       SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
114*67e74705SXin Li     return RangeAfter;
115*67e74705SXin Li   return RangeOverlap;
116*67e74705SXin Li }
117*67e74705SXin Li 
118*67e74705SXin Li /// \brief Determine if a source location falls within, before, or after a
119*67e74705SXin Li ///   a given source range.
LocationCompare(SourceManager & SM,SourceLocation L,SourceRange R)120*67e74705SXin Li static RangeComparisonResult LocationCompare(SourceManager &SM,
121*67e74705SXin Li                                              SourceLocation L, SourceRange R) {
122*67e74705SXin Li   assert(R.isValid() && "First range is invalid?");
123*67e74705SXin Li   assert(L.isValid() && "Second range is invalid?");
124*67e74705SXin Li   if (L == R.getBegin() || L == R.getEnd())
125*67e74705SXin Li     return RangeOverlap;
126*67e74705SXin Li   if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
127*67e74705SXin Li     return RangeBefore;
128*67e74705SXin Li   if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
129*67e74705SXin Li     return RangeAfter;
130*67e74705SXin Li   return RangeOverlap;
131*67e74705SXin Li }
132*67e74705SXin Li 
133*67e74705SXin Li /// \brief Translate a Clang source range into a CIndex source range.
134*67e74705SXin Li ///
135*67e74705SXin Li /// Clang internally represents ranges where the end location points to the
136*67e74705SXin Li /// start of the token at the end. However, for external clients it is more
137*67e74705SXin Li /// useful to have a CXSourceRange be a proper half-open interval. This routine
138*67e74705SXin Li /// does the appropriate translation.
translateSourceRange(const SourceManager & SM,const LangOptions & LangOpts,const CharSourceRange & R)139*67e74705SXin Li CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
140*67e74705SXin Li                                           const LangOptions &LangOpts,
141*67e74705SXin Li                                           const CharSourceRange &R) {
142*67e74705SXin Li   // We want the last character in this location, so we will adjust the
143*67e74705SXin Li   // location accordingly.
144*67e74705SXin Li   SourceLocation EndLoc = R.getEnd();
145*67e74705SXin Li   if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
146*67e74705SXin Li     EndLoc = SM.getExpansionRange(EndLoc).second;
147*67e74705SXin Li   if (R.isTokenRange() && EndLoc.isValid()) {
148*67e74705SXin Li     unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
149*67e74705SXin Li                                                 SM, LangOpts);
150*67e74705SXin Li     EndLoc = EndLoc.getLocWithOffset(Length);
151*67e74705SXin Li   }
152*67e74705SXin Li 
153*67e74705SXin Li   CXSourceRange Result = {
154*67e74705SXin Li     { &SM, &LangOpts },
155*67e74705SXin Li     R.getBegin().getRawEncoding(),
156*67e74705SXin Li     EndLoc.getRawEncoding()
157*67e74705SXin Li   };
158*67e74705SXin Li   return Result;
159*67e74705SXin Li }
160*67e74705SXin Li 
161*67e74705SXin Li //===----------------------------------------------------------------------===//
162*67e74705SXin Li // Cursor visitor.
163*67e74705SXin Li //===----------------------------------------------------------------------===//
164*67e74705SXin Li 
165*67e74705SXin Li static SourceRange getRawCursorExtent(CXCursor C);
166*67e74705SXin Li static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
167*67e74705SXin Li 
168*67e74705SXin Li 
CompareRegionOfInterest(SourceRange R)169*67e74705SXin Li RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
170*67e74705SXin Li   return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
171*67e74705SXin Li }
172*67e74705SXin Li 
173*67e74705SXin Li /// \brief Visit the given cursor and, if requested by the visitor,
174*67e74705SXin Li /// its children.
175*67e74705SXin Li ///
176*67e74705SXin Li /// \param Cursor the cursor to visit.
177*67e74705SXin Li ///
178*67e74705SXin Li /// \param CheckedRegionOfInterest if true, then the caller already checked
179*67e74705SXin Li /// that this cursor is within the region of interest.
180*67e74705SXin Li ///
181*67e74705SXin Li /// \returns true if the visitation should be aborted, false if it
182*67e74705SXin Li /// should continue.
Visit(CXCursor Cursor,bool CheckedRegionOfInterest)183*67e74705SXin Li bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
184*67e74705SXin Li   if (clang_isInvalid(Cursor.kind))
185*67e74705SXin Li     return false;
186*67e74705SXin Li 
187*67e74705SXin Li   if (clang_isDeclaration(Cursor.kind)) {
188*67e74705SXin Li     const Decl *D = getCursorDecl(Cursor);
189*67e74705SXin Li     if (!D) {
190*67e74705SXin Li       assert(0 && "Invalid declaration cursor");
191*67e74705SXin Li       return true; // abort.
192*67e74705SXin Li     }
193*67e74705SXin Li 
194*67e74705SXin Li     // Ignore implicit declarations, unless it's an objc method because
195*67e74705SXin Li     // currently we should report implicit methods for properties when indexing.
196*67e74705SXin Li     if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
197*67e74705SXin Li       return false;
198*67e74705SXin Li   }
199*67e74705SXin Li 
200*67e74705SXin Li   // If we have a range of interest, and this cursor doesn't intersect with it,
201*67e74705SXin Li   // we're done.
202*67e74705SXin Li   if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
203*67e74705SXin Li     SourceRange Range = getRawCursorExtent(Cursor);
204*67e74705SXin Li     if (Range.isInvalid() || CompareRegionOfInterest(Range))
205*67e74705SXin Li       return false;
206*67e74705SXin Li   }
207*67e74705SXin Li 
208*67e74705SXin Li   switch (Visitor(Cursor, Parent, ClientData)) {
209*67e74705SXin Li   case CXChildVisit_Break:
210*67e74705SXin Li     return true;
211*67e74705SXin Li 
212*67e74705SXin Li   case CXChildVisit_Continue:
213*67e74705SXin Li     return false;
214*67e74705SXin Li 
215*67e74705SXin Li   case CXChildVisit_Recurse: {
216*67e74705SXin Li     bool ret = VisitChildren(Cursor);
217*67e74705SXin Li     if (PostChildrenVisitor)
218*67e74705SXin Li       if (PostChildrenVisitor(Cursor, ClientData))
219*67e74705SXin Li         return true;
220*67e74705SXin Li     return ret;
221*67e74705SXin Li   }
222*67e74705SXin Li   }
223*67e74705SXin Li 
224*67e74705SXin Li   llvm_unreachable("Invalid CXChildVisitResult!");
225*67e74705SXin Li }
226*67e74705SXin Li 
visitPreprocessedEntitiesInRange(SourceRange R,PreprocessingRecord & PPRec,CursorVisitor & Visitor)227*67e74705SXin Li static bool visitPreprocessedEntitiesInRange(SourceRange R,
228*67e74705SXin Li                                              PreprocessingRecord &PPRec,
229*67e74705SXin Li                                              CursorVisitor &Visitor) {
230*67e74705SXin Li   SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
231*67e74705SXin Li   FileID FID;
232*67e74705SXin Li 
233*67e74705SXin Li   if (!Visitor.shouldVisitIncludedEntities()) {
234*67e74705SXin Li     // If the begin/end of the range lie in the same FileID, do the optimization
235*67e74705SXin Li     // where we skip preprocessed entities that do not come from the same FileID.
236*67e74705SXin Li     FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
237*67e74705SXin Li     if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
238*67e74705SXin Li       FID = FileID();
239*67e74705SXin Li   }
240*67e74705SXin Li 
241*67e74705SXin Li   const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
242*67e74705SXin Li   return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
243*67e74705SXin Li                                            PPRec, FID);
244*67e74705SXin Li }
245*67e74705SXin Li 
visitFileRegion()246*67e74705SXin Li bool CursorVisitor::visitFileRegion() {
247*67e74705SXin Li   if (RegionOfInterest.isInvalid())
248*67e74705SXin Li     return false;
249*67e74705SXin Li 
250*67e74705SXin Li   ASTUnit *Unit = cxtu::getASTUnit(TU);
251*67e74705SXin Li   SourceManager &SM = Unit->getSourceManager();
252*67e74705SXin Li 
253*67e74705SXin Li   std::pair<FileID, unsigned>
254*67e74705SXin Li     Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
255*67e74705SXin Li     End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
256*67e74705SXin Li 
257*67e74705SXin Li   if (End.first != Begin.first) {
258*67e74705SXin Li     // If the end does not reside in the same file, try to recover by
259*67e74705SXin Li     // picking the end of the file of begin location.
260*67e74705SXin Li     End.first = Begin.first;
261*67e74705SXin Li     End.second = SM.getFileIDSize(Begin.first);
262*67e74705SXin Li   }
263*67e74705SXin Li 
264*67e74705SXin Li   assert(Begin.first == End.first);
265*67e74705SXin Li   if (Begin.second > End.second)
266*67e74705SXin Li     return false;
267*67e74705SXin Li 
268*67e74705SXin Li   FileID File = Begin.first;
269*67e74705SXin Li   unsigned Offset = Begin.second;
270*67e74705SXin Li   unsigned Length = End.second - Begin.second;
271*67e74705SXin Li 
272*67e74705SXin Li   if (!VisitDeclsOnly && !VisitPreprocessorLast)
273*67e74705SXin Li     if (visitPreprocessedEntitiesInRegion())
274*67e74705SXin Li       return true; // visitation break.
275*67e74705SXin Li 
276*67e74705SXin Li   if (visitDeclsFromFileRegion(File, Offset, Length))
277*67e74705SXin Li     return true; // visitation break.
278*67e74705SXin Li 
279*67e74705SXin Li   if (!VisitDeclsOnly && VisitPreprocessorLast)
280*67e74705SXin Li     return visitPreprocessedEntitiesInRegion();
281*67e74705SXin Li 
282*67e74705SXin Li   return false;
283*67e74705SXin Li }
284*67e74705SXin Li 
isInLexicalContext(Decl * D,DeclContext * DC)285*67e74705SXin Li static bool isInLexicalContext(Decl *D, DeclContext *DC) {
286*67e74705SXin Li   if (!DC)
287*67e74705SXin Li     return false;
288*67e74705SXin Li 
289*67e74705SXin Li   for (DeclContext *DeclDC = D->getLexicalDeclContext();
290*67e74705SXin Li          DeclDC; DeclDC = DeclDC->getLexicalParent()) {
291*67e74705SXin Li     if (DeclDC == DC)
292*67e74705SXin Li       return true;
293*67e74705SXin Li   }
294*67e74705SXin Li   return false;
295*67e74705SXin Li }
296*67e74705SXin Li 
visitDeclsFromFileRegion(FileID File,unsigned Offset,unsigned Length)297*67e74705SXin Li bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
298*67e74705SXin Li                                              unsigned Offset, unsigned Length) {
299*67e74705SXin Li   ASTUnit *Unit = cxtu::getASTUnit(TU);
300*67e74705SXin Li   SourceManager &SM = Unit->getSourceManager();
301*67e74705SXin Li   SourceRange Range = RegionOfInterest;
302*67e74705SXin Li 
303*67e74705SXin Li   SmallVector<Decl *, 16> Decls;
304*67e74705SXin Li   Unit->findFileRegionDecls(File, Offset, Length, Decls);
305*67e74705SXin Li 
306*67e74705SXin Li   // If we didn't find any file level decls for the file, try looking at the
307*67e74705SXin Li   // file that it was included from.
308*67e74705SXin Li   while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
309*67e74705SXin Li     bool Invalid = false;
310*67e74705SXin Li     const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
311*67e74705SXin Li     if (Invalid)
312*67e74705SXin Li       return false;
313*67e74705SXin Li 
314*67e74705SXin Li     SourceLocation Outer;
315*67e74705SXin Li     if (SLEntry.isFile())
316*67e74705SXin Li       Outer = SLEntry.getFile().getIncludeLoc();
317*67e74705SXin Li     else
318*67e74705SXin Li       Outer = SLEntry.getExpansion().getExpansionLocStart();
319*67e74705SXin Li     if (Outer.isInvalid())
320*67e74705SXin Li       return false;
321*67e74705SXin Li 
322*67e74705SXin Li     std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
323*67e74705SXin Li     Length = 0;
324*67e74705SXin Li     Unit->findFileRegionDecls(File, Offset, Length, Decls);
325*67e74705SXin Li   }
326*67e74705SXin Li 
327*67e74705SXin Li   assert(!Decls.empty());
328*67e74705SXin Li 
329*67e74705SXin Li   bool VisitedAtLeastOnce = false;
330*67e74705SXin Li   DeclContext *CurDC = nullptr;
331*67e74705SXin Li   SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
332*67e74705SXin Li   for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
333*67e74705SXin Li     Decl *D = *DIt;
334*67e74705SXin Li     if (D->getSourceRange().isInvalid())
335*67e74705SXin Li       continue;
336*67e74705SXin Li 
337*67e74705SXin Li     if (isInLexicalContext(D, CurDC))
338*67e74705SXin Li       continue;
339*67e74705SXin Li 
340*67e74705SXin Li     CurDC = dyn_cast<DeclContext>(D);
341*67e74705SXin Li 
342*67e74705SXin Li     if (TagDecl *TD = dyn_cast<TagDecl>(D))
343*67e74705SXin Li       if (!TD->isFreeStanding())
344*67e74705SXin Li         continue;
345*67e74705SXin Li 
346*67e74705SXin Li     RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
347*67e74705SXin Li     if (CompRes == RangeBefore)
348*67e74705SXin Li       continue;
349*67e74705SXin Li     if (CompRes == RangeAfter)
350*67e74705SXin Li       break;
351*67e74705SXin Li 
352*67e74705SXin Li     assert(CompRes == RangeOverlap);
353*67e74705SXin Li     VisitedAtLeastOnce = true;
354*67e74705SXin Li 
355*67e74705SXin Li     if (isa<ObjCContainerDecl>(D)) {
356*67e74705SXin Li       FileDI_current = &DIt;
357*67e74705SXin Li       FileDE_current = DE;
358*67e74705SXin Li     } else {
359*67e74705SXin Li       FileDI_current = nullptr;
360*67e74705SXin Li     }
361*67e74705SXin Li 
362*67e74705SXin Li     if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
363*67e74705SXin Li       return true; // visitation break.
364*67e74705SXin Li   }
365*67e74705SXin Li 
366*67e74705SXin Li   if (VisitedAtLeastOnce)
367*67e74705SXin Li     return false;
368*67e74705SXin Li 
369*67e74705SXin Li   // No Decls overlapped with the range. Move up the lexical context until there
370*67e74705SXin Li   // is a context that contains the range or we reach the translation unit
371*67e74705SXin Li   // level.
372*67e74705SXin Li   DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
373*67e74705SXin Li                                          : (*(DIt-1))->getLexicalDeclContext();
374*67e74705SXin Li 
375*67e74705SXin Li   while (DC && !DC->isTranslationUnit()) {
376*67e74705SXin Li     Decl *D = cast<Decl>(DC);
377*67e74705SXin Li     SourceRange CurDeclRange = D->getSourceRange();
378*67e74705SXin Li     if (CurDeclRange.isInvalid())
379*67e74705SXin Li       break;
380*67e74705SXin Li 
381*67e74705SXin Li     if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
382*67e74705SXin Li       if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
383*67e74705SXin Li         return true; // visitation break.
384*67e74705SXin Li     }
385*67e74705SXin Li 
386*67e74705SXin Li     DC = D->getLexicalDeclContext();
387*67e74705SXin Li   }
388*67e74705SXin Li 
389*67e74705SXin Li   return false;
390*67e74705SXin Li }
391*67e74705SXin Li 
visitPreprocessedEntitiesInRegion()392*67e74705SXin Li bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
393*67e74705SXin Li   if (!AU->getPreprocessor().getPreprocessingRecord())
394*67e74705SXin Li     return false;
395*67e74705SXin Li 
396*67e74705SXin Li   PreprocessingRecord &PPRec
397*67e74705SXin Li     = *AU->getPreprocessor().getPreprocessingRecord();
398*67e74705SXin Li   SourceManager &SM = AU->getSourceManager();
399*67e74705SXin Li 
400*67e74705SXin Li   if (RegionOfInterest.isValid()) {
401*67e74705SXin Li     SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
402*67e74705SXin Li     SourceLocation B = MappedRange.getBegin();
403*67e74705SXin Li     SourceLocation E = MappedRange.getEnd();
404*67e74705SXin Li 
405*67e74705SXin Li     if (AU->isInPreambleFileID(B)) {
406*67e74705SXin Li       if (SM.isLoadedSourceLocation(E))
407*67e74705SXin Li         return visitPreprocessedEntitiesInRange(SourceRange(B, E),
408*67e74705SXin Li                                                  PPRec, *this);
409*67e74705SXin Li 
410*67e74705SXin Li       // Beginning of range lies in the preamble but it also extends beyond
411*67e74705SXin Li       // it into the main file. Split the range into 2 parts, one covering
412*67e74705SXin Li       // the preamble and another covering the main file. This allows subsequent
413*67e74705SXin Li       // calls to visitPreprocessedEntitiesInRange to accept a source range that
414*67e74705SXin Li       // lies in the same FileID, allowing it to skip preprocessed entities that
415*67e74705SXin Li       // do not come from the same FileID.
416*67e74705SXin Li       bool breaked =
417*67e74705SXin Li         visitPreprocessedEntitiesInRange(
418*67e74705SXin Li                                    SourceRange(B, AU->getEndOfPreambleFileID()),
419*67e74705SXin Li                                           PPRec, *this);
420*67e74705SXin Li       if (breaked) return true;
421*67e74705SXin Li       return visitPreprocessedEntitiesInRange(
422*67e74705SXin Li                                     SourceRange(AU->getStartOfMainFileID(), E),
423*67e74705SXin Li                                         PPRec, *this);
424*67e74705SXin Li     }
425*67e74705SXin Li 
426*67e74705SXin Li     return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
427*67e74705SXin Li   }
428*67e74705SXin Li 
429*67e74705SXin Li   bool OnlyLocalDecls
430*67e74705SXin Li     = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
431*67e74705SXin Li 
432*67e74705SXin Li   if (OnlyLocalDecls)
433*67e74705SXin Li     return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
434*67e74705SXin Li                                      PPRec);
435*67e74705SXin Li 
436*67e74705SXin Li   return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
437*67e74705SXin Li }
438*67e74705SXin Li 
439*67e74705SXin Li template<typename InputIterator>
visitPreprocessedEntities(InputIterator First,InputIterator Last,PreprocessingRecord & PPRec,FileID FID)440*67e74705SXin Li bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
441*67e74705SXin Li                                               InputIterator Last,
442*67e74705SXin Li                                               PreprocessingRecord &PPRec,
443*67e74705SXin Li                                               FileID FID) {
444*67e74705SXin Li   for (; First != Last; ++First) {
445*67e74705SXin Li     if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
446*67e74705SXin Li       continue;
447*67e74705SXin Li 
448*67e74705SXin Li     PreprocessedEntity *PPE = *First;
449*67e74705SXin Li     if (!PPE)
450*67e74705SXin Li       continue;
451*67e74705SXin Li 
452*67e74705SXin Li     if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
453*67e74705SXin Li       if (Visit(MakeMacroExpansionCursor(ME, TU)))
454*67e74705SXin Li         return true;
455*67e74705SXin Li 
456*67e74705SXin Li       continue;
457*67e74705SXin Li     }
458*67e74705SXin Li 
459*67e74705SXin Li     if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
460*67e74705SXin Li       if (Visit(MakeMacroDefinitionCursor(MD, TU)))
461*67e74705SXin Li         return true;
462*67e74705SXin Li 
463*67e74705SXin Li       continue;
464*67e74705SXin Li     }
465*67e74705SXin Li 
466*67e74705SXin Li     if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
467*67e74705SXin Li       if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
468*67e74705SXin Li         return true;
469*67e74705SXin Li 
470*67e74705SXin Li       continue;
471*67e74705SXin Li     }
472*67e74705SXin Li   }
473*67e74705SXin Li 
474*67e74705SXin Li   return false;
475*67e74705SXin Li }
476*67e74705SXin Li 
477*67e74705SXin Li /// \brief Visit the children of the given cursor.
478*67e74705SXin Li ///
479*67e74705SXin Li /// \returns true if the visitation should be aborted, false if it
480*67e74705SXin Li /// should continue.
VisitChildren(CXCursor Cursor)481*67e74705SXin Li bool CursorVisitor::VisitChildren(CXCursor Cursor) {
482*67e74705SXin Li   if (clang_isReference(Cursor.kind) &&
483*67e74705SXin Li       Cursor.kind != CXCursor_CXXBaseSpecifier) {
484*67e74705SXin Li     // By definition, references have no children.
485*67e74705SXin Li     return false;
486*67e74705SXin Li   }
487*67e74705SXin Li 
488*67e74705SXin Li   // Set the Parent field to Cursor, then back to its old value once we're
489*67e74705SXin Li   // done.
490*67e74705SXin Li   SetParentRAII SetParent(Parent, StmtParent, Cursor);
491*67e74705SXin Li 
492*67e74705SXin Li   if (clang_isDeclaration(Cursor.kind)) {
493*67e74705SXin Li     Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
494*67e74705SXin Li     if (!D)
495*67e74705SXin Li       return false;
496*67e74705SXin Li 
497*67e74705SXin Li     return VisitAttributes(D) || Visit(D);
498*67e74705SXin Li   }
499*67e74705SXin Li 
500*67e74705SXin Li   if (clang_isStatement(Cursor.kind)) {
501*67e74705SXin Li     if (const Stmt *S = getCursorStmt(Cursor))
502*67e74705SXin Li       return Visit(S);
503*67e74705SXin Li 
504*67e74705SXin Li     return false;
505*67e74705SXin Li   }
506*67e74705SXin Li 
507*67e74705SXin Li   if (clang_isExpression(Cursor.kind)) {
508*67e74705SXin Li     if (const Expr *E = getCursorExpr(Cursor))
509*67e74705SXin Li       return Visit(E);
510*67e74705SXin Li 
511*67e74705SXin Li     return false;
512*67e74705SXin Li   }
513*67e74705SXin Li 
514*67e74705SXin Li   if (clang_isTranslationUnit(Cursor.kind)) {
515*67e74705SXin Li     CXTranslationUnit TU = getCursorTU(Cursor);
516*67e74705SXin Li     ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
517*67e74705SXin Li 
518*67e74705SXin Li     int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
519*67e74705SXin Li     for (unsigned I = 0; I != 2; ++I) {
520*67e74705SXin Li       if (VisitOrder[I]) {
521*67e74705SXin Li         if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
522*67e74705SXin Li             RegionOfInterest.isInvalid()) {
523*67e74705SXin Li           for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
524*67e74705SXin Li                                         TLEnd = CXXUnit->top_level_end();
525*67e74705SXin Li                TL != TLEnd; ++TL) {
526*67e74705SXin Li             const Optional<bool> V = handleDeclForVisitation(*TL);
527*67e74705SXin Li             if (!V.hasValue())
528*67e74705SXin Li               continue;
529*67e74705SXin Li             return V.getValue();
530*67e74705SXin Li           }
531*67e74705SXin Li         } else if (VisitDeclContext(
532*67e74705SXin Li                                 CXXUnit->getASTContext().getTranslationUnitDecl()))
533*67e74705SXin Li           return true;
534*67e74705SXin Li         continue;
535*67e74705SXin Li       }
536*67e74705SXin Li 
537*67e74705SXin Li       // Walk the preprocessing record.
538*67e74705SXin Li       if (CXXUnit->getPreprocessor().getPreprocessingRecord())
539*67e74705SXin Li         visitPreprocessedEntitiesInRegion();
540*67e74705SXin Li     }
541*67e74705SXin Li 
542*67e74705SXin Li     return false;
543*67e74705SXin Li   }
544*67e74705SXin Li 
545*67e74705SXin Li   if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
546*67e74705SXin Li     if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
547*67e74705SXin Li       if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
548*67e74705SXin Li         return Visit(BaseTSInfo->getTypeLoc());
549*67e74705SXin Li       }
550*67e74705SXin Li     }
551*67e74705SXin Li   }
552*67e74705SXin Li 
553*67e74705SXin Li   if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
554*67e74705SXin Li     const IBOutletCollectionAttr *A =
555*67e74705SXin Li       cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
556*67e74705SXin Li     if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
557*67e74705SXin Li       return Visit(cxcursor::MakeCursorObjCClassRef(
558*67e74705SXin Li           ObjT->getInterface(),
559*67e74705SXin Li           A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
560*67e74705SXin Li   }
561*67e74705SXin Li 
562*67e74705SXin Li   // If pointing inside a macro definition, check if the token is an identifier
563*67e74705SXin Li   // that was ever defined as a macro. In such a case, create a "pseudo" macro
564*67e74705SXin Li   // expansion cursor for that token.
565*67e74705SXin Li   SourceLocation BeginLoc = RegionOfInterest.getBegin();
566*67e74705SXin Li   if (Cursor.kind == CXCursor_MacroDefinition &&
567*67e74705SXin Li       BeginLoc == RegionOfInterest.getEnd()) {
568*67e74705SXin Li     SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
569*67e74705SXin Li     const MacroInfo *MI =
570*67e74705SXin Li         getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
571*67e74705SXin Li     if (MacroDefinitionRecord *MacroDef =
572*67e74705SXin Li             checkForMacroInMacroDefinition(MI, Loc, TU))
573*67e74705SXin Li       return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
574*67e74705SXin Li   }
575*67e74705SXin Li 
576*67e74705SXin Li   // Nothing to visit at the moment.
577*67e74705SXin Li   return false;
578*67e74705SXin Li }
579*67e74705SXin Li 
VisitBlockDecl(BlockDecl * B)580*67e74705SXin Li bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
581*67e74705SXin Li   if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
582*67e74705SXin Li     if (Visit(TSInfo->getTypeLoc()))
583*67e74705SXin Li         return true;
584*67e74705SXin Li 
585*67e74705SXin Li   if (Stmt *Body = B->getBody())
586*67e74705SXin Li     return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
587*67e74705SXin Li 
588*67e74705SXin Li   return false;
589*67e74705SXin Li }
590*67e74705SXin Li 
shouldVisitCursor(CXCursor Cursor)591*67e74705SXin Li Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
592*67e74705SXin Li   if (RegionOfInterest.isValid()) {
593*67e74705SXin Li     SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
594*67e74705SXin Li     if (Range.isInvalid())
595*67e74705SXin Li       return None;
596*67e74705SXin Li 
597*67e74705SXin Li     switch (CompareRegionOfInterest(Range)) {
598*67e74705SXin Li     case RangeBefore:
599*67e74705SXin Li       // This declaration comes before the region of interest; skip it.
600*67e74705SXin Li       return None;
601*67e74705SXin Li 
602*67e74705SXin Li     case RangeAfter:
603*67e74705SXin Li       // This declaration comes after the region of interest; we're done.
604*67e74705SXin Li       return false;
605*67e74705SXin Li 
606*67e74705SXin Li     case RangeOverlap:
607*67e74705SXin Li       // This declaration overlaps the region of interest; visit it.
608*67e74705SXin Li       break;
609*67e74705SXin Li     }
610*67e74705SXin Li   }
611*67e74705SXin Li   return true;
612*67e74705SXin Li }
613*67e74705SXin Li 
VisitDeclContext(DeclContext * DC)614*67e74705SXin Li bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
615*67e74705SXin Li   DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
616*67e74705SXin Li 
617*67e74705SXin Li   // FIXME: Eventually remove.  This part of a hack to support proper
618*67e74705SXin Li   // iteration over all Decls contained lexically within an ObjC container.
619*67e74705SXin Li   SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
620*67e74705SXin Li   SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
621*67e74705SXin Li 
622*67e74705SXin Li   for ( ; I != E; ++I) {
623*67e74705SXin Li     Decl *D = *I;
624*67e74705SXin Li     if (D->getLexicalDeclContext() != DC)
625*67e74705SXin Li       continue;
626*67e74705SXin Li     const Optional<bool> V = handleDeclForVisitation(D);
627*67e74705SXin Li     if (!V.hasValue())
628*67e74705SXin Li       continue;
629*67e74705SXin Li     return V.getValue();
630*67e74705SXin Li   }
631*67e74705SXin Li   return false;
632*67e74705SXin Li }
633*67e74705SXin Li 
handleDeclForVisitation(const Decl * D)634*67e74705SXin Li Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
635*67e74705SXin Li   CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
636*67e74705SXin Li 
637*67e74705SXin Li   // Ignore synthesized ivars here, otherwise if we have something like:
638*67e74705SXin Li   //   @synthesize prop = _prop;
639*67e74705SXin Li   // and '_prop' is not declared, we will encounter a '_prop' ivar before
640*67e74705SXin Li   // encountering the 'prop' synthesize declaration and we will think that
641*67e74705SXin Li   // we passed the region-of-interest.
642*67e74705SXin Li   if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
643*67e74705SXin Li     if (ivarD->getSynthesize())
644*67e74705SXin Li       return None;
645*67e74705SXin Li   }
646*67e74705SXin Li 
647*67e74705SXin Li   // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
648*67e74705SXin Li   // declarations is a mismatch with the compiler semantics.
649*67e74705SXin Li   if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
650*67e74705SXin Li     auto *ID = cast<ObjCInterfaceDecl>(D);
651*67e74705SXin Li     if (!ID->isThisDeclarationADefinition())
652*67e74705SXin Li       Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
653*67e74705SXin Li 
654*67e74705SXin Li   } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
655*67e74705SXin Li     auto *PD = cast<ObjCProtocolDecl>(D);
656*67e74705SXin Li     if (!PD->isThisDeclarationADefinition())
657*67e74705SXin Li       Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
658*67e74705SXin Li   }
659*67e74705SXin Li 
660*67e74705SXin Li   const Optional<bool> V = shouldVisitCursor(Cursor);
661*67e74705SXin Li   if (!V.hasValue())
662*67e74705SXin Li     return None;
663*67e74705SXin Li   if (!V.getValue())
664*67e74705SXin Li     return false;
665*67e74705SXin Li   if (Visit(Cursor, true))
666*67e74705SXin Li     return true;
667*67e74705SXin Li   return None;
668*67e74705SXin Li }
669*67e74705SXin Li 
VisitTranslationUnitDecl(TranslationUnitDecl * D)670*67e74705SXin Li bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
671*67e74705SXin Li   llvm_unreachable("Translation units are visited directly by Visit()");
672*67e74705SXin Li }
673*67e74705SXin Li 
VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl * D)674*67e74705SXin Li bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
675*67e74705SXin Li     if (VisitTemplateParameters(D->getTemplateParameters()))
676*67e74705SXin Li         return true;
677*67e74705SXin Li 
678*67e74705SXin Li     return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
679*67e74705SXin Li }
680*67e74705SXin Li 
VisitTypeAliasDecl(TypeAliasDecl * D)681*67e74705SXin Li bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
682*67e74705SXin Li   if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
683*67e74705SXin Li     return Visit(TSInfo->getTypeLoc());
684*67e74705SXin Li 
685*67e74705SXin Li   return false;
686*67e74705SXin Li }
687*67e74705SXin Li 
VisitTypedefDecl(TypedefDecl * D)688*67e74705SXin Li bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
689*67e74705SXin Li   if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
690*67e74705SXin Li     return Visit(TSInfo->getTypeLoc());
691*67e74705SXin Li 
692*67e74705SXin Li   return false;
693*67e74705SXin Li }
694*67e74705SXin Li 
VisitTagDecl(TagDecl * D)695*67e74705SXin Li bool CursorVisitor::VisitTagDecl(TagDecl *D) {
696*67e74705SXin Li   return VisitDeclContext(D);
697*67e74705SXin Li }
698*67e74705SXin Li 
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)699*67e74705SXin Li bool CursorVisitor::VisitClassTemplateSpecializationDecl(
700*67e74705SXin Li                                           ClassTemplateSpecializationDecl *D) {
701*67e74705SXin Li   bool ShouldVisitBody = false;
702*67e74705SXin Li   switch (D->getSpecializationKind()) {
703*67e74705SXin Li   case TSK_Undeclared:
704*67e74705SXin Li   case TSK_ImplicitInstantiation:
705*67e74705SXin Li     // Nothing to visit
706*67e74705SXin Li     return false;
707*67e74705SXin Li 
708*67e74705SXin Li   case TSK_ExplicitInstantiationDeclaration:
709*67e74705SXin Li   case TSK_ExplicitInstantiationDefinition:
710*67e74705SXin Li     break;
711*67e74705SXin Li 
712*67e74705SXin Li   case TSK_ExplicitSpecialization:
713*67e74705SXin Li     ShouldVisitBody = true;
714*67e74705SXin Li     break;
715*67e74705SXin Li   }
716*67e74705SXin Li 
717*67e74705SXin Li   // Visit the template arguments used in the specialization.
718*67e74705SXin Li   if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
719*67e74705SXin Li     TypeLoc TL = SpecType->getTypeLoc();
720*67e74705SXin Li     if (TemplateSpecializationTypeLoc TSTLoc =
721*67e74705SXin Li             TL.getAs<TemplateSpecializationTypeLoc>()) {
722*67e74705SXin Li       for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
723*67e74705SXin Li         if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
724*67e74705SXin Li           return true;
725*67e74705SXin Li     }
726*67e74705SXin Li   }
727*67e74705SXin Li 
728*67e74705SXin Li   return ShouldVisitBody && VisitCXXRecordDecl(D);
729*67e74705SXin Li }
730*67e74705SXin Li 
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)731*67e74705SXin Li bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
732*67e74705SXin Li                                    ClassTemplatePartialSpecializationDecl *D) {
733*67e74705SXin Li   // FIXME: Visit the "outer" template parameter lists on the TagDecl
734*67e74705SXin Li   // before visiting these template parameters.
735*67e74705SXin Li   if (VisitTemplateParameters(D->getTemplateParameters()))
736*67e74705SXin Li     return true;
737*67e74705SXin Li 
738*67e74705SXin Li   // Visit the partial specialization arguments.
739*67e74705SXin Li   const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
740*67e74705SXin Li   const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
741*67e74705SXin Li   for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
742*67e74705SXin Li     if (VisitTemplateArgumentLoc(TemplateArgs[I]))
743*67e74705SXin Li       return true;
744*67e74705SXin Li 
745*67e74705SXin Li   return VisitCXXRecordDecl(D);
746*67e74705SXin Li }
747*67e74705SXin Li 
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)748*67e74705SXin Li bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
749*67e74705SXin Li   // Visit the default argument.
750*67e74705SXin Li   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
751*67e74705SXin Li     if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
752*67e74705SXin Li       if (Visit(DefArg->getTypeLoc()))
753*67e74705SXin Li         return true;
754*67e74705SXin Li 
755*67e74705SXin Li   return false;
756*67e74705SXin Li }
757*67e74705SXin Li 
VisitEnumConstantDecl(EnumConstantDecl * D)758*67e74705SXin Li bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
759*67e74705SXin Li   if (Expr *Init = D->getInitExpr())
760*67e74705SXin Li     return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
761*67e74705SXin Li   return false;
762*67e74705SXin Li }
763*67e74705SXin Li 
VisitDeclaratorDecl(DeclaratorDecl * DD)764*67e74705SXin Li bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
765*67e74705SXin Li   unsigned NumParamList = DD->getNumTemplateParameterLists();
766*67e74705SXin Li   for (unsigned i = 0; i < NumParamList; i++) {
767*67e74705SXin Li     TemplateParameterList* Params = DD->getTemplateParameterList(i);
768*67e74705SXin Li     if (VisitTemplateParameters(Params))
769*67e74705SXin Li       return true;
770*67e74705SXin Li   }
771*67e74705SXin Li 
772*67e74705SXin Li   if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
773*67e74705SXin Li     if (Visit(TSInfo->getTypeLoc()))
774*67e74705SXin Li       return true;
775*67e74705SXin Li 
776*67e74705SXin Li   // Visit the nested-name-specifier, if present.
777*67e74705SXin Li   if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
778*67e74705SXin Li     if (VisitNestedNameSpecifierLoc(QualifierLoc))
779*67e74705SXin Li       return true;
780*67e74705SXin Li 
781*67e74705SXin Li   return false;
782*67e74705SXin Li }
783*67e74705SXin Li 
784*67e74705SXin Li /// \brief Compare two base or member initializers based on their source order.
CompareCXXCtorInitializers(CXXCtorInitializer * const * X,CXXCtorInitializer * const * Y)785*67e74705SXin Li static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
786*67e74705SXin Li                                       CXXCtorInitializer *const *Y) {
787*67e74705SXin Li   return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
788*67e74705SXin Li }
789*67e74705SXin Li 
VisitFunctionDecl(FunctionDecl * ND)790*67e74705SXin Li bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
791*67e74705SXin Li   unsigned NumParamList = ND->getNumTemplateParameterLists();
792*67e74705SXin Li   for (unsigned i = 0; i < NumParamList; i++) {
793*67e74705SXin Li     TemplateParameterList* Params = ND->getTemplateParameterList(i);
794*67e74705SXin Li     if (VisitTemplateParameters(Params))
795*67e74705SXin Li       return true;
796*67e74705SXin Li   }
797*67e74705SXin Li 
798*67e74705SXin Li   if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
799*67e74705SXin Li     // Visit the function declaration's syntactic components in the order
800*67e74705SXin Li     // written. This requires a bit of work.
801*67e74705SXin Li     TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
802*67e74705SXin Li     FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
803*67e74705SXin Li 
804*67e74705SXin Li     // If we have a function declared directly (without the use of a typedef),
805*67e74705SXin Li     // visit just the return type. Otherwise, just visit the function's type
806*67e74705SXin Li     // now.
807*67e74705SXin Li     if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
808*67e74705SXin Li         (!FTL && Visit(TL)))
809*67e74705SXin Li       return true;
810*67e74705SXin Li 
811*67e74705SXin Li     // Visit the nested-name-specifier, if present.
812*67e74705SXin Li     if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
813*67e74705SXin Li       if (VisitNestedNameSpecifierLoc(QualifierLoc))
814*67e74705SXin Li         return true;
815*67e74705SXin Li 
816*67e74705SXin Li     // Visit the declaration name.
817*67e74705SXin Li     if (!isa<CXXDestructorDecl>(ND))
818*67e74705SXin Li       if (VisitDeclarationNameInfo(ND->getNameInfo()))
819*67e74705SXin Li         return true;
820*67e74705SXin Li 
821*67e74705SXin Li     // FIXME: Visit explicitly-specified template arguments!
822*67e74705SXin Li 
823*67e74705SXin Li     // Visit the function parameters, if we have a function type.
824*67e74705SXin Li     if (FTL && VisitFunctionTypeLoc(FTL, true))
825*67e74705SXin Li       return true;
826*67e74705SXin Li 
827*67e74705SXin Li     // FIXME: Attributes?
828*67e74705SXin Li   }
829*67e74705SXin Li 
830*67e74705SXin Li   if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
831*67e74705SXin Li     if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
832*67e74705SXin Li       // Find the initializers that were written in the source.
833*67e74705SXin Li       SmallVector<CXXCtorInitializer *, 4> WrittenInits;
834*67e74705SXin Li       for (auto *I : Constructor->inits()) {
835*67e74705SXin Li         if (!I->isWritten())
836*67e74705SXin Li           continue;
837*67e74705SXin Li 
838*67e74705SXin Li         WrittenInits.push_back(I);
839*67e74705SXin Li       }
840*67e74705SXin Li 
841*67e74705SXin Li       // Sort the initializers in source order
842*67e74705SXin Li       llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
843*67e74705SXin Li                            &CompareCXXCtorInitializers);
844*67e74705SXin Li 
845*67e74705SXin Li       // Visit the initializers in source order
846*67e74705SXin Li       for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
847*67e74705SXin Li         CXXCtorInitializer *Init = WrittenInits[I];
848*67e74705SXin Li         if (Init->isAnyMemberInitializer()) {
849*67e74705SXin Li           if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
850*67e74705SXin Li                                         Init->getMemberLocation(), TU)))
851*67e74705SXin Li             return true;
852*67e74705SXin Li         } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
853*67e74705SXin Li           if (Visit(TInfo->getTypeLoc()))
854*67e74705SXin Li             return true;
855*67e74705SXin Li         }
856*67e74705SXin Li 
857*67e74705SXin Li         // Visit the initializer value.
858*67e74705SXin Li         if (Expr *Initializer = Init->getInit())
859*67e74705SXin Li           if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
860*67e74705SXin Li             return true;
861*67e74705SXin Li       }
862*67e74705SXin Li     }
863*67e74705SXin Li 
864*67e74705SXin Li     if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
865*67e74705SXin Li       return true;
866*67e74705SXin Li   }
867*67e74705SXin Li 
868*67e74705SXin Li   return false;
869*67e74705SXin Li }
870*67e74705SXin Li 
VisitFieldDecl(FieldDecl * D)871*67e74705SXin Li bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
872*67e74705SXin Li   if (VisitDeclaratorDecl(D))
873*67e74705SXin Li     return true;
874*67e74705SXin Li 
875*67e74705SXin Li   if (Expr *BitWidth = D->getBitWidth())
876*67e74705SXin Li     return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
877*67e74705SXin Li 
878*67e74705SXin Li   return false;
879*67e74705SXin Li }
880*67e74705SXin Li 
VisitVarDecl(VarDecl * D)881*67e74705SXin Li bool CursorVisitor::VisitVarDecl(VarDecl *D) {
882*67e74705SXin Li   if (VisitDeclaratorDecl(D))
883*67e74705SXin Li     return true;
884*67e74705SXin Li 
885*67e74705SXin Li   if (Expr *Init = D->getInit())
886*67e74705SXin Li     return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
887*67e74705SXin Li 
888*67e74705SXin Li   return false;
889*67e74705SXin Li }
890*67e74705SXin Li 
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)891*67e74705SXin Li bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
892*67e74705SXin Li   if (VisitDeclaratorDecl(D))
893*67e74705SXin Li     return true;
894*67e74705SXin Li 
895*67e74705SXin Li   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
896*67e74705SXin Li     if (Expr *DefArg = D->getDefaultArgument())
897*67e74705SXin Li       return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
898*67e74705SXin Li 
899*67e74705SXin Li   return false;
900*67e74705SXin Li }
901*67e74705SXin Li 
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)902*67e74705SXin Li bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
903*67e74705SXin Li   // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
904*67e74705SXin Li   // before visiting these template parameters.
905*67e74705SXin Li   if (VisitTemplateParameters(D->getTemplateParameters()))
906*67e74705SXin Li     return true;
907*67e74705SXin Li 
908*67e74705SXin Li   return VisitFunctionDecl(D->getTemplatedDecl());
909*67e74705SXin Li }
910*67e74705SXin Li 
VisitClassTemplateDecl(ClassTemplateDecl * D)911*67e74705SXin Li bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
912*67e74705SXin Li   // FIXME: Visit the "outer" template parameter lists on the TagDecl
913*67e74705SXin Li   // before visiting these template parameters.
914*67e74705SXin Li   if (VisitTemplateParameters(D->getTemplateParameters()))
915*67e74705SXin Li     return true;
916*67e74705SXin Li 
917*67e74705SXin Li   return VisitCXXRecordDecl(D->getTemplatedDecl());
918*67e74705SXin Li }
919*67e74705SXin Li 
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)920*67e74705SXin Li bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
921*67e74705SXin Li   if (VisitTemplateParameters(D->getTemplateParameters()))
922*67e74705SXin Li     return true;
923*67e74705SXin Li 
924*67e74705SXin Li   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
925*67e74705SXin Li       VisitTemplateArgumentLoc(D->getDefaultArgument()))
926*67e74705SXin Li     return true;
927*67e74705SXin Li 
928*67e74705SXin Li   return false;
929*67e74705SXin Li }
930*67e74705SXin Li 
VisitObjCTypeParamDecl(ObjCTypeParamDecl * D)931*67e74705SXin Li bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
932*67e74705SXin Li   // Visit the bound, if it's explicit.
933*67e74705SXin Li   if (D->hasExplicitBound()) {
934*67e74705SXin Li     if (auto TInfo = D->getTypeSourceInfo()) {
935*67e74705SXin Li       if (Visit(TInfo->getTypeLoc()))
936*67e74705SXin Li         return true;
937*67e74705SXin Li     }
938*67e74705SXin Li   }
939*67e74705SXin Li 
940*67e74705SXin Li   return false;
941*67e74705SXin Li }
942*67e74705SXin Li 
VisitObjCMethodDecl(ObjCMethodDecl * ND)943*67e74705SXin Li bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
944*67e74705SXin Li   if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
945*67e74705SXin Li     if (Visit(TSInfo->getTypeLoc()))
946*67e74705SXin Li       return true;
947*67e74705SXin Li 
948*67e74705SXin Li   for (const auto *P : ND->parameters()) {
949*67e74705SXin Li     if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
950*67e74705SXin Li       return true;
951*67e74705SXin Li   }
952*67e74705SXin Li 
953*67e74705SXin Li   return ND->isThisDeclarationADefinition() &&
954*67e74705SXin Li          Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
955*67e74705SXin Li }
956*67e74705SXin Li 
957*67e74705SXin Li template <typename DeclIt>
addRangedDeclsInContainer(DeclIt * DI_current,DeclIt DE_current,SourceManager & SM,SourceLocation EndLoc,SmallVectorImpl<Decl * > & Decls)958*67e74705SXin Li static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
959*67e74705SXin Li                                       SourceManager &SM, SourceLocation EndLoc,
960*67e74705SXin Li                                       SmallVectorImpl<Decl *> &Decls) {
961*67e74705SXin Li   DeclIt next = *DI_current;
962*67e74705SXin Li   while (++next != DE_current) {
963*67e74705SXin Li     Decl *D_next = *next;
964*67e74705SXin Li     if (!D_next)
965*67e74705SXin Li       break;
966*67e74705SXin Li     SourceLocation L = D_next->getLocStart();
967*67e74705SXin Li     if (!L.isValid())
968*67e74705SXin Li       break;
969*67e74705SXin Li     if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
970*67e74705SXin Li       *DI_current = next;
971*67e74705SXin Li       Decls.push_back(D_next);
972*67e74705SXin Li       continue;
973*67e74705SXin Li     }
974*67e74705SXin Li     break;
975*67e74705SXin Li   }
976*67e74705SXin Li }
977*67e74705SXin Li 
VisitObjCContainerDecl(ObjCContainerDecl * D)978*67e74705SXin Li bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
979*67e74705SXin Li   // FIXME: Eventually convert back to just 'VisitDeclContext()'.  Essentially
980*67e74705SXin Li   // an @implementation can lexically contain Decls that are not properly
981*67e74705SXin Li   // nested in the AST.  When we identify such cases, we need to retrofit
982*67e74705SXin Li   // this nesting here.
983*67e74705SXin Li   if (!DI_current && !FileDI_current)
984*67e74705SXin Li     return VisitDeclContext(D);
985*67e74705SXin Li 
986*67e74705SXin Li   // Scan the Decls that immediately come after the container
987*67e74705SXin Li   // in the current DeclContext.  If any fall within the
988*67e74705SXin Li   // container's lexical region, stash them into a vector
989*67e74705SXin Li   // for later processing.
990*67e74705SXin Li   SmallVector<Decl *, 24> DeclsInContainer;
991*67e74705SXin Li   SourceLocation EndLoc = D->getSourceRange().getEnd();
992*67e74705SXin Li   SourceManager &SM = AU->getSourceManager();
993*67e74705SXin Li   if (EndLoc.isValid()) {
994*67e74705SXin Li     if (DI_current) {
995*67e74705SXin Li       addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
996*67e74705SXin Li                                 DeclsInContainer);
997*67e74705SXin Li     } else {
998*67e74705SXin Li       addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
999*67e74705SXin Li                                 DeclsInContainer);
1000*67e74705SXin Li     }
1001*67e74705SXin Li   }
1002*67e74705SXin Li 
1003*67e74705SXin Li   // The common case.
1004*67e74705SXin Li   if (DeclsInContainer.empty())
1005*67e74705SXin Li     return VisitDeclContext(D);
1006*67e74705SXin Li 
1007*67e74705SXin Li   // Get all the Decls in the DeclContext, and sort them with the
1008*67e74705SXin Li   // additional ones we've collected.  Then visit them.
1009*67e74705SXin Li   for (auto *SubDecl : D->decls()) {
1010*67e74705SXin Li     if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1011*67e74705SXin Li         SubDecl->getLocStart().isInvalid())
1012*67e74705SXin Li       continue;
1013*67e74705SXin Li     DeclsInContainer.push_back(SubDecl);
1014*67e74705SXin Li   }
1015*67e74705SXin Li 
1016*67e74705SXin Li   // Now sort the Decls so that they appear in lexical order.
1017*67e74705SXin Li   std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
1018*67e74705SXin Li             [&SM](Decl *A, Decl *B) {
1019*67e74705SXin Li     SourceLocation L_A = A->getLocStart();
1020*67e74705SXin Li     SourceLocation L_B = B->getLocStart();
1021*67e74705SXin Li     assert(L_A.isValid() && L_B.isValid());
1022*67e74705SXin Li     return SM.isBeforeInTranslationUnit(L_A, L_B);
1023*67e74705SXin Li   });
1024*67e74705SXin Li 
1025*67e74705SXin Li   // Now visit the decls.
1026*67e74705SXin Li   for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1027*67e74705SXin Li          E = DeclsInContainer.end(); I != E; ++I) {
1028*67e74705SXin Li     CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
1029*67e74705SXin Li     const Optional<bool> &V = shouldVisitCursor(Cursor);
1030*67e74705SXin Li     if (!V.hasValue())
1031*67e74705SXin Li       continue;
1032*67e74705SXin Li     if (!V.getValue())
1033*67e74705SXin Li       return false;
1034*67e74705SXin Li     if (Visit(Cursor, true))
1035*67e74705SXin Li       return true;
1036*67e74705SXin Li   }
1037*67e74705SXin Li   return false;
1038*67e74705SXin Li }
1039*67e74705SXin Li 
VisitObjCCategoryDecl(ObjCCategoryDecl * ND)1040*67e74705SXin Li bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1041*67e74705SXin Li   if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1042*67e74705SXin Li                                    TU)))
1043*67e74705SXin Li     return true;
1044*67e74705SXin Li 
1045*67e74705SXin Li   if (VisitObjCTypeParamList(ND->getTypeParamList()))
1046*67e74705SXin Li     return true;
1047*67e74705SXin Li 
1048*67e74705SXin Li   ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1049*67e74705SXin Li   for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1050*67e74705SXin Li          E = ND->protocol_end(); I != E; ++I, ++PL)
1051*67e74705SXin Li     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1052*67e74705SXin Li       return true;
1053*67e74705SXin Li 
1054*67e74705SXin Li   return VisitObjCContainerDecl(ND);
1055*67e74705SXin Li }
1056*67e74705SXin Li 
VisitObjCProtocolDecl(ObjCProtocolDecl * PID)1057*67e74705SXin Li bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1058*67e74705SXin Li   if (!PID->isThisDeclarationADefinition())
1059*67e74705SXin Li     return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1060*67e74705SXin Li 
1061*67e74705SXin Li   ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1062*67e74705SXin Li   for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1063*67e74705SXin Li        E = PID->protocol_end(); I != E; ++I, ++PL)
1064*67e74705SXin Li     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1065*67e74705SXin Li       return true;
1066*67e74705SXin Li 
1067*67e74705SXin Li   return VisitObjCContainerDecl(PID);
1068*67e74705SXin Li }
1069*67e74705SXin Li 
VisitObjCPropertyDecl(ObjCPropertyDecl * PD)1070*67e74705SXin Li bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1071*67e74705SXin Li   if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1072*67e74705SXin Li     return true;
1073*67e74705SXin Li 
1074*67e74705SXin Li   // FIXME: This implements a workaround with @property declarations also being
1075*67e74705SXin Li   // installed in the DeclContext for the @interface.  Eventually this code
1076*67e74705SXin Li   // should be removed.
1077*67e74705SXin Li   ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1078*67e74705SXin Li   if (!CDecl || !CDecl->IsClassExtension())
1079*67e74705SXin Li     return false;
1080*67e74705SXin Li 
1081*67e74705SXin Li   ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1082*67e74705SXin Li   if (!ID)
1083*67e74705SXin Li     return false;
1084*67e74705SXin Li 
1085*67e74705SXin Li   IdentifierInfo *PropertyId = PD->getIdentifier();
1086*67e74705SXin Li   ObjCPropertyDecl *prevDecl =
1087*67e74705SXin Li     ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId,
1088*67e74705SXin Li                                        PD->getQueryKind());
1089*67e74705SXin Li 
1090*67e74705SXin Li   if (!prevDecl)
1091*67e74705SXin Li     return false;
1092*67e74705SXin Li 
1093*67e74705SXin Li   // Visit synthesized methods since they will be skipped when visiting
1094*67e74705SXin Li   // the @interface.
1095*67e74705SXin Li   if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1096*67e74705SXin Li     if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1097*67e74705SXin Li       if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1098*67e74705SXin Li         return true;
1099*67e74705SXin Li 
1100*67e74705SXin Li   if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1101*67e74705SXin Li     if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1102*67e74705SXin Li       if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1103*67e74705SXin Li         return true;
1104*67e74705SXin Li 
1105*67e74705SXin Li   return false;
1106*67e74705SXin Li }
1107*67e74705SXin Li 
VisitObjCTypeParamList(ObjCTypeParamList * typeParamList)1108*67e74705SXin Li bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1109*67e74705SXin Li   if (!typeParamList)
1110*67e74705SXin Li     return false;
1111*67e74705SXin Li 
1112*67e74705SXin Li   for (auto *typeParam : *typeParamList) {
1113*67e74705SXin Li     // Visit the type parameter.
1114*67e74705SXin Li     if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1115*67e74705SXin Li       return true;
1116*67e74705SXin Li   }
1117*67e74705SXin Li 
1118*67e74705SXin Li   return false;
1119*67e74705SXin Li }
1120*67e74705SXin Li 
VisitObjCInterfaceDecl(ObjCInterfaceDecl * D)1121*67e74705SXin Li bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1122*67e74705SXin Li   if (!D->isThisDeclarationADefinition()) {
1123*67e74705SXin Li     // Forward declaration is treated like a reference.
1124*67e74705SXin Li     return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1125*67e74705SXin Li   }
1126*67e74705SXin Li 
1127*67e74705SXin Li   // Objective-C type parameters.
1128*67e74705SXin Li   if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1129*67e74705SXin Li     return true;
1130*67e74705SXin Li 
1131*67e74705SXin Li   // Issue callbacks for super class.
1132*67e74705SXin Li   if (D->getSuperClass() &&
1133*67e74705SXin Li       Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1134*67e74705SXin Li                                         D->getSuperClassLoc(),
1135*67e74705SXin Li                                         TU)))
1136*67e74705SXin Li     return true;
1137*67e74705SXin Li 
1138*67e74705SXin Li   if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1139*67e74705SXin Li     if (Visit(SuperClassTInfo->getTypeLoc()))
1140*67e74705SXin Li       return true;
1141*67e74705SXin Li 
1142*67e74705SXin Li   ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1143*67e74705SXin Li   for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1144*67e74705SXin Li          E = D->protocol_end(); I != E; ++I, ++PL)
1145*67e74705SXin Li     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1146*67e74705SXin Li       return true;
1147*67e74705SXin Li 
1148*67e74705SXin Li   return VisitObjCContainerDecl(D);
1149*67e74705SXin Li }
1150*67e74705SXin Li 
VisitObjCImplDecl(ObjCImplDecl * D)1151*67e74705SXin Li bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1152*67e74705SXin Li   return VisitObjCContainerDecl(D);
1153*67e74705SXin Li }
1154*67e74705SXin Li 
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)1155*67e74705SXin Li bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1156*67e74705SXin Li   // 'ID' could be null when dealing with invalid code.
1157*67e74705SXin Li   if (ObjCInterfaceDecl *ID = D->getClassInterface())
1158*67e74705SXin Li     if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1159*67e74705SXin Li       return true;
1160*67e74705SXin Li 
1161*67e74705SXin Li   return VisitObjCImplDecl(D);
1162*67e74705SXin Li }
1163*67e74705SXin Li 
VisitObjCImplementationDecl(ObjCImplementationDecl * D)1164*67e74705SXin Li bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1165*67e74705SXin Li #if 0
1166*67e74705SXin Li   // Issue callbacks for super class.
1167*67e74705SXin Li   // FIXME: No source location information!
1168*67e74705SXin Li   if (D->getSuperClass() &&
1169*67e74705SXin Li       Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1170*67e74705SXin Li                                         D->getSuperClassLoc(),
1171*67e74705SXin Li                                         TU)))
1172*67e74705SXin Li     return true;
1173*67e74705SXin Li #endif
1174*67e74705SXin Li 
1175*67e74705SXin Li   return VisitObjCImplDecl(D);
1176*67e74705SXin Li }
1177*67e74705SXin Li 
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * PD)1178*67e74705SXin Li bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1179*67e74705SXin Li   if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1180*67e74705SXin Li     if (PD->isIvarNameSpecified())
1181*67e74705SXin Li       return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1182*67e74705SXin Li 
1183*67e74705SXin Li   return false;
1184*67e74705SXin Li }
1185*67e74705SXin Li 
VisitNamespaceDecl(NamespaceDecl * D)1186*67e74705SXin Li bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1187*67e74705SXin Li   return VisitDeclContext(D);
1188*67e74705SXin Li }
1189*67e74705SXin Li 
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)1190*67e74705SXin Li bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1191*67e74705SXin Li   // Visit nested-name-specifier.
1192*67e74705SXin Li   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1193*67e74705SXin Li     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1194*67e74705SXin Li       return true;
1195*67e74705SXin Li 
1196*67e74705SXin Li   return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1197*67e74705SXin Li                                       D->getTargetNameLoc(), TU));
1198*67e74705SXin Li }
1199*67e74705SXin Li 
VisitUsingDecl(UsingDecl * D)1200*67e74705SXin Li bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1201*67e74705SXin Li   // Visit nested-name-specifier.
1202*67e74705SXin Li   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1203*67e74705SXin Li     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1204*67e74705SXin Li       return true;
1205*67e74705SXin Li   }
1206*67e74705SXin Li 
1207*67e74705SXin Li   if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1208*67e74705SXin Li     return true;
1209*67e74705SXin Li 
1210*67e74705SXin Li   return VisitDeclarationNameInfo(D->getNameInfo());
1211*67e74705SXin Li }
1212*67e74705SXin Li 
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)1213*67e74705SXin Li bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1214*67e74705SXin Li   // Visit nested-name-specifier.
1215*67e74705SXin Li   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1216*67e74705SXin Li     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1217*67e74705SXin Li       return true;
1218*67e74705SXin Li 
1219*67e74705SXin Li   return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1220*67e74705SXin Li                                       D->getIdentLocation(), TU));
1221*67e74705SXin Li }
1222*67e74705SXin Li 
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)1223*67e74705SXin Li bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1224*67e74705SXin Li   // Visit nested-name-specifier.
1225*67e74705SXin Li   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1226*67e74705SXin Li     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1227*67e74705SXin Li       return true;
1228*67e74705SXin Li   }
1229*67e74705SXin Li 
1230*67e74705SXin Li   return VisitDeclarationNameInfo(D->getNameInfo());
1231*67e74705SXin Li }
1232*67e74705SXin Li 
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)1233*67e74705SXin Li bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1234*67e74705SXin Li                                                UnresolvedUsingTypenameDecl *D) {
1235*67e74705SXin Li   // Visit nested-name-specifier.
1236*67e74705SXin Li   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1237*67e74705SXin Li     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1238*67e74705SXin Li       return true;
1239*67e74705SXin Li 
1240*67e74705SXin Li   return false;
1241*67e74705SXin Li }
1242*67e74705SXin Li 
VisitStaticAssertDecl(StaticAssertDecl * D)1243*67e74705SXin Li bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
1244*67e74705SXin Li   if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
1245*67e74705SXin Li     return true;
1246*67e74705SXin Li   if (Visit(MakeCXCursor(D->getMessage(), StmtParent, TU, RegionOfInterest)))
1247*67e74705SXin Li     return true;
1248*67e74705SXin Li   return false;
1249*67e74705SXin Li }
1250*67e74705SXin Li 
VisitDeclarationNameInfo(DeclarationNameInfo Name)1251*67e74705SXin Li bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1252*67e74705SXin Li   switch (Name.getName().getNameKind()) {
1253*67e74705SXin Li   case clang::DeclarationName::Identifier:
1254*67e74705SXin Li   case clang::DeclarationName::CXXLiteralOperatorName:
1255*67e74705SXin Li   case clang::DeclarationName::CXXOperatorName:
1256*67e74705SXin Li   case clang::DeclarationName::CXXUsingDirective:
1257*67e74705SXin Li     return false;
1258*67e74705SXin Li 
1259*67e74705SXin Li   case clang::DeclarationName::CXXConstructorName:
1260*67e74705SXin Li   case clang::DeclarationName::CXXDestructorName:
1261*67e74705SXin Li   case clang::DeclarationName::CXXConversionFunctionName:
1262*67e74705SXin Li     if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1263*67e74705SXin Li       return Visit(TSInfo->getTypeLoc());
1264*67e74705SXin Li     return false;
1265*67e74705SXin Li 
1266*67e74705SXin Li   case clang::DeclarationName::ObjCZeroArgSelector:
1267*67e74705SXin Li   case clang::DeclarationName::ObjCOneArgSelector:
1268*67e74705SXin Li   case clang::DeclarationName::ObjCMultiArgSelector:
1269*67e74705SXin Li     // FIXME: Per-identifier location info?
1270*67e74705SXin Li     return false;
1271*67e74705SXin Li   }
1272*67e74705SXin Li 
1273*67e74705SXin Li   llvm_unreachable("Invalid DeclarationName::Kind!");
1274*67e74705SXin Li }
1275*67e74705SXin Li 
VisitNestedNameSpecifier(NestedNameSpecifier * NNS,SourceRange Range)1276*67e74705SXin Li bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1277*67e74705SXin Li                                              SourceRange Range) {
1278*67e74705SXin Li   // FIXME: This whole routine is a hack to work around the lack of proper
1279*67e74705SXin Li   // source information in nested-name-specifiers (PR5791). Since we do have
1280*67e74705SXin Li   // a beginning source location, we can visit the first component of the
1281*67e74705SXin Li   // nested-name-specifier, if it's a single-token component.
1282*67e74705SXin Li   if (!NNS)
1283*67e74705SXin Li     return false;
1284*67e74705SXin Li 
1285*67e74705SXin Li   // Get the first component in the nested-name-specifier.
1286*67e74705SXin Li   while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1287*67e74705SXin Li     NNS = Prefix;
1288*67e74705SXin Li 
1289*67e74705SXin Li   switch (NNS->getKind()) {
1290*67e74705SXin Li   case NestedNameSpecifier::Namespace:
1291*67e74705SXin Li     return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1292*67e74705SXin Li                                         TU));
1293*67e74705SXin Li 
1294*67e74705SXin Li   case NestedNameSpecifier::NamespaceAlias:
1295*67e74705SXin Li     return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1296*67e74705SXin Li                                         Range.getBegin(), TU));
1297*67e74705SXin Li 
1298*67e74705SXin Li   case NestedNameSpecifier::TypeSpec: {
1299*67e74705SXin Li     // If the type has a form where we know that the beginning of the source
1300*67e74705SXin Li     // range matches up with a reference cursor. Visit the appropriate reference
1301*67e74705SXin Li     // cursor.
1302*67e74705SXin Li     const Type *T = NNS->getAsType();
1303*67e74705SXin Li     if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1304*67e74705SXin Li       return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1305*67e74705SXin Li     if (const TagType *Tag = dyn_cast<TagType>(T))
1306*67e74705SXin Li       return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1307*67e74705SXin Li     if (const TemplateSpecializationType *TST
1308*67e74705SXin Li                                       = dyn_cast<TemplateSpecializationType>(T))
1309*67e74705SXin Li       return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1310*67e74705SXin Li     break;
1311*67e74705SXin Li   }
1312*67e74705SXin Li 
1313*67e74705SXin Li   case NestedNameSpecifier::TypeSpecWithTemplate:
1314*67e74705SXin Li   case NestedNameSpecifier::Global:
1315*67e74705SXin Li   case NestedNameSpecifier::Identifier:
1316*67e74705SXin Li   case NestedNameSpecifier::Super:
1317*67e74705SXin Li     break;
1318*67e74705SXin Li   }
1319*67e74705SXin Li 
1320*67e74705SXin Li   return false;
1321*67e74705SXin Li }
1322*67e74705SXin Li 
1323*67e74705SXin Li bool
VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)1324*67e74705SXin Li CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1325*67e74705SXin Li   SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1326*67e74705SXin Li   for (; Qualifier; Qualifier = Qualifier.getPrefix())
1327*67e74705SXin Li     Qualifiers.push_back(Qualifier);
1328*67e74705SXin Li 
1329*67e74705SXin Li   while (!Qualifiers.empty()) {
1330*67e74705SXin Li     NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1331*67e74705SXin Li     NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1332*67e74705SXin Li     switch (NNS->getKind()) {
1333*67e74705SXin Li     case NestedNameSpecifier::Namespace:
1334*67e74705SXin Li       if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1335*67e74705SXin Li                                        Q.getLocalBeginLoc(),
1336*67e74705SXin Li                                        TU)))
1337*67e74705SXin Li         return true;
1338*67e74705SXin Li 
1339*67e74705SXin Li       break;
1340*67e74705SXin Li 
1341*67e74705SXin Li     case NestedNameSpecifier::NamespaceAlias:
1342*67e74705SXin Li       if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1343*67e74705SXin Li                                        Q.getLocalBeginLoc(),
1344*67e74705SXin Li                                        TU)))
1345*67e74705SXin Li         return true;
1346*67e74705SXin Li 
1347*67e74705SXin Li       break;
1348*67e74705SXin Li 
1349*67e74705SXin Li     case NestedNameSpecifier::TypeSpec:
1350*67e74705SXin Li     case NestedNameSpecifier::TypeSpecWithTemplate:
1351*67e74705SXin Li       if (Visit(Q.getTypeLoc()))
1352*67e74705SXin Li         return true;
1353*67e74705SXin Li 
1354*67e74705SXin Li       break;
1355*67e74705SXin Li 
1356*67e74705SXin Li     case NestedNameSpecifier::Global:
1357*67e74705SXin Li     case NestedNameSpecifier::Identifier:
1358*67e74705SXin Li     case NestedNameSpecifier::Super:
1359*67e74705SXin Li       break;
1360*67e74705SXin Li     }
1361*67e74705SXin Li   }
1362*67e74705SXin Li 
1363*67e74705SXin Li   return false;
1364*67e74705SXin Li }
1365*67e74705SXin Li 
VisitTemplateParameters(const TemplateParameterList * Params)1366*67e74705SXin Li bool CursorVisitor::VisitTemplateParameters(
1367*67e74705SXin Li                                           const TemplateParameterList *Params) {
1368*67e74705SXin Li   if (!Params)
1369*67e74705SXin Li     return false;
1370*67e74705SXin Li 
1371*67e74705SXin Li   for (TemplateParameterList::const_iterator P = Params->begin(),
1372*67e74705SXin Li                                           PEnd = Params->end();
1373*67e74705SXin Li        P != PEnd; ++P) {
1374*67e74705SXin Li     if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1375*67e74705SXin Li       return true;
1376*67e74705SXin Li   }
1377*67e74705SXin Li 
1378*67e74705SXin Li   return false;
1379*67e74705SXin Li }
1380*67e74705SXin Li 
VisitTemplateName(TemplateName Name,SourceLocation Loc)1381*67e74705SXin Li bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1382*67e74705SXin Li   switch (Name.getKind()) {
1383*67e74705SXin Li   case TemplateName::Template:
1384*67e74705SXin Li     return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1385*67e74705SXin Li 
1386*67e74705SXin Li   case TemplateName::OverloadedTemplate:
1387*67e74705SXin Li     // Visit the overloaded template set.
1388*67e74705SXin Li     if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1389*67e74705SXin Li       return true;
1390*67e74705SXin Li 
1391*67e74705SXin Li     return false;
1392*67e74705SXin Li 
1393*67e74705SXin Li   case TemplateName::DependentTemplate:
1394*67e74705SXin Li     // FIXME: Visit nested-name-specifier.
1395*67e74705SXin Li     return false;
1396*67e74705SXin Li 
1397*67e74705SXin Li   case TemplateName::QualifiedTemplate:
1398*67e74705SXin Li     // FIXME: Visit nested-name-specifier.
1399*67e74705SXin Li     return Visit(MakeCursorTemplateRef(
1400*67e74705SXin Li                                   Name.getAsQualifiedTemplateName()->getDecl(),
1401*67e74705SXin Li                                        Loc, TU));
1402*67e74705SXin Li 
1403*67e74705SXin Li   case TemplateName::SubstTemplateTemplateParm:
1404*67e74705SXin Li     return Visit(MakeCursorTemplateRef(
1405*67e74705SXin Li                          Name.getAsSubstTemplateTemplateParm()->getParameter(),
1406*67e74705SXin Li                                        Loc, TU));
1407*67e74705SXin Li 
1408*67e74705SXin Li   case TemplateName::SubstTemplateTemplateParmPack:
1409*67e74705SXin Li     return Visit(MakeCursorTemplateRef(
1410*67e74705SXin Li                   Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1411*67e74705SXin Li                                        Loc, TU));
1412*67e74705SXin Li   }
1413*67e74705SXin Li 
1414*67e74705SXin Li   llvm_unreachable("Invalid TemplateName::Kind!");
1415*67e74705SXin Li }
1416*67e74705SXin Li 
VisitTemplateArgumentLoc(const TemplateArgumentLoc & TAL)1417*67e74705SXin Li bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1418*67e74705SXin Li   switch (TAL.getArgument().getKind()) {
1419*67e74705SXin Li   case TemplateArgument::Null:
1420*67e74705SXin Li   case TemplateArgument::Integral:
1421*67e74705SXin Li   case TemplateArgument::Pack:
1422*67e74705SXin Li     return false;
1423*67e74705SXin Li 
1424*67e74705SXin Li   case TemplateArgument::Type:
1425*67e74705SXin Li     if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1426*67e74705SXin Li       return Visit(TSInfo->getTypeLoc());
1427*67e74705SXin Li     return false;
1428*67e74705SXin Li 
1429*67e74705SXin Li   case TemplateArgument::Declaration:
1430*67e74705SXin Li     if (Expr *E = TAL.getSourceDeclExpression())
1431*67e74705SXin Li       return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1432*67e74705SXin Li     return false;
1433*67e74705SXin Li 
1434*67e74705SXin Li   case TemplateArgument::NullPtr:
1435*67e74705SXin Li     if (Expr *E = TAL.getSourceNullPtrExpression())
1436*67e74705SXin Li       return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1437*67e74705SXin Li     return false;
1438*67e74705SXin Li 
1439*67e74705SXin Li   case TemplateArgument::Expression:
1440*67e74705SXin Li     if (Expr *E = TAL.getSourceExpression())
1441*67e74705SXin Li       return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1442*67e74705SXin Li     return false;
1443*67e74705SXin Li 
1444*67e74705SXin Li   case TemplateArgument::Template:
1445*67e74705SXin Li   case TemplateArgument::TemplateExpansion:
1446*67e74705SXin Li     if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1447*67e74705SXin Li       return true;
1448*67e74705SXin Li 
1449*67e74705SXin Li     return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1450*67e74705SXin Li                              TAL.getTemplateNameLoc());
1451*67e74705SXin Li   }
1452*67e74705SXin Li 
1453*67e74705SXin Li   llvm_unreachable("Invalid TemplateArgument::Kind!");
1454*67e74705SXin Li }
1455*67e74705SXin Li 
VisitLinkageSpecDecl(LinkageSpecDecl * D)1456*67e74705SXin Li bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1457*67e74705SXin Li   return VisitDeclContext(D);
1458*67e74705SXin Li }
1459*67e74705SXin Li 
VisitQualifiedTypeLoc(QualifiedTypeLoc TL)1460*67e74705SXin Li bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1461*67e74705SXin Li   return Visit(TL.getUnqualifiedLoc());
1462*67e74705SXin Li }
1463*67e74705SXin Li 
VisitBuiltinTypeLoc(BuiltinTypeLoc TL)1464*67e74705SXin Li bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1465*67e74705SXin Li   ASTContext &Context = AU->getASTContext();
1466*67e74705SXin Li 
1467*67e74705SXin Li   // Some builtin types (such as Objective-C's "id", "sel", and
1468*67e74705SXin Li   // "Class") have associated declarations. Create cursors for those.
1469*67e74705SXin Li   QualType VisitType;
1470*67e74705SXin Li   switch (TL.getTypePtr()->getKind()) {
1471*67e74705SXin Li 
1472*67e74705SXin Li   case BuiltinType::Void:
1473*67e74705SXin Li   case BuiltinType::NullPtr:
1474*67e74705SXin Li   case BuiltinType::Dependent:
1475*67e74705SXin Li #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
1476*67e74705SXin Li   case BuiltinType::Id:
1477*67e74705SXin Li #include "clang/Basic/OpenCLImageTypes.def"
1478*67e74705SXin Li   case BuiltinType::OCLSampler:
1479*67e74705SXin Li   case BuiltinType::OCLEvent:
1480*67e74705SXin Li   case BuiltinType::OCLClkEvent:
1481*67e74705SXin Li   case BuiltinType::OCLQueue:
1482*67e74705SXin Li   case BuiltinType::OCLNDRange:
1483*67e74705SXin Li   case BuiltinType::OCLReserveID:
1484*67e74705SXin Li #define BUILTIN_TYPE(Id, SingletonId)
1485*67e74705SXin Li #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1486*67e74705SXin Li #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1487*67e74705SXin Li #define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1488*67e74705SXin Li #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1489*67e74705SXin Li #include "clang/AST/BuiltinTypes.def"
1490*67e74705SXin Li     break;
1491*67e74705SXin Li 
1492*67e74705SXin Li   case BuiltinType::ObjCId:
1493*67e74705SXin Li     VisitType = Context.getObjCIdType();
1494*67e74705SXin Li     break;
1495*67e74705SXin Li 
1496*67e74705SXin Li   case BuiltinType::ObjCClass:
1497*67e74705SXin Li     VisitType = Context.getObjCClassType();
1498*67e74705SXin Li     break;
1499*67e74705SXin Li 
1500*67e74705SXin Li   case BuiltinType::ObjCSel:
1501*67e74705SXin Li     VisitType = Context.getObjCSelType();
1502*67e74705SXin Li     break;
1503*67e74705SXin Li   }
1504*67e74705SXin Li 
1505*67e74705SXin Li   if (!VisitType.isNull()) {
1506*67e74705SXin Li     if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1507*67e74705SXin Li       return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1508*67e74705SXin Li                                      TU));
1509*67e74705SXin Li   }
1510*67e74705SXin Li 
1511*67e74705SXin Li   return false;
1512*67e74705SXin Li }
1513*67e74705SXin Li 
VisitTypedefTypeLoc(TypedefTypeLoc TL)1514*67e74705SXin Li bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1515*67e74705SXin Li   return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1516*67e74705SXin Li }
1517*67e74705SXin Li 
VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL)1518*67e74705SXin Li bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1519*67e74705SXin Li   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1520*67e74705SXin Li }
1521*67e74705SXin Li 
VisitTagTypeLoc(TagTypeLoc TL)1522*67e74705SXin Li bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1523*67e74705SXin Li   if (TL.isDefinition())
1524*67e74705SXin Li     return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1525*67e74705SXin Li 
1526*67e74705SXin Li   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1527*67e74705SXin Li }
1528*67e74705SXin Li 
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)1529*67e74705SXin Li bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1530*67e74705SXin Li   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1531*67e74705SXin Li }
1532*67e74705SXin Li 
VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL)1533*67e74705SXin Li bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1534*67e74705SXin Li   return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
1535*67e74705SXin Li }
1536*67e74705SXin Li 
VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL)1537*67e74705SXin Li bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1538*67e74705SXin Li   if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1539*67e74705SXin Li     return true;
1540*67e74705SXin Li 
1541*67e74705SXin Li   for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1542*67e74705SXin Li     if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1543*67e74705SXin Li       return true;
1544*67e74705SXin Li   }
1545*67e74705SXin Li 
1546*67e74705SXin Li   for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1547*67e74705SXin Li     if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1548*67e74705SXin Li                                         TU)))
1549*67e74705SXin Li       return true;
1550*67e74705SXin Li   }
1551*67e74705SXin Li 
1552*67e74705SXin Li   return false;
1553*67e74705SXin Li }
1554*67e74705SXin Li 
VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL)1555*67e74705SXin Li bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1556*67e74705SXin Li   return Visit(TL.getPointeeLoc());
1557*67e74705SXin Li }
1558*67e74705SXin Li 
VisitParenTypeLoc(ParenTypeLoc TL)1559*67e74705SXin Li bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1560*67e74705SXin Li   return Visit(TL.getInnerLoc());
1561*67e74705SXin Li }
1562*67e74705SXin Li 
VisitPointerTypeLoc(PointerTypeLoc TL)1563*67e74705SXin Li bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1564*67e74705SXin Li   return Visit(TL.getPointeeLoc());
1565*67e74705SXin Li }
1566*67e74705SXin Li 
VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL)1567*67e74705SXin Li bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1568*67e74705SXin Li   return Visit(TL.getPointeeLoc());
1569*67e74705SXin Li }
1570*67e74705SXin Li 
VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL)1571*67e74705SXin Li bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1572*67e74705SXin Li   return Visit(TL.getPointeeLoc());
1573*67e74705SXin Li }
1574*67e74705SXin Li 
VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL)1575*67e74705SXin Li bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1576*67e74705SXin Li   return Visit(TL.getPointeeLoc());
1577*67e74705SXin Li }
1578*67e74705SXin Li 
VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL)1579*67e74705SXin Li bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1580*67e74705SXin Li   return Visit(TL.getPointeeLoc());
1581*67e74705SXin Li }
1582*67e74705SXin Li 
VisitAttributedTypeLoc(AttributedTypeLoc TL)1583*67e74705SXin Li bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1584*67e74705SXin Li   return Visit(TL.getModifiedLoc());
1585*67e74705SXin Li }
1586*67e74705SXin Li 
VisitFunctionTypeLoc(FunctionTypeLoc TL,bool SkipResultType)1587*67e74705SXin Li bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1588*67e74705SXin Li                                          bool SkipResultType) {
1589*67e74705SXin Li   if (!SkipResultType && Visit(TL.getReturnLoc()))
1590*67e74705SXin Li     return true;
1591*67e74705SXin Li 
1592*67e74705SXin Li   for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1593*67e74705SXin Li     if (Decl *D = TL.getParam(I))
1594*67e74705SXin Li       if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1595*67e74705SXin Li         return true;
1596*67e74705SXin Li 
1597*67e74705SXin Li   return false;
1598*67e74705SXin Li }
1599*67e74705SXin Li 
VisitArrayTypeLoc(ArrayTypeLoc TL)1600*67e74705SXin Li bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1601*67e74705SXin Li   if (Visit(TL.getElementLoc()))
1602*67e74705SXin Li     return true;
1603*67e74705SXin Li 
1604*67e74705SXin Li   if (Expr *Size = TL.getSizeExpr())
1605*67e74705SXin Li     return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1606*67e74705SXin Li 
1607*67e74705SXin Li   return false;
1608*67e74705SXin Li }
1609*67e74705SXin Li 
VisitDecayedTypeLoc(DecayedTypeLoc TL)1610*67e74705SXin Li bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1611*67e74705SXin Li   return Visit(TL.getOriginalLoc());
1612*67e74705SXin Li }
1613*67e74705SXin Li 
VisitAdjustedTypeLoc(AdjustedTypeLoc TL)1614*67e74705SXin Li bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1615*67e74705SXin Li   return Visit(TL.getOriginalLoc());
1616*67e74705SXin Li }
1617*67e74705SXin Li 
VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)1618*67e74705SXin Li bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1619*67e74705SXin Li                                              TemplateSpecializationTypeLoc TL) {
1620*67e74705SXin Li   // Visit the template name.
1621*67e74705SXin Li   if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1622*67e74705SXin Li                         TL.getTemplateNameLoc()))
1623*67e74705SXin Li     return true;
1624*67e74705SXin Li 
1625*67e74705SXin Li   // Visit the template arguments.
1626*67e74705SXin Li   for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1627*67e74705SXin Li     if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1628*67e74705SXin Li       return true;
1629*67e74705SXin Li 
1630*67e74705SXin Li   return false;
1631*67e74705SXin Li }
1632*67e74705SXin Li 
VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL)1633*67e74705SXin Li bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1634*67e74705SXin Li   return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1635*67e74705SXin Li }
1636*67e74705SXin Li 
VisitTypeOfTypeLoc(TypeOfTypeLoc TL)1637*67e74705SXin Li bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1638*67e74705SXin Li   if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1639*67e74705SXin Li     return Visit(TSInfo->getTypeLoc());
1640*67e74705SXin Li 
1641*67e74705SXin Li   return false;
1642*67e74705SXin Li }
1643*67e74705SXin Li 
VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL)1644*67e74705SXin Li bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1645*67e74705SXin Li   if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1646*67e74705SXin Li     return Visit(TSInfo->getTypeLoc());
1647*67e74705SXin Li 
1648*67e74705SXin Li   return false;
1649*67e74705SXin Li }
1650*67e74705SXin Li 
VisitDependentNameTypeLoc(DependentNameTypeLoc TL)1651*67e74705SXin Li bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1652*67e74705SXin Li   return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
1653*67e74705SXin Li }
1654*67e74705SXin Li 
VisitDependentTemplateSpecializationTypeLoc(DependentTemplateSpecializationTypeLoc TL)1655*67e74705SXin Li bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1656*67e74705SXin Li                                     DependentTemplateSpecializationTypeLoc TL) {
1657*67e74705SXin Li   // Visit the nested-name-specifier, if there is one.
1658*67e74705SXin Li   if (TL.getQualifierLoc() &&
1659*67e74705SXin Li       VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1660*67e74705SXin Li     return true;
1661*67e74705SXin Li 
1662*67e74705SXin Li   // Visit the template arguments.
1663*67e74705SXin Li   for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1664*67e74705SXin Li     if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1665*67e74705SXin Li       return true;
1666*67e74705SXin Li 
1667*67e74705SXin Li   return false;
1668*67e74705SXin Li }
1669*67e74705SXin Li 
VisitElaboratedTypeLoc(ElaboratedTypeLoc TL)1670*67e74705SXin Li bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1671*67e74705SXin Li   if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1672*67e74705SXin Li     return true;
1673*67e74705SXin Li 
1674*67e74705SXin Li   return Visit(TL.getNamedTypeLoc());
1675*67e74705SXin Li }
1676*67e74705SXin Li 
VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL)1677*67e74705SXin Li bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1678*67e74705SXin Li   return Visit(TL.getPatternLoc());
1679*67e74705SXin Li }
1680*67e74705SXin Li 
VisitDecltypeTypeLoc(DecltypeTypeLoc TL)1681*67e74705SXin Li bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1682*67e74705SXin Li   if (Expr *E = TL.getUnderlyingExpr())
1683*67e74705SXin Li     return Visit(MakeCXCursor(E, StmtParent, TU));
1684*67e74705SXin Li 
1685*67e74705SXin Li   return false;
1686*67e74705SXin Li }
1687*67e74705SXin Li 
VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL)1688*67e74705SXin Li bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1689*67e74705SXin Li   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1690*67e74705SXin Li }
1691*67e74705SXin Li 
VisitAtomicTypeLoc(AtomicTypeLoc TL)1692*67e74705SXin Li bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1693*67e74705SXin Li   return Visit(TL.getValueLoc());
1694*67e74705SXin Li }
1695*67e74705SXin Li 
VisitPipeTypeLoc(PipeTypeLoc TL)1696*67e74705SXin Li bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1697*67e74705SXin Li   return Visit(TL.getValueLoc());
1698*67e74705SXin Li }
1699*67e74705SXin Li 
1700*67e74705SXin Li #define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1701*67e74705SXin Li bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1702*67e74705SXin Li   return Visit##PARENT##Loc(TL); \
1703*67e74705SXin Li }
1704*67e74705SXin Li 
DEFAULT_TYPELOC_IMPL(Complex,Type)1705*67e74705SXin Li DEFAULT_TYPELOC_IMPL(Complex, Type)
1706*67e74705SXin Li DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1707*67e74705SXin Li DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1708*67e74705SXin Li DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1709*67e74705SXin Li DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1710*67e74705SXin Li DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1711*67e74705SXin Li DEFAULT_TYPELOC_IMPL(Vector, Type)
1712*67e74705SXin Li DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1713*67e74705SXin Li DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1714*67e74705SXin Li DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1715*67e74705SXin Li DEFAULT_TYPELOC_IMPL(Record, TagType)
1716*67e74705SXin Li DEFAULT_TYPELOC_IMPL(Enum, TagType)
1717*67e74705SXin Li DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1718*67e74705SXin Li DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1719*67e74705SXin Li DEFAULT_TYPELOC_IMPL(Auto, Type)
1720*67e74705SXin Li 
1721*67e74705SXin Li bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1722*67e74705SXin Li   // Visit the nested-name-specifier, if present.
1723*67e74705SXin Li   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1724*67e74705SXin Li     if (VisitNestedNameSpecifierLoc(QualifierLoc))
1725*67e74705SXin Li       return true;
1726*67e74705SXin Li 
1727*67e74705SXin Li   if (D->isCompleteDefinition()) {
1728*67e74705SXin Li     for (const auto &I : D->bases()) {
1729*67e74705SXin Li       if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
1730*67e74705SXin Li         return true;
1731*67e74705SXin Li     }
1732*67e74705SXin Li   }
1733*67e74705SXin Li 
1734*67e74705SXin Li   return VisitTagDecl(D);
1735*67e74705SXin Li }
1736*67e74705SXin Li 
VisitAttributes(Decl * D)1737*67e74705SXin Li bool CursorVisitor::VisitAttributes(Decl *D) {
1738*67e74705SXin Li   for (const auto *I : D->attrs())
1739*67e74705SXin Li     if (Visit(MakeCXCursor(I, D, TU)))
1740*67e74705SXin Li         return true;
1741*67e74705SXin Li 
1742*67e74705SXin Li   return false;
1743*67e74705SXin Li }
1744*67e74705SXin Li 
1745*67e74705SXin Li //===----------------------------------------------------------------------===//
1746*67e74705SXin Li // Data-recursive visitor methods.
1747*67e74705SXin Li //===----------------------------------------------------------------------===//
1748*67e74705SXin Li 
1749*67e74705SXin Li namespace {
1750*67e74705SXin Li #define DEF_JOB(NAME, DATA, KIND)\
1751*67e74705SXin Li class NAME : public VisitorJob {\
1752*67e74705SXin Li public:\
1753*67e74705SXin Li   NAME(const DATA *d, CXCursor parent) : \
1754*67e74705SXin Li       VisitorJob(parent, VisitorJob::KIND, d) {} \
1755*67e74705SXin Li   static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
1756*67e74705SXin Li   const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
1757*67e74705SXin Li };
1758*67e74705SXin Li 
1759*67e74705SXin Li DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1760*67e74705SXin Li DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1761*67e74705SXin Li DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1762*67e74705SXin Li DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1763*67e74705SXin Li DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1764*67e74705SXin Li DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1765*67e74705SXin Li DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1766*67e74705SXin Li #undef DEF_JOB
1767*67e74705SXin Li 
1768*67e74705SXin Li class ExplicitTemplateArgsVisit : public VisitorJob {
1769*67e74705SXin Li public:
ExplicitTemplateArgsVisit(const TemplateArgumentLoc * Begin,const TemplateArgumentLoc * End,CXCursor parent)1770*67e74705SXin Li   ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1771*67e74705SXin Li                             const TemplateArgumentLoc *End, CXCursor parent)
1772*67e74705SXin Li       : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1773*67e74705SXin Li                    End) {}
classof(const VisitorJob * VJ)1774*67e74705SXin Li   static bool classof(const VisitorJob *VJ) {
1775*67e74705SXin Li     return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1776*67e74705SXin Li   }
begin() const1777*67e74705SXin Li   const TemplateArgumentLoc *begin() const {
1778*67e74705SXin Li     return static_cast<const TemplateArgumentLoc *>(data[0]);
1779*67e74705SXin Li   }
end()1780*67e74705SXin Li   const TemplateArgumentLoc *end() {
1781*67e74705SXin Li     return static_cast<const TemplateArgumentLoc *>(data[1]);
1782*67e74705SXin Li   }
1783*67e74705SXin Li };
1784*67e74705SXin Li class DeclVisit : public VisitorJob {
1785*67e74705SXin Li public:
DeclVisit(const Decl * D,CXCursor parent,bool isFirst)1786*67e74705SXin Li   DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
1787*67e74705SXin Li     VisitorJob(parent, VisitorJob::DeclVisitKind,
1788*67e74705SXin Li                D, isFirst ? (void*) 1 : (void*) nullptr) {}
classof(const VisitorJob * VJ)1789*67e74705SXin Li   static bool classof(const VisitorJob *VJ) {
1790*67e74705SXin Li     return VJ->getKind() == DeclVisitKind;
1791*67e74705SXin Li   }
get() const1792*67e74705SXin Li   const Decl *get() const { return static_cast<const Decl *>(data[0]); }
isFirst() const1793*67e74705SXin Li   bool isFirst() const { return data[1] != nullptr; }
1794*67e74705SXin Li };
1795*67e74705SXin Li class TypeLocVisit : public VisitorJob {
1796*67e74705SXin Li public:
TypeLocVisit(TypeLoc tl,CXCursor parent)1797*67e74705SXin Li   TypeLocVisit(TypeLoc tl, CXCursor parent) :
1798*67e74705SXin Li     VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1799*67e74705SXin Li                tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1800*67e74705SXin Li 
classof(const VisitorJob * VJ)1801*67e74705SXin Li   static bool classof(const VisitorJob *VJ) {
1802*67e74705SXin Li     return VJ->getKind() == TypeLocVisitKind;
1803*67e74705SXin Li   }
1804*67e74705SXin Li 
get() const1805*67e74705SXin Li   TypeLoc get() const {
1806*67e74705SXin Li     QualType T = QualType::getFromOpaquePtr(data[0]);
1807*67e74705SXin Li     return TypeLoc(T, const_cast<void *>(data[1]));
1808*67e74705SXin Li   }
1809*67e74705SXin Li };
1810*67e74705SXin Li 
1811*67e74705SXin Li class LabelRefVisit : public VisitorJob {
1812*67e74705SXin Li public:
LabelRefVisit(LabelDecl * LD,SourceLocation labelLoc,CXCursor parent)1813*67e74705SXin Li   LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1814*67e74705SXin Li     : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1815*67e74705SXin Li                  labelLoc.getPtrEncoding()) {}
1816*67e74705SXin Li 
classof(const VisitorJob * VJ)1817*67e74705SXin Li   static bool classof(const VisitorJob *VJ) {
1818*67e74705SXin Li     return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1819*67e74705SXin Li   }
get() const1820*67e74705SXin Li   const LabelDecl *get() const {
1821*67e74705SXin Li     return static_cast<const LabelDecl *>(data[0]);
1822*67e74705SXin Li   }
getLoc() const1823*67e74705SXin Li   SourceLocation getLoc() const {
1824*67e74705SXin Li     return SourceLocation::getFromPtrEncoding(data[1]); }
1825*67e74705SXin Li };
1826*67e74705SXin Li 
1827*67e74705SXin Li class NestedNameSpecifierLocVisit : public VisitorJob {
1828*67e74705SXin Li public:
NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier,CXCursor parent)1829*67e74705SXin Li   NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1830*67e74705SXin Li     : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1831*67e74705SXin Li                  Qualifier.getNestedNameSpecifier(),
1832*67e74705SXin Li                  Qualifier.getOpaqueData()) { }
1833*67e74705SXin Li 
classof(const VisitorJob * VJ)1834*67e74705SXin Li   static bool classof(const VisitorJob *VJ) {
1835*67e74705SXin Li     return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1836*67e74705SXin Li   }
1837*67e74705SXin Li 
get() const1838*67e74705SXin Li   NestedNameSpecifierLoc get() const {
1839*67e74705SXin Li     return NestedNameSpecifierLoc(
1840*67e74705SXin Li             const_cast<NestedNameSpecifier *>(
1841*67e74705SXin Li               static_cast<const NestedNameSpecifier *>(data[0])),
1842*67e74705SXin Li             const_cast<void *>(data[1]));
1843*67e74705SXin Li   }
1844*67e74705SXin Li };
1845*67e74705SXin Li 
1846*67e74705SXin Li class DeclarationNameInfoVisit : public VisitorJob {
1847*67e74705SXin Li public:
DeclarationNameInfoVisit(const Stmt * S,CXCursor parent)1848*67e74705SXin Li   DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
1849*67e74705SXin Li     : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
classof(const VisitorJob * VJ)1850*67e74705SXin Li   static bool classof(const VisitorJob *VJ) {
1851*67e74705SXin Li     return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1852*67e74705SXin Li   }
get() const1853*67e74705SXin Li   DeclarationNameInfo get() const {
1854*67e74705SXin Li     const Stmt *S = static_cast<const Stmt *>(data[0]);
1855*67e74705SXin Li     switch (S->getStmtClass()) {
1856*67e74705SXin Li     default:
1857*67e74705SXin Li       llvm_unreachable("Unhandled Stmt");
1858*67e74705SXin Li     case clang::Stmt::MSDependentExistsStmtClass:
1859*67e74705SXin Li       return cast<MSDependentExistsStmt>(S)->getNameInfo();
1860*67e74705SXin Li     case Stmt::CXXDependentScopeMemberExprClass:
1861*67e74705SXin Li       return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1862*67e74705SXin Li     case Stmt::DependentScopeDeclRefExprClass:
1863*67e74705SXin Li       return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1864*67e74705SXin Li     case Stmt::OMPCriticalDirectiveClass:
1865*67e74705SXin Li       return cast<OMPCriticalDirective>(S)->getDirectiveName();
1866*67e74705SXin Li     }
1867*67e74705SXin Li   }
1868*67e74705SXin Li };
1869*67e74705SXin Li class MemberRefVisit : public VisitorJob {
1870*67e74705SXin Li public:
MemberRefVisit(const FieldDecl * D,SourceLocation L,CXCursor parent)1871*67e74705SXin Li   MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
1872*67e74705SXin Li     : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1873*67e74705SXin Li                  L.getPtrEncoding()) {}
classof(const VisitorJob * VJ)1874*67e74705SXin Li   static bool classof(const VisitorJob *VJ) {
1875*67e74705SXin Li     return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1876*67e74705SXin Li   }
get() const1877*67e74705SXin Li   const FieldDecl *get() const {
1878*67e74705SXin Li     return static_cast<const FieldDecl *>(data[0]);
1879*67e74705SXin Li   }
getLoc() const1880*67e74705SXin Li   SourceLocation getLoc() const {
1881*67e74705SXin Li     return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1882*67e74705SXin Li   }
1883*67e74705SXin Li };
1884*67e74705SXin Li class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
1885*67e74705SXin Li   friend class OMPClauseEnqueue;
1886*67e74705SXin Li   VisitorWorkList &WL;
1887*67e74705SXin Li   CXCursor Parent;
1888*67e74705SXin Li public:
EnqueueVisitor(VisitorWorkList & wl,CXCursor parent)1889*67e74705SXin Li   EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1890*67e74705SXin Li     : WL(wl), Parent(parent) {}
1891*67e74705SXin Li 
1892*67e74705SXin Li   void VisitAddrLabelExpr(const AddrLabelExpr *E);
1893*67e74705SXin Li   void VisitBlockExpr(const BlockExpr *B);
1894*67e74705SXin Li   void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1895*67e74705SXin Li   void VisitCompoundStmt(const CompoundStmt *S);
VisitCXXDefaultArgExpr(const CXXDefaultArgExpr * E)1896*67e74705SXin Li   void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1897*67e74705SXin Li   void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1898*67e74705SXin Li   void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1899*67e74705SXin Li   void VisitCXXNewExpr(const CXXNewExpr *E);
1900*67e74705SXin Li   void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1901*67e74705SXin Li   void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1902*67e74705SXin Li   void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1903*67e74705SXin Li   void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1904*67e74705SXin Li   void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1905*67e74705SXin Li   void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1906*67e74705SXin Li   void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1907*67e74705SXin Li   void VisitCXXCatchStmt(const CXXCatchStmt *S);
1908*67e74705SXin Li   void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
1909*67e74705SXin Li   void VisitDeclRefExpr(const DeclRefExpr *D);
1910*67e74705SXin Li   void VisitDeclStmt(const DeclStmt *S);
1911*67e74705SXin Li   void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1912*67e74705SXin Li   void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1913*67e74705SXin Li   void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1914*67e74705SXin Li   void VisitForStmt(const ForStmt *FS);
1915*67e74705SXin Li   void VisitGotoStmt(const GotoStmt *GS);
1916*67e74705SXin Li   void VisitIfStmt(const IfStmt *If);
1917*67e74705SXin Li   void VisitInitListExpr(const InitListExpr *IE);
1918*67e74705SXin Li   void VisitMemberExpr(const MemberExpr *M);
1919*67e74705SXin Li   void VisitOffsetOfExpr(const OffsetOfExpr *E);
1920*67e74705SXin Li   void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1921*67e74705SXin Li   void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1922*67e74705SXin Li   void VisitOverloadExpr(const OverloadExpr *E);
1923*67e74705SXin Li   void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1924*67e74705SXin Li   void VisitStmt(const Stmt *S);
1925*67e74705SXin Li   void VisitSwitchStmt(const SwitchStmt *S);
1926*67e74705SXin Li   void VisitWhileStmt(const WhileStmt *W);
1927*67e74705SXin Li   void VisitTypeTraitExpr(const TypeTraitExpr *E);
1928*67e74705SXin Li   void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1929*67e74705SXin Li   void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1930*67e74705SXin Li   void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1931*67e74705SXin Li   void VisitVAArgExpr(const VAArgExpr *E);
1932*67e74705SXin Li   void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1933*67e74705SXin Li   void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1934*67e74705SXin Li   void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1935*67e74705SXin Li   void VisitLambdaExpr(const LambdaExpr *E);
1936*67e74705SXin Li   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1937*67e74705SXin Li   void VisitOMPLoopDirective(const OMPLoopDirective *D);
1938*67e74705SXin Li   void VisitOMPParallelDirective(const OMPParallelDirective *D);
1939*67e74705SXin Li   void VisitOMPSimdDirective(const OMPSimdDirective *D);
1940*67e74705SXin Li   void VisitOMPForDirective(const OMPForDirective *D);
1941*67e74705SXin Li   void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
1942*67e74705SXin Li   void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
1943*67e74705SXin Li   void VisitOMPSectionDirective(const OMPSectionDirective *D);
1944*67e74705SXin Li   void VisitOMPSingleDirective(const OMPSingleDirective *D);
1945*67e74705SXin Li   void VisitOMPMasterDirective(const OMPMasterDirective *D);
1946*67e74705SXin Li   void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
1947*67e74705SXin Li   void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
1948*67e74705SXin Li   void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
1949*67e74705SXin Li   void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
1950*67e74705SXin Li   void VisitOMPTaskDirective(const OMPTaskDirective *D);
1951*67e74705SXin Li   void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
1952*67e74705SXin Li   void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
1953*67e74705SXin Li   void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
1954*67e74705SXin Li   void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
1955*67e74705SXin Li   void
1956*67e74705SXin Li   VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
1957*67e74705SXin Li   void VisitOMPCancelDirective(const OMPCancelDirective *D);
1958*67e74705SXin Li   void VisitOMPFlushDirective(const OMPFlushDirective *D);
1959*67e74705SXin Li   void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
1960*67e74705SXin Li   void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
1961*67e74705SXin Li   void VisitOMPTargetDirective(const OMPTargetDirective *D);
1962*67e74705SXin Li   void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
1963*67e74705SXin Li   void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
1964*67e74705SXin Li   void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
1965*67e74705SXin Li   void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
1966*67e74705SXin Li   void
1967*67e74705SXin Li   VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
1968*67e74705SXin Li   void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
1969*67e74705SXin Li   void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
1970*67e74705SXin Li   void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
1971*67e74705SXin Li   void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
1972*67e74705SXin Li   void VisitOMPDistributeParallelForDirective(
1973*67e74705SXin Li       const OMPDistributeParallelForDirective *D);
1974*67e74705SXin Li   void VisitOMPDistributeParallelForSimdDirective(
1975*67e74705SXin Li       const OMPDistributeParallelForSimdDirective *D);
1976*67e74705SXin Li   void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
1977*67e74705SXin Li   void VisitOMPTargetParallelForSimdDirective(
1978*67e74705SXin Li       const OMPTargetParallelForSimdDirective *D);
1979*67e74705SXin Li 
1980*67e74705SXin Li private:
1981*67e74705SXin Li   void AddDeclarationNameInfo(const Stmt *S);
1982*67e74705SXin Li   void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1983*67e74705SXin Li   void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
1984*67e74705SXin Li                                unsigned NumTemplateArgs);
1985*67e74705SXin Li   void AddMemberRef(const FieldDecl *D, SourceLocation L);
1986*67e74705SXin Li   void AddStmt(const Stmt *S);
1987*67e74705SXin Li   void AddDecl(const Decl *D, bool isFirst = true);
1988*67e74705SXin Li   void AddTypeLoc(TypeSourceInfo *TI);
1989*67e74705SXin Li   void EnqueueChildren(const Stmt *S);
1990*67e74705SXin Li   void EnqueueChildren(const OMPClause *S);
1991*67e74705SXin Li };
1992*67e74705SXin Li } // end anonyous namespace
1993*67e74705SXin Li 
AddDeclarationNameInfo(const Stmt * S)1994*67e74705SXin Li void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
1995*67e74705SXin Li   // 'S' should always be non-null, since it comes from the
1996*67e74705SXin Li   // statement we are visiting.
1997*67e74705SXin Li   WL.push_back(DeclarationNameInfoVisit(S, Parent));
1998*67e74705SXin Li }
1999*67e74705SXin Li 
2000*67e74705SXin Li void
AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)2001*67e74705SXin Li EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
2002*67e74705SXin Li   if (Qualifier)
2003*67e74705SXin Li     WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2004*67e74705SXin Li }
2005*67e74705SXin Li 
AddStmt(const Stmt * S)2006*67e74705SXin Li void EnqueueVisitor::AddStmt(const Stmt *S) {
2007*67e74705SXin Li   if (S)
2008*67e74705SXin Li     WL.push_back(StmtVisit(S, Parent));
2009*67e74705SXin Li }
AddDecl(const Decl * D,bool isFirst)2010*67e74705SXin Li void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
2011*67e74705SXin Li   if (D)
2012*67e74705SXin Li     WL.push_back(DeclVisit(D, Parent, isFirst));
2013*67e74705SXin Li }
AddExplicitTemplateArgs(const TemplateArgumentLoc * A,unsigned NumTemplateArgs)2014*67e74705SXin Li void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2015*67e74705SXin Li                                              unsigned NumTemplateArgs) {
2016*67e74705SXin Li   WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
2017*67e74705SXin Li }
AddMemberRef(const FieldDecl * D,SourceLocation L)2018*67e74705SXin Li void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
2019*67e74705SXin Li   if (D)
2020*67e74705SXin Li     WL.push_back(MemberRefVisit(D, L, Parent));
2021*67e74705SXin Li }
AddTypeLoc(TypeSourceInfo * TI)2022*67e74705SXin Li void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2023*67e74705SXin Li   if (TI)
2024*67e74705SXin Li     WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2025*67e74705SXin Li  }
EnqueueChildren(const Stmt * S)2026*67e74705SXin Li void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
2027*67e74705SXin Li   unsigned size = WL.size();
2028*67e74705SXin Li   for (const Stmt *SubStmt : S->children()) {
2029*67e74705SXin Li     AddStmt(SubStmt);
2030*67e74705SXin Li   }
2031*67e74705SXin Li   if (size == WL.size())
2032*67e74705SXin Li     return;
2033*67e74705SXin Li   // Now reverse the entries we just added.  This will match the DFS
2034*67e74705SXin Li   // ordering performed by the worklist.
2035*67e74705SXin Li   VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2036*67e74705SXin Li   std::reverse(I, E);
2037*67e74705SXin Li }
2038*67e74705SXin Li namespace {
2039*67e74705SXin Li class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2040*67e74705SXin Li   EnqueueVisitor *Visitor;
2041*67e74705SXin Li   /// \brief Process clauses with list of variables.
2042*67e74705SXin Li   template <typename T>
2043*67e74705SXin Li   void VisitOMPClauseList(T *Node);
2044*67e74705SXin Li public:
OMPClauseEnqueue(EnqueueVisitor * Visitor)2045*67e74705SXin Li   OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2046*67e74705SXin Li #define OPENMP_CLAUSE(Name, Class)                                             \
2047*67e74705SXin Li   void Visit##Class(const Class *C);
2048*67e74705SXin Li #include "clang/Basic/OpenMPKinds.def"
2049*67e74705SXin Li   void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
2050*67e74705SXin Li   void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
2051*67e74705SXin Li };
2052*67e74705SXin Li 
VisitOMPClauseWithPreInit(const OMPClauseWithPreInit * C)2053*67e74705SXin Li void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2054*67e74705SXin Li     const OMPClauseWithPreInit *C) {
2055*67e74705SXin Li   Visitor->AddStmt(C->getPreInitStmt());
2056*67e74705SXin Li }
2057*67e74705SXin Li 
VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate * C)2058*67e74705SXin Li void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2059*67e74705SXin Li     const OMPClauseWithPostUpdate *C) {
2060*67e74705SXin Li   VisitOMPClauseWithPreInit(C);
2061*67e74705SXin Li   Visitor->AddStmt(C->getPostUpdateExpr());
2062*67e74705SXin Li }
2063*67e74705SXin Li 
VisitOMPIfClause(const OMPIfClause * C)2064*67e74705SXin Li void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2065*67e74705SXin Li   Visitor->AddStmt(C->getCondition());
2066*67e74705SXin Li }
2067*67e74705SXin Li 
VisitOMPFinalClause(const OMPFinalClause * C)2068*67e74705SXin Li void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2069*67e74705SXin Li   Visitor->AddStmt(C->getCondition());
2070*67e74705SXin Li }
2071*67e74705SXin Li 
VisitOMPNumThreadsClause(const OMPNumThreadsClause * C)2072*67e74705SXin Li void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2073*67e74705SXin Li   Visitor->AddStmt(C->getNumThreads());
2074*67e74705SXin Li }
2075*67e74705SXin Li 
VisitOMPSafelenClause(const OMPSafelenClause * C)2076*67e74705SXin Li void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2077*67e74705SXin Li   Visitor->AddStmt(C->getSafelen());
2078*67e74705SXin Li }
2079*67e74705SXin Li 
VisitOMPSimdlenClause(const OMPSimdlenClause * C)2080*67e74705SXin Li void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2081*67e74705SXin Li   Visitor->AddStmt(C->getSimdlen());
2082*67e74705SXin Li }
2083*67e74705SXin Li 
VisitOMPCollapseClause(const OMPCollapseClause * C)2084*67e74705SXin Li void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2085*67e74705SXin Li   Visitor->AddStmt(C->getNumForLoops());
2086*67e74705SXin Li }
2087*67e74705SXin Li 
VisitOMPDefaultClause(const OMPDefaultClause * C)2088*67e74705SXin Li void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
2089*67e74705SXin Li 
VisitOMPProcBindClause(const OMPProcBindClause * C)2090*67e74705SXin Li void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2091*67e74705SXin Li 
VisitOMPScheduleClause(const OMPScheduleClause * C)2092*67e74705SXin Li void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2093*67e74705SXin Li   VisitOMPClauseWithPreInit(C);
2094*67e74705SXin Li   Visitor->AddStmt(C->getChunkSize());
2095*67e74705SXin Li }
2096*67e74705SXin Li 
VisitOMPOrderedClause(const OMPOrderedClause * C)2097*67e74705SXin Li void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2098*67e74705SXin Li   Visitor->AddStmt(C->getNumForLoops());
2099*67e74705SXin Li }
2100*67e74705SXin Li 
VisitOMPNowaitClause(const OMPNowaitClause *)2101*67e74705SXin Li void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2102*67e74705SXin Li 
VisitOMPUntiedClause(const OMPUntiedClause *)2103*67e74705SXin Li void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2104*67e74705SXin Li 
VisitOMPMergeableClause(const OMPMergeableClause *)2105*67e74705SXin Li void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2106*67e74705SXin Li 
VisitOMPReadClause(const OMPReadClause *)2107*67e74705SXin Li void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2108*67e74705SXin Li 
VisitOMPWriteClause(const OMPWriteClause *)2109*67e74705SXin Li void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2110*67e74705SXin Li 
VisitOMPUpdateClause(const OMPUpdateClause *)2111*67e74705SXin Li void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2112*67e74705SXin Li 
VisitOMPCaptureClause(const OMPCaptureClause *)2113*67e74705SXin Li void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2114*67e74705SXin Li 
VisitOMPSeqCstClause(const OMPSeqCstClause *)2115*67e74705SXin Li void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2116*67e74705SXin Li 
VisitOMPThreadsClause(const OMPThreadsClause *)2117*67e74705SXin Li void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2118*67e74705SXin Li 
VisitOMPSIMDClause(const OMPSIMDClause *)2119*67e74705SXin Li void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2120*67e74705SXin Li 
VisitOMPNogroupClause(const OMPNogroupClause *)2121*67e74705SXin Li void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2122*67e74705SXin Li 
VisitOMPDeviceClause(const OMPDeviceClause * C)2123*67e74705SXin Li void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2124*67e74705SXin Li   Visitor->AddStmt(C->getDevice());
2125*67e74705SXin Li }
2126*67e74705SXin Li 
VisitOMPNumTeamsClause(const OMPNumTeamsClause * C)2127*67e74705SXin Li void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2128*67e74705SXin Li   Visitor->AddStmt(C->getNumTeams());
2129*67e74705SXin Li }
2130*67e74705SXin Li 
VisitOMPThreadLimitClause(const OMPThreadLimitClause * C)2131*67e74705SXin Li void OMPClauseEnqueue::VisitOMPThreadLimitClause(const OMPThreadLimitClause *C) {
2132*67e74705SXin Li   Visitor->AddStmt(C->getThreadLimit());
2133*67e74705SXin Li }
2134*67e74705SXin Li 
VisitOMPPriorityClause(const OMPPriorityClause * C)2135*67e74705SXin Li void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2136*67e74705SXin Li   Visitor->AddStmt(C->getPriority());
2137*67e74705SXin Li }
2138*67e74705SXin Li 
VisitOMPGrainsizeClause(const OMPGrainsizeClause * C)2139*67e74705SXin Li void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2140*67e74705SXin Li   Visitor->AddStmt(C->getGrainsize());
2141*67e74705SXin Li }
2142*67e74705SXin Li 
VisitOMPNumTasksClause(const OMPNumTasksClause * C)2143*67e74705SXin Li void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2144*67e74705SXin Li   Visitor->AddStmt(C->getNumTasks());
2145*67e74705SXin Li }
2146*67e74705SXin Li 
VisitOMPHintClause(const OMPHintClause * C)2147*67e74705SXin Li void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2148*67e74705SXin Li   Visitor->AddStmt(C->getHint());
2149*67e74705SXin Li }
2150*67e74705SXin Li 
2151*67e74705SXin Li template<typename T>
VisitOMPClauseList(T * Node)2152*67e74705SXin Li void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
2153*67e74705SXin Li   for (const auto *I : Node->varlists()) {
2154*67e74705SXin Li     Visitor->AddStmt(I);
2155*67e74705SXin Li   }
2156*67e74705SXin Li }
2157*67e74705SXin Li 
VisitOMPPrivateClause(const OMPPrivateClause * C)2158*67e74705SXin Li void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
2159*67e74705SXin Li   VisitOMPClauseList(C);
2160*67e74705SXin Li   for (const auto *E : C->private_copies()) {
2161*67e74705SXin Li     Visitor->AddStmt(E);
2162*67e74705SXin Li   }
2163*67e74705SXin Li }
VisitOMPFirstprivateClause(const OMPFirstprivateClause * C)2164*67e74705SXin Li void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2165*67e74705SXin Li                                         const OMPFirstprivateClause *C) {
2166*67e74705SXin Li   VisitOMPClauseList(C);
2167*67e74705SXin Li   VisitOMPClauseWithPreInit(C);
2168*67e74705SXin Li   for (const auto *E : C->private_copies()) {
2169*67e74705SXin Li     Visitor->AddStmt(E);
2170*67e74705SXin Li   }
2171*67e74705SXin Li   for (const auto *E : C->inits()) {
2172*67e74705SXin Li     Visitor->AddStmt(E);
2173*67e74705SXin Li   }
2174*67e74705SXin Li }
VisitOMPLastprivateClause(const OMPLastprivateClause * C)2175*67e74705SXin Li void OMPClauseEnqueue::VisitOMPLastprivateClause(
2176*67e74705SXin Li                                         const OMPLastprivateClause *C) {
2177*67e74705SXin Li   VisitOMPClauseList(C);
2178*67e74705SXin Li   VisitOMPClauseWithPostUpdate(C);
2179*67e74705SXin Li   for (auto *E : C->private_copies()) {
2180*67e74705SXin Li     Visitor->AddStmt(E);
2181*67e74705SXin Li   }
2182*67e74705SXin Li   for (auto *E : C->source_exprs()) {
2183*67e74705SXin Li     Visitor->AddStmt(E);
2184*67e74705SXin Li   }
2185*67e74705SXin Li   for (auto *E : C->destination_exprs()) {
2186*67e74705SXin Li     Visitor->AddStmt(E);
2187*67e74705SXin Li   }
2188*67e74705SXin Li   for (auto *E : C->assignment_ops()) {
2189*67e74705SXin Li     Visitor->AddStmt(E);
2190*67e74705SXin Li   }
2191*67e74705SXin Li }
VisitOMPSharedClause(const OMPSharedClause * C)2192*67e74705SXin Li void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
2193*67e74705SXin Li   VisitOMPClauseList(C);
2194*67e74705SXin Li }
VisitOMPReductionClause(const OMPReductionClause * C)2195*67e74705SXin Li void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2196*67e74705SXin Li   VisitOMPClauseList(C);
2197*67e74705SXin Li   VisitOMPClauseWithPostUpdate(C);
2198*67e74705SXin Li   for (auto *E : C->privates()) {
2199*67e74705SXin Li     Visitor->AddStmt(E);
2200*67e74705SXin Li   }
2201*67e74705SXin Li   for (auto *E : C->lhs_exprs()) {
2202*67e74705SXin Li     Visitor->AddStmt(E);
2203*67e74705SXin Li   }
2204*67e74705SXin Li   for (auto *E : C->rhs_exprs()) {
2205*67e74705SXin Li     Visitor->AddStmt(E);
2206*67e74705SXin Li   }
2207*67e74705SXin Li   for (auto *E : C->reduction_ops()) {
2208*67e74705SXin Li     Visitor->AddStmt(E);
2209*67e74705SXin Li   }
2210*67e74705SXin Li }
VisitOMPLinearClause(const OMPLinearClause * C)2211*67e74705SXin Li void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2212*67e74705SXin Li   VisitOMPClauseList(C);
2213*67e74705SXin Li   VisitOMPClauseWithPostUpdate(C);
2214*67e74705SXin Li   for (const auto *E : C->privates()) {
2215*67e74705SXin Li     Visitor->AddStmt(E);
2216*67e74705SXin Li   }
2217*67e74705SXin Li   for (const auto *E : C->inits()) {
2218*67e74705SXin Li     Visitor->AddStmt(E);
2219*67e74705SXin Li   }
2220*67e74705SXin Li   for (const auto *E : C->updates()) {
2221*67e74705SXin Li     Visitor->AddStmt(E);
2222*67e74705SXin Li   }
2223*67e74705SXin Li   for (const auto *E : C->finals()) {
2224*67e74705SXin Li     Visitor->AddStmt(E);
2225*67e74705SXin Li   }
2226*67e74705SXin Li   Visitor->AddStmt(C->getStep());
2227*67e74705SXin Li   Visitor->AddStmt(C->getCalcStep());
2228*67e74705SXin Li }
VisitOMPAlignedClause(const OMPAlignedClause * C)2229*67e74705SXin Li void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2230*67e74705SXin Li   VisitOMPClauseList(C);
2231*67e74705SXin Li   Visitor->AddStmt(C->getAlignment());
2232*67e74705SXin Li }
VisitOMPCopyinClause(const OMPCopyinClause * C)2233*67e74705SXin Li void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2234*67e74705SXin Li   VisitOMPClauseList(C);
2235*67e74705SXin Li   for (auto *E : C->source_exprs()) {
2236*67e74705SXin Li     Visitor->AddStmt(E);
2237*67e74705SXin Li   }
2238*67e74705SXin Li   for (auto *E : C->destination_exprs()) {
2239*67e74705SXin Li     Visitor->AddStmt(E);
2240*67e74705SXin Li   }
2241*67e74705SXin Li   for (auto *E : C->assignment_ops()) {
2242*67e74705SXin Li     Visitor->AddStmt(E);
2243*67e74705SXin Li   }
2244*67e74705SXin Li }
2245*67e74705SXin Li void
VisitOMPCopyprivateClause(const OMPCopyprivateClause * C)2246*67e74705SXin Li OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2247*67e74705SXin Li   VisitOMPClauseList(C);
2248*67e74705SXin Li   for (auto *E : C->source_exprs()) {
2249*67e74705SXin Li     Visitor->AddStmt(E);
2250*67e74705SXin Li   }
2251*67e74705SXin Li   for (auto *E : C->destination_exprs()) {
2252*67e74705SXin Li     Visitor->AddStmt(E);
2253*67e74705SXin Li   }
2254*67e74705SXin Li   for (auto *E : C->assignment_ops()) {
2255*67e74705SXin Li     Visitor->AddStmt(E);
2256*67e74705SXin Li   }
2257*67e74705SXin Li }
VisitOMPFlushClause(const OMPFlushClause * C)2258*67e74705SXin Li void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2259*67e74705SXin Li   VisitOMPClauseList(C);
2260*67e74705SXin Li }
VisitOMPDependClause(const OMPDependClause * C)2261*67e74705SXin Li void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2262*67e74705SXin Li   VisitOMPClauseList(C);
2263*67e74705SXin Li }
VisitOMPMapClause(const OMPMapClause * C)2264*67e74705SXin Li void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2265*67e74705SXin Li   VisitOMPClauseList(C);
2266*67e74705SXin Li }
VisitOMPDistScheduleClause(const OMPDistScheduleClause * C)2267*67e74705SXin Li void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2268*67e74705SXin Li     const OMPDistScheduleClause *C) {
2269*67e74705SXin Li   VisitOMPClauseWithPreInit(C);
2270*67e74705SXin Li   Visitor->AddStmt(C->getChunkSize());
2271*67e74705SXin Li }
VisitOMPDefaultmapClause(const OMPDefaultmapClause *)2272*67e74705SXin Li void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2273*67e74705SXin Li     const OMPDefaultmapClause * /*C*/) {}
VisitOMPToClause(const OMPToClause * C)2274*67e74705SXin Li void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2275*67e74705SXin Li   VisitOMPClauseList(C);
2276*67e74705SXin Li }
VisitOMPFromClause(const OMPFromClause * C)2277*67e74705SXin Li void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2278*67e74705SXin Li   VisitOMPClauseList(C);
2279*67e74705SXin Li }
VisitOMPUseDevicePtrClause(const OMPUseDevicePtrClause * C)2280*67e74705SXin Li void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(const OMPUseDevicePtrClause *C) {
2281*67e74705SXin Li   VisitOMPClauseList(C);
2282*67e74705SXin Li }
VisitOMPIsDevicePtrClause(const OMPIsDevicePtrClause * C)2283*67e74705SXin Li void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(const OMPIsDevicePtrClause *C) {
2284*67e74705SXin Li   VisitOMPClauseList(C);
2285*67e74705SXin Li }
2286*67e74705SXin Li }
2287*67e74705SXin Li 
EnqueueChildren(const OMPClause * S)2288*67e74705SXin Li void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2289*67e74705SXin Li   unsigned size = WL.size();
2290*67e74705SXin Li   OMPClauseEnqueue Visitor(this);
2291*67e74705SXin Li   Visitor.Visit(S);
2292*67e74705SXin Li   if (size == WL.size())
2293*67e74705SXin Li     return;
2294*67e74705SXin Li   // Now reverse the entries we just added.  This will match the DFS
2295*67e74705SXin Li   // ordering performed by the worklist.
2296*67e74705SXin Li   VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2297*67e74705SXin Li   std::reverse(I, E);
2298*67e74705SXin Li }
VisitAddrLabelExpr(const AddrLabelExpr * E)2299*67e74705SXin Li void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
2300*67e74705SXin Li   WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2301*67e74705SXin Li }
VisitBlockExpr(const BlockExpr * B)2302*67e74705SXin Li void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
2303*67e74705SXin Li   AddDecl(B->getBlockDecl());
2304*67e74705SXin Li }
VisitCompoundLiteralExpr(const CompoundLiteralExpr * E)2305*67e74705SXin Li void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
2306*67e74705SXin Li   EnqueueChildren(E);
2307*67e74705SXin Li   AddTypeLoc(E->getTypeSourceInfo());
2308*67e74705SXin Li }
VisitCompoundStmt(const CompoundStmt * S)2309*67e74705SXin Li void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2310*67e74705SXin Li   for (auto &I : llvm::reverse(S->body()))
2311*67e74705SXin Li     AddStmt(I);
2312*67e74705SXin Li }
2313*67e74705SXin Li void EnqueueVisitor::
VisitMSDependentExistsStmt(const MSDependentExistsStmt * S)2314*67e74705SXin Li VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
2315*67e74705SXin Li   AddStmt(S->getSubStmt());
2316*67e74705SXin Li   AddDeclarationNameInfo(S);
2317*67e74705SXin Li   if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2318*67e74705SXin Li     AddNestedNameSpecifierLoc(QualifierLoc);
2319*67e74705SXin Li }
2320*67e74705SXin Li 
2321*67e74705SXin Li void EnqueueVisitor::
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr * E)2322*67e74705SXin Li VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
2323*67e74705SXin Li   if (E->hasExplicitTemplateArgs())
2324*67e74705SXin Li     AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2325*67e74705SXin Li   AddDeclarationNameInfo(E);
2326*67e74705SXin Li   if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2327*67e74705SXin Li     AddNestedNameSpecifierLoc(QualifierLoc);
2328*67e74705SXin Li   if (!E->isImplicitAccess())
2329*67e74705SXin Li     AddStmt(E->getBase());
2330*67e74705SXin Li }
VisitCXXNewExpr(const CXXNewExpr * E)2331*67e74705SXin Li void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
2332*67e74705SXin Li   // Enqueue the initializer , if any.
2333*67e74705SXin Li   AddStmt(E->getInitializer());
2334*67e74705SXin Li   // Enqueue the array size, if any.
2335*67e74705SXin Li   AddStmt(E->getArraySize());
2336*67e74705SXin Li   // Enqueue the allocated type.
2337*67e74705SXin Li   AddTypeLoc(E->getAllocatedTypeSourceInfo());
2338*67e74705SXin Li   // Enqueue the placement arguments.
2339*67e74705SXin Li   for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2340*67e74705SXin Li     AddStmt(E->getPlacementArg(I-1));
2341*67e74705SXin Li }
VisitCXXOperatorCallExpr(const CXXOperatorCallExpr * CE)2342*67e74705SXin Li void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
2343*67e74705SXin Li   for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2344*67e74705SXin Li     AddStmt(CE->getArg(I-1));
2345*67e74705SXin Li   AddStmt(CE->getCallee());
2346*67e74705SXin Li   AddStmt(CE->getArg(0));
2347*67e74705SXin Li }
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)2348*67e74705SXin Li void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2349*67e74705SXin Li                                         const CXXPseudoDestructorExpr *E) {
2350*67e74705SXin Li   // Visit the name of the type being destroyed.
2351*67e74705SXin Li   AddTypeLoc(E->getDestroyedTypeInfo());
2352*67e74705SXin Li   // Visit the scope type that looks disturbingly like the nested-name-specifier
2353*67e74705SXin Li   // but isn't.
2354*67e74705SXin Li   AddTypeLoc(E->getScopeTypeInfo());
2355*67e74705SXin Li   // Visit the nested-name-specifier.
2356*67e74705SXin Li   if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2357*67e74705SXin Li     AddNestedNameSpecifierLoc(QualifierLoc);
2358*67e74705SXin Li   // Visit base expression.
2359*67e74705SXin Li   AddStmt(E->getBase());
2360*67e74705SXin Li }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)2361*67e74705SXin Li void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2362*67e74705SXin Li                                         const CXXScalarValueInitExpr *E) {
2363*67e74705SXin Li   AddTypeLoc(E->getTypeSourceInfo());
2364*67e74705SXin Li }
VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr * E)2365*67e74705SXin Li void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2366*67e74705SXin Li                                         const CXXTemporaryObjectExpr *E) {
2367*67e74705SXin Li   EnqueueChildren(E);
2368*67e74705SXin Li   AddTypeLoc(E->getTypeSourceInfo());
2369*67e74705SXin Li }
VisitCXXTypeidExpr(const CXXTypeidExpr * E)2370*67e74705SXin Li void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
2371*67e74705SXin Li   EnqueueChildren(E);
2372*67e74705SXin Li   if (E->isTypeOperand())
2373*67e74705SXin Li     AddTypeLoc(E->getTypeOperandSourceInfo());
2374*67e74705SXin Li }
2375*67e74705SXin Li 
VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr * E)2376*67e74705SXin Li void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2377*67e74705SXin Li                                         const CXXUnresolvedConstructExpr *E) {
2378*67e74705SXin Li   EnqueueChildren(E);
2379*67e74705SXin Li   AddTypeLoc(E->getTypeSourceInfo());
2380*67e74705SXin Li }
VisitCXXUuidofExpr(const CXXUuidofExpr * E)2381*67e74705SXin Li void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
2382*67e74705SXin Li   EnqueueChildren(E);
2383*67e74705SXin Li   if (E->isTypeOperand())
2384*67e74705SXin Li     AddTypeLoc(E->getTypeOperandSourceInfo());
2385*67e74705SXin Li }
2386*67e74705SXin Li 
VisitCXXCatchStmt(const CXXCatchStmt * S)2387*67e74705SXin Li void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
2388*67e74705SXin Li   EnqueueChildren(S);
2389*67e74705SXin Li   AddDecl(S->getExceptionDecl());
2390*67e74705SXin Li }
2391*67e74705SXin Li 
VisitCXXForRangeStmt(const CXXForRangeStmt * S)2392*67e74705SXin Li void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
2393*67e74705SXin Li   AddStmt(S->getBody());
2394*67e74705SXin Li   AddStmt(S->getRangeInit());
2395*67e74705SXin Li   AddDecl(S->getLoopVariable());
2396*67e74705SXin Li }
2397*67e74705SXin Li 
VisitDeclRefExpr(const DeclRefExpr * DR)2398*67e74705SXin Li void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
2399*67e74705SXin Li   if (DR->hasExplicitTemplateArgs())
2400*67e74705SXin Li     AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
2401*67e74705SXin Li   WL.push_back(DeclRefExprParts(DR, Parent));
2402*67e74705SXin Li }
VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr * E)2403*67e74705SXin Li void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2404*67e74705SXin Li                                         const DependentScopeDeclRefExpr *E) {
2405*67e74705SXin Li   if (E->hasExplicitTemplateArgs())
2406*67e74705SXin Li     AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2407*67e74705SXin Li   AddDeclarationNameInfo(E);
2408*67e74705SXin Li   AddNestedNameSpecifierLoc(E->getQualifierLoc());
2409*67e74705SXin Li }
VisitDeclStmt(const DeclStmt * S)2410*67e74705SXin Li void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
2411*67e74705SXin Li   unsigned size = WL.size();
2412*67e74705SXin Li   bool isFirst = true;
2413*67e74705SXin Li   for (const auto *D : S->decls()) {
2414*67e74705SXin Li     AddDecl(D, isFirst);
2415*67e74705SXin Li     isFirst = false;
2416*67e74705SXin Li   }
2417*67e74705SXin Li   if (size == WL.size())
2418*67e74705SXin Li     return;
2419*67e74705SXin Li   // Now reverse the entries we just added.  This will match the DFS
2420*67e74705SXin Li   // ordering performed by the worklist.
2421*67e74705SXin Li   VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2422*67e74705SXin Li   std::reverse(I, E);
2423*67e74705SXin Li }
VisitDesignatedInitExpr(const DesignatedInitExpr * E)2424*67e74705SXin Li void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
2425*67e74705SXin Li   AddStmt(E->getInit());
2426*67e74705SXin Li   for (const DesignatedInitExpr::Designator &D :
2427*67e74705SXin Li        llvm::reverse(E->designators())) {
2428*67e74705SXin Li     if (D.isFieldDesignator()) {
2429*67e74705SXin Li       if (FieldDecl *Field = D.getField())
2430*67e74705SXin Li         AddMemberRef(Field, D.getFieldLoc());
2431*67e74705SXin Li       continue;
2432*67e74705SXin Li     }
2433*67e74705SXin Li     if (D.isArrayDesignator()) {
2434*67e74705SXin Li       AddStmt(E->getArrayIndex(D));
2435*67e74705SXin Li       continue;
2436*67e74705SXin Li     }
2437*67e74705SXin Li     assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2438*67e74705SXin Li     AddStmt(E->getArrayRangeEnd(D));
2439*67e74705SXin Li     AddStmt(E->getArrayRangeStart(D));
2440*67e74705SXin Li   }
2441*67e74705SXin Li }
VisitExplicitCastExpr(const ExplicitCastExpr * E)2442*67e74705SXin Li void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
2443*67e74705SXin Li   EnqueueChildren(E);
2444*67e74705SXin Li   AddTypeLoc(E->getTypeInfoAsWritten());
2445*67e74705SXin Li }
VisitForStmt(const ForStmt * FS)2446*67e74705SXin Li void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
2447*67e74705SXin Li   AddStmt(FS->getBody());
2448*67e74705SXin Li   AddStmt(FS->getInc());
2449*67e74705SXin Li   AddStmt(FS->getCond());
2450*67e74705SXin Li   AddDecl(FS->getConditionVariable());
2451*67e74705SXin Li   AddStmt(FS->getInit());
2452*67e74705SXin Li }
VisitGotoStmt(const GotoStmt * GS)2453*67e74705SXin Li void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
2454*67e74705SXin Li   WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2455*67e74705SXin Li }
VisitIfStmt(const IfStmt * If)2456*67e74705SXin Li void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
2457*67e74705SXin Li   AddStmt(If->getElse());
2458*67e74705SXin Li   AddStmt(If->getThen());
2459*67e74705SXin Li   AddStmt(If->getCond());
2460*67e74705SXin Li   AddDecl(If->getConditionVariable());
2461*67e74705SXin Li }
VisitInitListExpr(const InitListExpr * IE)2462*67e74705SXin Li void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
2463*67e74705SXin Li   // We care about the syntactic form of the initializer list, only.
2464*67e74705SXin Li   if (InitListExpr *Syntactic = IE->getSyntacticForm())
2465*67e74705SXin Li     IE = Syntactic;
2466*67e74705SXin Li   EnqueueChildren(IE);
2467*67e74705SXin Li }
VisitMemberExpr(const MemberExpr * M)2468*67e74705SXin Li void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
2469*67e74705SXin Li   WL.push_back(MemberExprParts(M, Parent));
2470*67e74705SXin Li 
2471*67e74705SXin Li   // If the base of the member access expression is an implicit 'this', don't
2472*67e74705SXin Li   // visit it.
2473*67e74705SXin Li   // FIXME: If we ever want to show these implicit accesses, this will be
2474*67e74705SXin Li   // unfortunate. However, clang_getCursor() relies on this behavior.
2475*67e74705SXin Li   if (M->isImplicitAccess())
2476*67e74705SXin Li     return;
2477*67e74705SXin Li 
2478*67e74705SXin Li   // Ignore base anonymous struct/union fields, otherwise they will shadow the
2479*67e74705SXin Li   // real field that that we are interested in.
2480*67e74705SXin Li   if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2481*67e74705SXin Li     if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2482*67e74705SXin Li       if (FD->isAnonymousStructOrUnion()) {
2483*67e74705SXin Li         AddStmt(SubME->getBase());
2484*67e74705SXin Li         return;
2485*67e74705SXin Li       }
2486*67e74705SXin Li     }
2487*67e74705SXin Li   }
2488*67e74705SXin Li 
2489*67e74705SXin Li   AddStmt(M->getBase());
2490*67e74705SXin Li }
VisitObjCEncodeExpr(const ObjCEncodeExpr * E)2491*67e74705SXin Li void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
2492*67e74705SXin Li   AddTypeLoc(E->getEncodedTypeSourceInfo());
2493*67e74705SXin Li }
VisitObjCMessageExpr(const ObjCMessageExpr * M)2494*67e74705SXin Li void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
2495*67e74705SXin Li   EnqueueChildren(M);
2496*67e74705SXin Li   AddTypeLoc(M->getClassReceiverTypeInfo());
2497*67e74705SXin Li }
VisitOffsetOfExpr(const OffsetOfExpr * E)2498*67e74705SXin Li void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
2499*67e74705SXin Li   // Visit the components of the offsetof expression.
2500*67e74705SXin Li   for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2501*67e74705SXin Li     const OffsetOfNode &Node = E->getComponent(I-1);
2502*67e74705SXin Li     switch (Node.getKind()) {
2503*67e74705SXin Li     case OffsetOfNode::Array:
2504*67e74705SXin Li       AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2505*67e74705SXin Li       break;
2506*67e74705SXin Li     case OffsetOfNode::Field:
2507*67e74705SXin Li       AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2508*67e74705SXin Li       break;
2509*67e74705SXin Li     case OffsetOfNode::Identifier:
2510*67e74705SXin Li     case OffsetOfNode::Base:
2511*67e74705SXin Li       continue;
2512*67e74705SXin Li     }
2513*67e74705SXin Li   }
2514*67e74705SXin Li   // Visit the type into which we're computing the offset.
2515*67e74705SXin Li   AddTypeLoc(E->getTypeSourceInfo());
2516*67e74705SXin Li }
VisitOverloadExpr(const OverloadExpr * E)2517*67e74705SXin Li void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
2518*67e74705SXin Li   if (E->hasExplicitTemplateArgs())
2519*67e74705SXin Li     AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2520*67e74705SXin Li   WL.push_back(OverloadExprParts(E, Parent));
2521*67e74705SXin Li }
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)2522*67e74705SXin Li void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2523*67e74705SXin Li                                         const UnaryExprOrTypeTraitExpr *E) {
2524*67e74705SXin Li   EnqueueChildren(E);
2525*67e74705SXin Li   if (E->isArgumentType())
2526*67e74705SXin Li     AddTypeLoc(E->getArgumentTypeInfo());
2527*67e74705SXin Li }
VisitStmt(const Stmt * S)2528*67e74705SXin Li void EnqueueVisitor::VisitStmt(const Stmt *S) {
2529*67e74705SXin Li   EnqueueChildren(S);
2530*67e74705SXin Li }
VisitSwitchStmt(const SwitchStmt * S)2531*67e74705SXin Li void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
2532*67e74705SXin Li   AddStmt(S->getBody());
2533*67e74705SXin Li   AddStmt(S->getCond());
2534*67e74705SXin Li   AddDecl(S->getConditionVariable());
2535*67e74705SXin Li }
2536*67e74705SXin Li 
VisitWhileStmt(const WhileStmt * W)2537*67e74705SXin Li void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
2538*67e74705SXin Li   AddStmt(W->getBody());
2539*67e74705SXin Li   AddStmt(W->getCond());
2540*67e74705SXin Li   AddDecl(W->getConditionVariable());
2541*67e74705SXin Li }
2542*67e74705SXin Li 
VisitTypeTraitExpr(const TypeTraitExpr * E)2543*67e74705SXin Li void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
2544*67e74705SXin Li   for (unsigned I = E->getNumArgs(); I > 0; --I)
2545*67e74705SXin Li     AddTypeLoc(E->getArg(I-1));
2546*67e74705SXin Li }
2547*67e74705SXin Li 
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)2548*67e74705SXin Li void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
2549*67e74705SXin Li   AddTypeLoc(E->getQueriedTypeSourceInfo());
2550*67e74705SXin Li }
2551*67e74705SXin Li 
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)2552*67e74705SXin Li void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
2553*67e74705SXin Li   EnqueueChildren(E);
2554*67e74705SXin Li }
2555*67e74705SXin Li 
VisitUnresolvedMemberExpr(const UnresolvedMemberExpr * U)2556*67e74705SXin Li void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
2557*67e74705SXin Li   VisitOverloadExpr(U);
2558*67e74705SXin Li   if (!U->isImplicitAccess())
2559*67e74705SXin Li     AddStmt(U->getBase());
2560*67e74705SXin Li }
VisitVAArgExpr(const VAArgExpr * E)2561*67e74705SXin Li void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
2562*67e74705SXin Li   AddStmt(E->getSubExpr());
2563*67e74705SXin Li   AddTypeLoc(E->getWrittenTypeInfo());
2564*67e74705SXin Li }
VisitSizeOfPackExpr(const SizeOfPackExpr * E)2565*67e74705SXin Li void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
2566*67e74705SXin Li   WL.push_back(SizeOfPackExprParts(E, Parent));
2567*67e74705SXin Li }
VisitOpaqueValueExpr(const OpaqueValueExpr * E)2568*67e74705SXin Li void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2569*67e74705SXin Li   // If the opaque value has a source expression, just transparently
2570*67e74705SXin Li   // visit that.  This is useful for (e.g.) pseudo-object expressions.
2571*67e74705SXin Li   if (Expr *SourceExpr = E->getSourceExpr())
2572*67e74705SXin Li     return Visit(SourceExpr);
2573*67e74705SXin Li }
VisitLambdaExpr(const LambdaExpr * E)2574*67e74705SXin Li void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
2575*67e74705SXin Li   AddStmt(E->getBody());
2576*67e74705SXin Li   WL.push_back(LambdaExprParts(E, Parent));
2577*67e74705SXin Li }
VisitPseudoObjectExpr(const PseudoObjectExpr * E)2578*67e74705SXin Li void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
2579*67e74705SXin Li   // Treat the expression like its syntactic form.
2580*67e74705SXin Li   Visit(E->getSyntacticForm());
2581*67e74705SXin Li }
2582*67e74705SXin Li 
VisitOMPExecutableDirective(const OMPExecutableDirective * D)2583*67e74705SXin Li void EnqueueVisitor::VisitOMPExecutableDirective(
2584*67e74705SXin Li   const OMPExecutableDirective *D) {
2585*67e74705SXin Li   EnqueueChildren(D);
2586*67e74705SXin Li   for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2587*67e74705SXin Li                                        E = D->clauses().end();
2588*67e74705SXin Li        I != E; ++I)
2589*67e74705SXin Li     EnqueueChildren(*I);
2590*67e74705SXin Li }
2591*67e74705SXin Li 
VisitOMPLoopDirective(const OMPLoopDirective * D)2592*67e74705SXin Li void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2593*67e74705SXin Li   VisitOMPExecutableDirective(D);
2594*67e74705SXin Li }
2595*67e74705SXin Li 
VisitOMPParallelDirective(const OMPParallelDirective * D)2596*67e74705SXin Li void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2597*67e74705SXin Li   VisitOMPExecutableDirective(D);
2598*67e74705SXin Li }
2599*67e74705SXin Li 
VisitOMPSimdDirective(const OMPSimdDirective * D)2600*67e74705SXin Li void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2601*67e74705SXin Li   VisitOMPLoopDirective(D);
2602*67e74705SXin Li }
2603*67e74705SXin Li 
VisitOMPForDirective(const OMPForDirective * D)2604*67e74705SXin Li void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
2605*67e74705SXin Li   VisitOMPLoopDirective(D);
2606*67e74705SXin Li }
2607*67e74705SXin Li 
VisitOMPForSimdDirective(const OMPForSimdDirective * D)2608*67e74705SXin Li void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2609*67e74705SXin Li   VisitOMPLoopDirective(D);
2610*67e74705SXin Li }
2611*67e74705SXin Li 
VisitOMPSectionsDirective(const OMPSectionsDirective * D)2612*67e74705SXin Li void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2613*67e74705SXin Li   VisitOMPExecutableDirective(D);
2614*67e74705SXin Li }
2615*67e74705SXin Li 
VisitOMPSectionDirective(const OMPSectionDirective * D)2616*67e74705SXin Li void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2617*67e74705SXin Li   VisitOMPExecutableDirective(D);
2618*67e74705SXin Li }
2619*67e74705SXin Li 
VisitOMPSingleDirective(const OMPSingleDirective * D)2620*67e74705SXin Li void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2621*67e74705SXin Li   VisitOMPExecutableDirective(D);
2622*67e74705SXin Li }
2623*67e74705SXin Li 
VisitOMPMasterDirective(const OMPMasterDirective * D)2624*67e74705SXin Li void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2625*67e74705SXin Li   VisitOMPExecutableDirective(D);
2626*67e74705SXin Li }
2627*67e74705SXin Li 
VisitOMPCriticalDirective(const OMPCriticalDirective * D)2628*67e74705SXin Li void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2629*67e74705SXin Li   VisitOMPExecutableDirective(D);
2630*67e74705SXin Li   AddDeclarationNameInfo(D);
2631*67e74705SXin Li }
2632*67e74705SXin Li 
2633*67e74705SXin Li void
VisitOMPParallelForDirective(const OMPParallelForDirective * D)2634*67e74705SXin Li EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
2635*67e74705SXin Li   VisitOMPLoopDirective(D);
2636*67e74705SXin Li }
2637*67e74705SXin Li 
VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective * D)2638*67e74705SXin Li void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2639*67e74705SXin Li     const OMPParallelForSimdDirective *D) {
2640*67e74705SXin Li   VisitOMPLoopDirective(D);
2641*67e74705SXin Li }
2642*67e74705SXin Li 
VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective * D)2643*67e74705SXin Li void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2644*67e74705SXin Li     const OMPParallelSectionsDirective *D) {
2645*67e74705SXin Li   VisitOMPExecutableDirective(D);
2646*67e74705SXin Li }
2647*67e74705SXin Li 
VisitOMPTaskDirective(const OMPTaskDirective * D)2648*67e74705SXin Li void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2649*67e74705SXin Li   VisitOMPExecutableDirective(D);
2650*67e74705SXin Li }
2651*67e74705SXin Li 
2652*67e74705SXin Li void
VisitOMPTaskyieldDirective(const OMPTaskyieldDirective * D)2653*67e74705SXin Li EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2654*67e74705SXin Li   VisitOMPExecutableDirective(D);
2655*67e74705SXin Li }
2656*67e74705SXin Li 
VisitOMPBarrierDirective(const OMPBarrierDirective * D)2657*67e74705SXin Li void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2658*67e74705SXin Li   VisitOMPExecutableDirective(D);
2659*67e74705SXin Li }
2660*67e74705SXin Li 
VisitOMPTaskwaitDirective(const OMPTaskwaitDirective * D)2661*67e74705SXin Li void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2662*67e74705SXin Li   VisitOMPExecutableDirective(D);
2663*67e74705SXin Li }
2664*67e74705SXin Li 
VisitOMPTaskgroupDirective(const OMPTaskgroupDirective * D)2665*67e74705SXin Li void EnqueueVisitor::VisitOMPTaskgroupDirective(
2666*67e74705SXin Li     const OMPTaskgroupDirective *D) {
2667*67e74705SXin Li   VisitOMPExecutableDirective(D);
2668*67e74705SXin Li }
2669*67e74705SXin Li 
VisitOMPFlushDirective(const OMPFlushDirective * D)2670*67e74705SXin Li void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2671*67e74705SXin Li   VisitOMPExecutableDirective(D);
2672*67e74705SXin Li }
2673*67e74705SXin Li 
VisitOMPOrderedDirective(const OMPOrderedDirective * D)2674*67e74705SXin Li void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2675*67e74705SXin Li   VisitOMPExecutableDirective(D);
2676*67e74705SXin Li }
2677*67e74705SXin Li 
VisitOMPAtomicDirective(const OMPAtomicDirective * D)2678*67e74705SXin Li void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2679*67e74705SXin Li   VisitOMPExecutableDirective(D);
2680*67e74705SXin Li }
2681*67e74705SXin Li 
VisitOMPTargetDirective(const OMPTargetDirective * D)2682*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2683*67e74705SXin Li   VisitOMPExecutableDirective(D);
2684*67e74705SXin Li }
2685*67e74705SXin Li 
VisitOMPTargetDataDirective(const OMPTargetDataDirective * D)2686*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetDataDirective(const
2687*67e74705SXin Li                                                  OMPTargetDataDirective *D) {
2688*67e74705SXin Li   VisitOMPExecutableDirective(D);
2689*67e74705SXin Li }
2690*67e74705SXin Li 
VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective * D)2691*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2692*67e74705SXin Li     const OMPTargetEnterDataDirective *D) {
2693*67e74705SXin Li   VisitOMPExecutableDirective(D);
2694*67e74705SXin Li }
2695*67e74705SXin Li 
VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective * D)2696*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2697*67e74705SXin Li     const OMPTargetExitDataDirective *D) {
2698*67e74705SXin Li   VisitOMPExecutableDirective(D);
2699*67e74705SXin Li }
2700*67e74705SXin Li 
VisitOMPTargetParallelDirective(const OMPTargetParallelDirective * D)2701*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetParallelDirective(
2702*67e74705SXin Li     const OMPTargetParallelDirective *D) {
2703*67e74705SXin Li   VisitOMPExecutableDirective(D);
2704*67e74705SXin Li }
2705*67e74705SXin Li 
VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective * D)2706*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2707*67e74705SXin Li     const OMPTargetParallelForDirective *D) {
2708*67e74705SXin Li   VisitOMPLoopDirective(D);
2709*67e74705SXin Li }
2710*67e74705SXin Li 
VisitOMPTeamsDirective(const OMPTeamsDirective * D)2711*67e74705SXin Li void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2712*67e74705SXin Li   VisitOMPExecutableDirective(D);
2713*67e74705SXin Li }
2714*67e74705SXin Li 
VisitOMPCancellationPointDirective(const OMPCancellationPointDirective * D)2715*67e74705SXin Li void EnqueueVisitor::VisitOMPCancellationPointDirective(
2716*67e74705SXin Li     const OMPCancellationPointDirective *D) {
2717*67e74705SXin Li   VisitOMPExecutableDirective(D);
2718*67e74705SXin Li }
2719*67e74705SXin Li 
VisitOMPCancelDirective(const OMPCancelDirective * D)2720*67e74705SXin Li void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2721*67e74705SXin Li   VisitOMPExecutableDirective(D);
2722*67e74705SXin Li }
2723*67e74705SXin Li 
VisitOMPTaskLoopDirective(const OMPTaskLoopDirective * D)2724*67e74705SXin Li void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2725*67e74705SXin Li   VisitOMPLoopDirective(D);
2726*67e74705SXin Li }
2727*67e74705SXin Li 
VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective * D)2728*67e74705SXin Li void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2729*67e74705SXin Li     const OMPTaskLoopSimdDirective *D) {
2730*67e74705SXin Li   VisitOMPLoopDirective(D);
2731*67e74705SXin Li }
2732*67e74705SXin Li 
VisitOMPDistributeDirective(const OMPDistributeDirective * D)2733*67e74705SXin Li void EnqueueVisitor::VisitOMPDistributeDirective(
2734*67e74705SXin Li     const OMPDistributeDirective *D) {
2735*67e74705SXin Li   VisitOMPLoopDirective(D);
2736*67e74705SXin Li }
2737*67e74705SXin Li 
VisitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective * D)2738*67e74705SXin Li void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
2739*67e74705SXin Li     const OMPDistributeParallelForDirective *D) {
2740*67e74705SXin Li   VisitOMPLoopDirective(D);
2741*67e74705SXin Li }
2742*67e74705SXin Li 
VisitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective * D)2743*67e74705SXin Li void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
2744*67e74705SXin Li     const OMPDistributeParallelForSimdDirective *D) {
2745*67e74705SXin Li   VisitOMPLoopDirective(D);
2746*67e74705SXin Li }
2747*67e74705SXin Li 
VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective * D)2748*67e74705SXin Li void EnqueueVisitor::VisitOMPDistributeSimdDirective(
2749*67e74705SXin Li     const OMPDistributeSimdDirective *D) {
2750*67e74705SXin Li   VisitOMPLoopDirective(D);
2751*67e74705SXin Li }
2752*67e74705SXin Li 
VisitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective * D)2753*67e74705SXin Li void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
2754*67e74705SXin Li     const OMPTargetParallelForSimdDirective *D) {
2755*67e74705SXin Li   VisitOMPLoopDirective(D);
2756*67e74705SXin Li }
2757*67e74705SXin Li 
EnqueueWorkList(VisitorWorkList & WL,const Stmt * S)2758*67e74705SXin Li void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
2759*67e74705SXin Li   EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2760*67e74705SXin Li }
2761*67e74705SXin Li 
IsInRegionOfInterest(CXCursor C)2762*67e74705SXin Li bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2763*67e74705SXin Li   if (RegionOfInterest.isValid()) {
2764*67e74705SXin Li     SourceRange Range = getRawCursorExtent(C);
2765*67e74705SXin Li     if (Range.isInvalid() || CompareRegionOfInterest(Range))
2766*67e74705SXin Li       return false;
2767*67e74705SXin Li   }
2768*67e74705SXin Li   return true;
2769*67e74705SXin Li }
2770*67e74705SXin Li 
RunVisitorWorkList(VisitorWorkList & WL)2771*67e74705SXin Li bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2772*67e74705SXin Li   while (!WL.empty()) {
2773*67e74705SXin Li     // Dequeue the worklist item.
2774*67e74705SXin Li     VisitorJob LI = WL.pop_back_val();
2775*67e74705SXin Li 
2776*67e74705SXin Li     // Set the Parent field, then back to its old value once we're done.
2777*67e74705SXin Li     SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2778*67e74705SXin Li 
2779*67e74705SXin Li     switch (LI.getKind()) {
2780*67e74705SXin Li       case VisitorJob::DeclVisitKind: {
2781*67e74705SXin Li         const Decl *D = cast<DeclVisit>(&LI)->get();
2782*67e74705SXin Li         if (!D)
2783*67e74705SXin Li           continue;
2784*67e74705SXin Li 
2785*67e74705SXin Li         // For now, perform default visitation for Decls.
2786*67e74705SXin Li         if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2787*67e74705SXin Li                                cast<DeclVisit>(&LI)->isFirst())))
2788*67e74705SXin Li             return true;
2789*67e74705SXin Li 
2790*67e74705SXin Li         continue;
2791*67e74705SXin Li       }
2792*67e74705SXin Li       case VisitorJob::ExplicitTemplateArgsVisitKind: {
2793*67e74705SXin Li         for (const TemplateArgumentLoc &Arg :
2794*67e74705SXin Li              *cast<ExplicitTemplateArgsVisit>(&LI)) {
2795*67e74705SXin Li           if (VisitTemplateArgumentLoc(Arg))
2796*67e74705SXin Li             return true;
2797*67e74705SXin Li         }
2798*67e74705SXin Li         continue;
2799*67e74705SXin Li       }
2800*67e74705SXin Li       case VisitorJob::TypeLocVisitKind: {
2801*67e74705SXin Li         // Perform default visitation for TypeLocs.
2802*67e74705SXin Li         if (Visit(cast<TypeLocVisit>(&LI)->get()))
2803*67e74705SXin Li           return true;
2804*67e74705SXin Li         continue;
2805*67e74705SXin Li       }
2806*67e74705SXin Li       case VisitorJob::LabelRefVisitKind: {
2807*67e74705SXin Li         const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
2808*67e74705SXin Li         if (LabelStmt *stmt = LS->getStmt()) {
2809*67e74705SXin Li           if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2810*67e74705SXin Li                                        TU))) {
2811*67e74705SXin Li             return true;
2812*67e74705SXin Li           }
2813*67e74705SXin Li         }
2814*67e74705SXin Li         continue;
2815*67e74705SXin Li       }
2816*67e74705SXin Li 
2817*67e74705SXin Li       case VisitorJob::NestedNameSpecifierLocVisitKind: {
2818*67e74705SXin Li         NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2819*67e74705SXin Li         if (VisitNestedNameSpecifierLoc(V->get()))
2820*67e74705SXin Li           return true;
2821*67e74705SXin Li         continue;
2822*67e74705SXin Li       }
2823*67e74705SXin Li 
2824*67e74705SXin Li       case VisitorJob::DeclarationNameInfoVisitKind: {
2825*67e74705SXin Li         if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2826*67e74705SXin Li                                      ->get()))
2827*67e74705SXin Li           return true;
2828*67e74705SXin Li         continue;
2829*67e74705SXin Li       }
2830*67e74705SXin Li       case VisitorJob::MemberRefVisitKind: {
2831*67e74705SXin Li         MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2832*67e74705SXin Li         if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2833*67e74705SXin Li           return true;
2834*67e74705SXin Li         continue;
2835*67e74705SXin Li       }
2836*67e74705SXin Li       case VisitorJob::StmtVisitKind: {
2837*67e74705SXin Li         const Stmt *S = cast<StmtVisit>(&LI)->get();
2838*67e74705SXin Li         if (!S)
2839*67e74705SXin Li           continue;
2840*67e74705SXin Li 
2841*67e74705SXin Li         // Update the current cursor.
2842*67e74705SXin Li         CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2843*67e74705SXin Li         if (!IsInRegionOfInterest(Cursor))
2844*67e74705SXin Li           continue;
2845*67e74705SXin Li         switch (Visitor(Cursor, Parent, ClientData)) {
2846*67e74705SXin Li           case CXChildVisit_Break: return true;
2847*67e74705SXin Li           case CXChildVisit_Continue: break;
2848*67e74705SXin Li           case CXChildVisit_Recurse:
2849*67e74705SXin Li             if (PostChildrenVisitor)
2850*67e74705SXin Li               WL.push_back(PostChildrenVisit(nullptr, Cursor));
2851*67e74705SXin Li             EnqueueWorkList(WL, S);
2852*67e74705SXin Li             break;
2853*67e74705SXin Li         }
2854*67e74705SXin Li         continue;
2855*67e74705SXin Li       }
2856*67e74705SXin Li       case VisitorJob::MemberExprPartsKind: {
2857*67e74705SXin Li         // Handle the other pieces in the MemberExpr besides the base.
2858*67e74705SXin Li         const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
2859*67e74705SXin Li 
2860*67e74705SXin Li         // Visit the nested-name-specifier
2861*67e74705SXin Li         if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2862*67e74705SXin Li           if (VisitNestedNameSpecifierLoc(QualifierLoc))
2863*67e74705SXin Li             return true;
2864*67e74705SXin Li 
2865*67e74705SXin Li         // Visit the declaration name.
2866*67e74705SXin Li         if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2867*67e74705SXin Li           return true;
2868*67e74705SXin Li 
2869*67e74705SXin Li         // Visit the explicitly-specified template arguments, if any.
2870*67e74705SXin Li         if (M->hasExplicitTemplateArgs()) {
2871*67e74705SXin Li           for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2872*67e74705SXin Li                *ArgEnd = Arg + M->getNumTemplateArgs();
2873*67e74705SXin Li                Arg != ArgEnd; ++Arg) {
2874*67e74705SXin Li             if (VisitTemplateArgumentLoc(*Arg))
2875*67e74705SXin Li               return true;
2876*67e74705SXin Li           }
2877*67e74705SXin Li         }
2878*67e74705SXin Li         continue;
2879*67e74705SXin Li       }
2880*67e74705SXin Li       case VisitorJob::DeclRefExprPartsKind: {
2881*67e74705SXin Li         const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
2882*67e74705SXin Li         // Visit nested-name-specifier, if present.
2883*67e74705SXin Li         if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2884*67e74705SXin Li           if (VisitNestedNameSpecifierLoc(QualifierLoc))
2885*67e74705SXin Li             return true;
2886*67e74705SXin Li         // Visit declaration name.
2887*67e74705SXin Li         if (VisitDeclarationNameInfo(DR->getNameInfo()))
2888*67e74705SXin Li           return true;
2889*67e74705SXin Li         continue;
2890*67e74705SXin Li       }
2891*67e74705SXin Li       case VisitorJob::OverloadExprPartsKind: {
2892*67e74705SXin Li         const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
2893*67e74705SXin Li         // Visit the nested-name-specifier.
2894*67e74705SXin Li         if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2895*67e74705SXin Li           if (VisitNestedNameSpecifierLoc(QualifierLoc))
2896*67e74705SXin Li             return true;
2897*67e74705SXin Li         // Visit the declaration name.
2898*67e74705SXin Li         if (VisitDeclarationNameInfo(O->getNameInfo()))
2899*67e74705SXin Li           return true;
2900*67e74705SXin Li         // Visit the overloaded declaration reference.
2901*67e74705SXin Li         if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2902*67e74705SXin Li           return true;
2903*67e74705SXin Li         continue;
2904*67e74705SXin Li       }
2905*67e74705SXin Li       case VisitorJob::SizeOfPackExprPartsKind: {
2906*67e74705SXin Li         const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
2907*67e74705SXin Li         NamedDecl *Pack = E->getPack();
2908*67e74705SXin Li         if (isa<TemplateTypeParmDecl>(Pack)) {
2909*67e74705SXin Li           if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2910*67e74705SXin Li                                       E->getPackLoc(), TU)))
2911*67e74705SXin Li             return true;
2912*67e74705SXin Li 
2913*67e74705SXin Li           continue;
2914*67e74705SXin Li         }
2915*67e74705SXin Li 
2916*67e74705SXin Li         if (isa<TemplateTemplateParmDecl>(Pack)) {
2917*67e74705SXin Li           if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2918*67e74705SXin Li                                           E->getPackLoc(), TU)))
2919*67e74705SXin Li             return true;
2920*67e74705SXin Li 
2921*67e74705SXin Li           continue;
2922*67e74705SXin Li         }
2923*67e74705SXin Li 
2924*67e74705SXin Li         // Non-type template parameter packs and function parameter packs are
2925*67e74705SXin Li         // treated like DeclRefExpr cursors.
2926*67e74705SXin Li         continue;
2927*67e74705SXin Li       }
2928*67e74705SXin Li 
2929*67e74705SXin Li       case VisitorJob::LambdaExprPartsKind: {
2930*67e74705SXin Li         // Visit captures.
2931*67e74705SXin Li         const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
2932*67e74705SXin Li         for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2933*67e74705SXin Li                                        CEnd = E->explicit_capture_end();
2934*67e74705SXin Li              C != CEnd; ++C) {
2935*67e74705SXin Li           // FIXME: Lambda init-captures.
2936*67e74705SXin Li           if (!C->capturesVariable())
2937*67e74705SXin Li             continue;
2938*67e74705SXin Li 
2939*67e74705SXin Li           if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2940*67e74705SXin Li                                           C->getLocation(),
2941*67e74705SXin Li                                           TU)))
2942*67e74705SXin Li             return true;
2943*67e74705SXin Li         }
2944*67e74705SXin Li 
2945*67e74705SXin Li         // Visit parameters and return type, if present.
2946*67e74705SXin Li         if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2947*67e74705SXin Li           TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2948*67e74705SXin Li           if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2949*67e74705SXin Li             // Visit the whole type.
2950*67e74705SXin Li             if (Visit(TL))
2951*67e74705SXin Li               return true;
2952*67e74705SXin Li           } else if (FunctionProtoTypeLoc Proto =
2953*67e74705SXin Li                          TL.getAs<FunctionProtoTypeLoc>()) {
2954*67e74705SXin Li             if (E->hasExplicitParameters()) {
2955*67e74705SXin Li               // Visit parameters.
2956*67e74705SXin Li               for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2957*67e74705SXin Li                 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
2958*67e74705SXin Li                   return true;
2959*67e74705SXin Li             } else {
2960*67e74705SXin Li               // Visit result type.
2961*67e74705SXin Li               if (Visit(Proto.getReturnLoc()))
2962*67e74705SXin Li                 return true;
2963*67e74705SXin Li             }
2964*67e74705SXin Li           }
2965*67e74705SXin Li         }
2966*67e74705SXin Li         break;
2967*67e74705SXin Li       }
2968*67e74705SXin Li 
2969*67e74705SXin Li       case VisitorJob::PostChildrenVisitKind:
2970*67e74705SXin Li         if (PostChildrenVisitor(Parent, ClientData))
2971*67e74705SXin Li           return true;
2972*67e74705SXin Li         break;
2973*67e74705SXin Li     }
2974*67e74705SXin Li   }
2975*67e74705SXin Li   return false;
2976*67e74705SXin Li }
2977*67e74705SXin Li 
Visit(const Stmt * S)2978*67e74705SXin Li bool CursorVisitor::Visit(const Stmt *S) {
2979*67e74705SXin Li   VisitorWorkList *WL = nullptr;
2980*67e74705SXin Li   if (!WorkListFreeList.empty()) {
2981*67e74705SXin Li     WL = WorkListFreeList.back();
2982*67e74705SXin Li     WL->clear();
2983*67e74705SXin Li     WorkListFreeList.pop_back();
2984*67e74705SXin Li   }
2985*67e74705SXin Li   else {
2986*67e74705SXin Li     WL = new VisitorWorkList();
2987*67e74705SXin Li     WorkListCache.push_back(WL);
2988*67e74705SXin Li   }
2989*67e74705SXin Li   EnqueueWorkList(*WL, S);
2990*67e74705SXin Li   bool result = RunVisitorWorkList(*WL);
2991*67e74705SXin Li   WorkListFreeList.push_back(WL);
2992*67e74705SXin Li   return result;
2993*67e74705SXin Li }
2994*67e74705SXin Li 
2995*67e74705SXin Li namespace {
2996*67e74705SXin Li typedef SmallVector<SourceRange, 4> RefNamePieces;
buildPieces(unsigned NameFlags,bool IsMemberRefExpr,const DeclarationNameInfo & NI,SourceRange QLoc,const SourceRange * TemplateArgsLoc=nullptr)2997*67e74705SXin Li RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2998*67e74705SXin Li                           const DeclarationNameInfo &NI, SourceRange QLoc,
2999*67e74705SXin Li                           const SourceRange *TemplateArgsLoc = nullptr) {
3000*67e74705SXin Li   const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3001*67e74705SXin Li   const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3002*67e74705SXin Li   const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
3003*67e74705SXin Li 
3004*67e74705SXin Li   const DeclarationName::NameKind Kind = NI.getName().getNameKind();
3005*67e74705SXin Li 
3006*67e74705SXin Li   RefNamePieces Pieces;
3007*67e74705SXin Li 
3008*67e74705SXin Li   if (WantQualifier && QLoc.isValid())
3009*67e74705SXin Li     Pieces.push_back(QLoc);
3010*67e74705SXin Li 
3011*67e74705SXin Li   if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3012*67e74705SXin Li     Pieces.push_back(NI.getLoc());
3013*67e74705SXin Li 
3014*67e74705SXin Li   if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3015*67e74705SXin Li     Pieces.push_back(*TemplateArgsLoc);
3016*67e74705SXin Li 
3017*67e74705SXin Li   if (Kind == DeclarationName::CXXOperatorName) {
3018*67e74705SXin Li     Pieces.push_back(SourceLocation::getFromRawEncoding(
3019*67e74705SXin Li                        NI.getInfo().CXXOperatorName.BeginOpNameLoc));
3020*67e74705SXin Li     Pieces.push_back(SourceLocation::getFromRawEncoding(
3021*67e74705SXin Li                        NI.getInfo().CXXOperatorName.EndOpNameLoc));
3022*67e74705SXin Li   }
3023*67e74705SXin Li 
3024*67e74705SXin Li   if (WantSinglePiece) {
3025*67e74705SXin Li     SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3026*67e74705SXin Li     Pieces.clear();
3027*67e74705SXin Li     Pieces.push_back(R);
3028*67e74705SXin Li   }
3029*67e74705SXin Li 
3030*67e74705SXin Li   return Pieces;
3031*67e74705SXin Li }
3032*67e74705SXin Li }
3033*67e74705SXin Li 
3034*67e74705SXin Li //===----------------------------------------------------------------------===//
3035*67e74705SXin Li // Misc. API hooks.
3036*67e74705SXin Li //===----------------------------------------------------------------------===//
3037*67e74705SXin Li 
fatal_error_handler(void * user_data,const std::string & reason,bool gen_crash_diag)3038*67e74705SXin Li static void fatal_error_handler(void *user_data, const std::string& reason,
3039*67e74705SXin Li                                 bool gen_crash_diag) {
3040*67e74705SXin Li   // Write the result out to stderr avoiding errs() because raw_ostreams can
3041*67e74705SXin Li   // call report_fatal_error.
3042*67e74705SXin Li   fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
3043*67e74705SXin Li   ::abort();
3044*67e74705SXin Li }
3045*67e74705SXin Li 
3046*67e74705SXin Li namespace {
3047*67e74705SXin Li struct RegisterFatalErrorHandler {
RegisterFatalErrorHandler__anonef1af4320511::RegisterFatalErrorHandler3048*67e74705SXin Li   RegisterFatalErrorHandler() {
3049*67e74705SXin Li     llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
3050*67e74705SXin Li   }
3051*67e74705SXin Li };
3052*67e74705SXin Li }
3053*67e74705SXin Li 
3054*67e74705SXin Li static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
3055*67e74705SXin Li 
3056*67e74705SXin Li extern "C" {
clang_createIndex(int excludeDeclarationsFromPCH,int displayDiagnostics)3057*67e74705SXin Li CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3058*67e74705SXin Li                           int displayDiagnostics) {
3059*67e74705SXin Li   // We use crash recovery to make some of our APIs more reliable, implicitly
3060*67e74705SXin Li   // enable it.
3061*67e74705SXin Li   if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3062*67e74705SXin Li     llvm::CrashRecoveryContext::Enable();
3063*67e74705SXin Li 
3064*67e74705SXin Li   // Look through the managed static to trigger construction of the managed
3065*67e74705SXin Li   // static which registers our fatal error handler. This ensures it is only
3066*67e74705SXin Li   // registered once.
3067*67e74705SXin Li   (void)*RegisterFatalErrorHandlerOnce;
3068*67e74705SXin Li 
3069*67e74705SXin Li   // Initialize targets for clang module support.
3070*67e74705SXin Li   llvm::InitializeAllTargets();
3071*67e74705SXin Li   llvm::InitializeAllTargetMCs();
3072*67e74705SXin Li   llvm::InitializeAllAsmPrinters();
3073*67e74705SXin Li   llvm::InitializeAllAsmParsers();
3074*67e74705SXin Li 
3075*67e74705SXin Li   CIndexer *CIdxr = new CIndexer();
3076*67e74705SXin Li 
3077*67e74705SXin Li   if (excludeDeclarationsFromPCH)
3078*67e74705SXin Li     CIdxr->setOnlyLocalDecls();
3079*67e74705SXin Li   if (displayDiagnostics)
3080*67e74705SXin Li     CIdxr->setDisplayDiagnostics();
3081*67e74705SXin Li 
3082*67e74705SXin Li   if (getenv("LIBCLANG_BGPRIO_INDEX"))
3083*67e74705SXin Li     CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3084*67e74705SXin Li                                CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3085*67e74705SXin Li   if (getenv("LIBCLANG_BGPRIO_EDIT"))
3086*67e74705SXin Li     CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3087*67e74705SXin Li                                CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3088*67e74705SXin Li 
3089*67e74705SXin Li   return CIdxr;
3090*67e74705SXin Li }
3091*67e74705SXin Li 
clang_disposeIndex(CXIndex CIdx)3092*67e74705SXin Li void clang_disposeIndex(CXIndex CIdx) {
3093*67e74705SXin Li   if (CIdx)
3094*67e74705SXin Li     delete static_cast<CIndexer *>(CIdx);
3095*67e74705SXin Li }
3096*67e74705SXin Li 
clang_CXIndex_setGlobalOptions(CXIndex CIdx,unsigned options)3097*67e74705SXin Li void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3098*67e74705SXin Li   if (CIdx)
3099*67e74705SXin Li     static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3100*67e74705SXin Li }
3101*67e74705SXin Li 
clang_CXIndex_getGlobalOptions(CXIndex CIdx)3102*67e74705SXin Li unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3103*67e74705SXin Li   if (CIdx)
3104*67e74705SXin Li     return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3105*67e74705SXin Li   return 0;
3106*67e74705SXin Li }
3107*67e74705SXin Li 
clang_toggleCrashRecovery(unsigned isEnabled)3108*67e74705SXin Li void clang_toggleCrashRecovery(unsigned isEnabled) {
3109*67e74705SXin Li   if (isEnabled)
3110*67e74705SXin Li     llvm::CrashRecoveryContext::Enable();
3111*67e74705SXin Li   else
3112*67e74705SXin Li     llvm::CrashRecoveryContext::Disable();
3113*67e74705SXin Li }
3114*67e74705SXin Li 
clang_createTranslationUnit(CXIndex CIdx,const char * ast_filename)3115*67e74705SXin Li CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3116*67e74705SXin Li                                               const char *ast_filename) {
3117*67e74705SXin Li   CXTranslationUnit TU;
3118*67e74705SXin Li   enum CXErrorCode Result =
3119*67e74705SXin Li       clang_createTranslationUnit2(CIdx, ast_filename, &TU);
3120*67e74705SXin Li   (void)Result;
3121*67e74705SXin Li   assert((TU && Result == CXError_Success) ||
3122*67e74705SXin Li          (!TU && Result != CXError_Success));
3123*67e74705SXin Li   return TU;
3124*67e74705SXin Li }
3125*67e74705SXin Li 
clang_createTranslationUnit2(CXIndex CIdx,const char * ast_filename,CXTranslationUnit * out_TU)3126*67e74705SXin Li enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3127*67e74705SXin Li                                               const char *ast_filename,
3128*67e74705SXin Li                                               CXTranslationUnit *out_TU) {
3129*67e74705SXin Li   if (out_TU)
3130*67e74705SXin Li     *out_TU = nullptr;
3131*67e74705SXin Li 
3132*67e74705SXin Li   if (!CIdx || !ast_filename || !out_TU)
3133*67e74705SXin Li     return CXError_InvalidArguments;
3134*67e74705SXin Li 
3135*67e74705SXin Li   LOG_FUNC_SECTION {
3136*67e74705SXin Li     *Log << ast_filename;
3137*67e74705SXin Li   }
3138*67e74705SXin Li 
3139*67e74705SXin Li   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3140*67e74705SXin Li   FileSystemOptions FileSystemOpts;
3141*67e74705SXin Li 
3142*67e74705SXin Li   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3143*67e74705SXin Li       CompilerInstance::createDiagnostics(new DiagnosticOptions());
3144*67e74705SXin Li   std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
3145*67e74705SXin Li       ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
3146*67e74705SXin Li       FileSystemOpts, /*UseDebugInfo=*/false,
3147*67e74705SXin Li       CXXIdx->getOnlyLocalDecls(), None,
3148*67e74705SXin Li       /*CaptureDiagnostics=*/true,
3149*67e74705SXin Li       /*AllowPCHWithCompilerErrors=*/true,
3150*67e74705SXin Li       /*UserFilesAreVolatile=*/true);
3151*67e74705SXin Li   *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
3152*67e74705SXin Li   return *out_TU ? CXError_Success : CXError_Failure;
3153*67e74705SXin Li }
3154*67e74705SXin Li 
clang_defaultEditingTranslationUnitOptions()3155*67e74705SXin Li unsigned clang_defaultEditingTranslationUnitOptions() {
3156*67e74705SXin Li   return CXTranslationUnit_PrecompiledPreamble |
3157*67e74705SXin Li          CXTranslationUnit_CacheCompletionResults;
3158*67e74705SXin Li }
3159*67e74705SXin Li 
3160*67e74705SXin Li 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)3161*67e74705SXin Li clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3162*67e74705SXin Li                                           const char *source_filename,
3163*67e74705SXin Li                                           int num_command_line_args,
3164*67e74705SXin Li                                           const char * const *command_line_args,
3165*67e74705SXin Li                                           unsigned num_unsaved_files,
3166*67e74705SXin Li                                           struct CXUnsavedFile *unsaved_files) {
3167*67e74705SXin Li   unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3168*67e74705SXin Li   return clang_parseTranslationUnit(CIdx, source_filename,
3169*67e74705SXin Li                                     command_line_args, num_command_line_args,
3170*67e74705SXin Li                                     unsaved_files, num_unsaved_files,
3171*67e74705SXin Li                                     Options);
3172*67e74705SXin Li }
3173*67e74705SXin Li 
3174*67e74705SXin Li static CXErrorCode
clang_parseTranslationUnit_Impl(CXIndex CIdx,const char * source_filename,const char * const * command_line_args,int num_command_line_args,ArrayRef<CXUnsavedFile> unsaved_files,unsigned options,CXTranslationUnit * out_TU)3175*67e74705SXin Li clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3176*67e74705SXin Li                                 const char *const *command_line_args,
3177*67e74705SXin Li                                 int num_command_line_args,
3178*67e74705SXin Li                                 ArrayRef<CXUnsavedFile> unsaved_files,
3179*67e74705SXin Li                                 unsigned options, CXTranslationUnit *out_TU) {
3180*67e74705SXin Li   // Set up the initial return values.
3181*67e74705SXin Li   if (out_TU)
3182*67e74705SXin Li     *out_TU = nullptr;
3183*67e74705SXin Li 
3184*67e74705SXin Li   // Check arguments.
3185*67e74705SXin Li   if (!CIdx || !out_TU)
3186*67e74705SXin Li     return CXError_InvalidArguments;
3187*67e74705SXin Li 
3188*67e74705SXin Li   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3189*67e74705SXin Li 
3190*67e74705SXin Li   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3191*67e74705SXin Li     setThreadBackgroundPriority();
3192*67e74705SXin Li 
3193*67e74705SXin Li   bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3194*67e74705SXin Li   bool CreatePreambleOnFirstParse =
3195*67e74705SXin Li       options & CXTranslationUnit_CreatePreambleOnFirstParse;
3196*67e74705SXin Li   // FIXME: Add a flag for modules.
3197*67e74705SXin Li   TranslationUnitKind TUKind
3198*67e74705SXin Li     = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
3199*67e74705SXin Li   bool CacheCodeCompletionResults
3200*67e74705SXin Li     = options & CXTranslationUnit_CacheCompletionResults;
3201*67e74705SXin Li   bool IncludeBriefCommentsInCodeCompletion
3202*67e74705SXin Li     = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3203*67e74705SXin Li   bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3204*67e74705SXin Li   bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3205*67e74705SXin Li 
3206*67e74705SXin Li   // Configure the diagnostics.
3207*67e74705SXin Li   IntrusiveRefCntPtr<DiagnosticsEngine>
3208*67e74705SXin Li     Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
3209*67e74705SXin Li 
3210*67e74705SXin Li   if (options & CXTranslationUnit_KeepGoing)
3211*67e74705SXin Li     Diags->setFatalsAsError(true);
3212*67e74705SXin Li 
3213*67e74705SXin Li   // Recover resources if we crash before exiting this function.
3214*67e74705SXin Li   llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3215*67e74705SXin Li     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
3216*67e74705SXin Li     DiagCleanup(Diags.get());
3217*67e74705SXin Li 
3218*67e74705SXin Li   std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3219*67e74705SXin Li       new std::vector<ASTUnit::RemappedFile>());
3220*67e74705SXin Li 
3221*67e74705SXin Li   // Recover resources if we crash before exiting this function.
3222*67e74705SXin Li   llvm::CrashRecoveryContextCleanupRegistrar<
3223*67e74705SXin Li     std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3224*67e74705SXin Li 
3225*67e74705SXin Li   for (auto &UF : unsaved_files) {
3226*67e74705SXin Li     std::unique_ptr<llvm::MemoryBuffer> MB =
3227*67e74705SXin Li         llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3228*67e74705SXin Li     RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
3229*67e74705SXin Li   }
3230*67e74705SXin Li 
3231*67e74705SXin Li   std::unique_ptr<std::vector<const char *>> Args(
3232*67e74705SXin Li       new std::vector<const char *>());
3233*67e74705SXin Li 
3234*67e74705SXin Li   // Recover resources if we crash before exiting this method.
3235*67e74705SXin Li   llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3236*67e74705SXin Li     ArgsCleanup(Args.get());
3237*67e74705SXin Li 
3238*67e74705SXin Li   // Since the Clang C library is primarily used by batch tools dealing with
3239*67e74705SXin Li   // (often very broken) source code, where spell-checking can have a
3240*67e74705SXin Li   // significant negative impact on performance (particularly when
3241*67e74705SXin Li   // precompiled headers are involved), we disable it by default.
3242*67e74705SXin Li   // Only do this if we haven't found a spell-checking-related argument.
3243*67e74705SXin Li   bool FoundSpellCheckingArgument = false;
3244*67e74705SXin Li   for (int I = 0; I != num_command_line_args; ++I) {
3245*67e74705SXin Li     if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3246*67e74705SXin Li         strcmp(command_line_args[I], "-fspell-checking") == 0) {
3247*67e74705SXin Li       FoundSpellCheckingArgument = true;
3248*67e74705SXin Li       break;
3249*67e74705SXin Li     }
3250*67e74705SXin Li   }
3251*67e74705SXin Li   Args->insert(Args->end(), command_line_args,
3252*67e74705SXin Li                command_line_args + num_command_line_args);
3253*67e74705SXin Li 
3254*67e74705SXin Li   if (!FoundSpellCheckingArgument)
3255*67e74705SXin Li     Args->insert(Args->begin() + 1, "-fno-spell-checking");
3256*67e74705SXin Li 
3257*67e74705SXin Li   // The 'source_filename' argument is optional.  If the caller does not
3258*67e74705SXin Li   // specify it then it is assumed that the source file is specified
3259*67e74705SXin Li   // in the actual argument list.
3260*67e74705SXin Li   // Put the source file after command_line_args otherwise if '-x' flag is
3261*67e74705SXin Li   // present it will be unused.
3262*67e74705SXin Li   if (source_filename)
3263*67e74705SXin Li     Args->push_back(source_filename);
3264*67e74705SXin Li 
3265*67e74705SXin Li   // Do we need the detailed preprocessing record?
3266*67e74705SXin Li   if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3267*67e74705SXin Li     Args->push_back("-Xclang");
3268*67e74705SXin Li     Args->push_back("-detailed-preprocessing-record");
3269*67e74705SXin Li   }
3270*67e74705SXin Li 
3271*67e74705SXin Li   unsigned NumErrors = Diags->getClient()->getNumErrors();
3272*67e74705SXin Li   std::unique_ptr<ASTUnit> ErrUnit;
3273*67e74705SXin Li   // Unless the user specified that they want the preamble on the first parse
3274*67e74705SXin Li   // set it up to be created on the first reparse. This makes the first parse
3275*67e74705SXin Li   // faster, trading for a slower (first) reparse.
3276*67e74705SXin Li   unsigned PrecompilePreambleAfterNParses =
3277*67e74705SXin Li       !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
3278*67e74705SXin Li   std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
3279*67e74705SXin Li       Args->data(), Args->data() + Args->size(),
3280*67e74705SXin Li       CXXIdx->getPCHContainerOperations(), Diags,
3281*67e74705SXin Li       CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3282*67e74705SXin Li       /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3283*67e74705SXin Li       /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3284*67e74705SXin Li       TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3285*67e74705SXin Li       /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3286*67e74705SXin Li       /*UserFilesAreVolatile=*/true, ForSerialization,
3287*67e74705SXin Li       CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3288*67e74705SXin Li       &ErrUnit));
3289*67e74705SXin Li 
3290*67e74705SXin Li   // Early failures in LoadFromCommandLine may return with ErrUnit unset.
3291*67e74705SXin Li   if (!Unit && !ErrUnit)
3292*67e74705SXin Li     return CXError_ASTReadError;
3293*67e74705SXin Li 
3294*67e74705SXin Li   if (NumErrors != Diags->getClient()->getNumErrors()) {
3295*67e74705SXin Li     // Make sure to check that 'Unit' is non-NULL.
3296*67e74705SXin Li     if (CXXIdx->getDisplayDiagnostics())
3297*67e74705SXin Li       printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3298*67e74705SXin Li   }
3299*67e74705SXin Li 
3300*67e74705SXin Li   if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3301*67e74705SXin Li     return CXError_ASTReadError;
3302*67e74705SXin Li 
3303*67e74705SXin Li   *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3304*67e74705SXin Li   return *out_TU ? CXError_Success : CXError_Failure;
3305*67e74705SXin Li }
3306*67e74705SXin Li 
3307*67e74705SXin Li 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)3308*67e74705SXin Li clang_parseTranslationUnit(CXIndex CIdx,
3309*67e74705SXin Li                            const char *source_filename,
3310*67e74705SXin Li                            const char *const *command_line_args,
3311*67e74705SXin Li                            int num_command_line_args,
3312*67e74705SXin Li                            struct CXUnsavedFile *unsaved_files,
3313*67e74705SXin Li                            unsigned num_unsaved_files,
3314*67e74705SXin Li                            unsigned options) {
3315*67e74705SXin Li   CXTranslationUnit TU;
3316*67e74705SXin Li   enum CXErrorCode Result = clang_parseTranslationUnit2(
3317*67e74705SXin Li       CIdx, source_filename, command_line_args, num_command_line_args,
3318*67e74705SXin Li       unsaved_files, num_unsaved_files, options, &TU);
3319*67e74705SXin Li   (void)Result;
3320*67e74705SXin Li   assert((TU && Result == CXError_Success) ||
3321*67e74705SXin Li          (!TU && Result != CXError_Success));
3322*67e74705SXin Li   return TU;
3323*67e74705SXin Li }
3324*67e74705SXin Li 
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)3325*67e74705SXin Li enum CXErrorCode clang_parseTranslationUnit2(
3326*67e74705SXin Li     CXIndex CIdx, const char *source_filename,
3327*67e74705SXin Li     const char *const *command_line_args, int num_command_line_args,
3328*67e74705SXin Li     struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3329*67e74705SXin Li     unsigned options, CXTranslationUnit *out_TU) {
3330*67e74705SXin Li   SmallVector<const char *, 4> Args;
3331*67e74705SXin Li   Args.push_back("clang");
3332*67e74705SXin Li   Args.append(command_line_args, command_line_args + num_command_line_args);
3333*67e74705SXin Li   return clang_parseTranslationUnit2FullArgv(
3334*67e74705SXin Li       CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3335*67e74705SXin Li       num_unsaved_files, options, out_TU);
3336*67e74705SXin Li }
3337*67e74705SXin Li 
clang_parseTranslationUnit2FullArgv(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)3338*67e74705SXin Li enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3339*67e74705SXin Li     CXIndex CIdx, const char *source_filename,
3340*67e74705SXin Li     const char *const *command_line_args, int num_command_line_args,
3341*67e74705SXin Li     struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3342*67e74705SXin Li     unsigned options, CXTranslationUnit *out_TU) {
3343*67e74705SXin Li   LOG_FUNC_SECTION {
3344*67e74705SXin Li     *Log << source_filename << ": ";
3345*67e74705SXin Li     for (int i = 0; i != num_command_line_args; ++i)
3346*67e74705SXin Li       *Log << command_line_args[i] << " ";
3347*67e74705SXin Li   }
3348*67e74705SXin Li 
3349*67e74705SXin Li   if (num_unsaved_files && !unsaved_files)
3350*67e74705SXin Li     return CXError_InvalidArguments;
3351*67e74705SXin Li 
3352*67e74705SXin Li   CXErrorCode result = CXError_Failure;
3353*67e74705SXin Li   auto ParseTranslationUnitImpl = [=, &result] {
3354*67e74705SXin Li     result = clang_parseTranslationUnit_Impl(
3355*67e74705SXin Li         CIdx, source_filename, command_line_args, num_command_line_args,
3356*67e74705SXin Li         llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3357*67e74705SXin Li   };
3358*67e74705SXin Li   llvm::CrashRecoveryContext CRC;
3359*67e74705SXin Li 
3360*67e74705SXin Li   if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
3361*67e74705SXin Li     fprintf(stderr, "libclang: crash detected during parsing: {\n");
3362*67e74705SXin Li     fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
3363*67e74705SXin Li     fprintf(stderr, "  'command_line_args' : [");
3364*67e74705SXin Li     for (int i = 0; i != num_command_line_args; ++i) {
3365*67e74705SXin Li       if (i)
3366*67e74705SXin Li         fprintf(stderr, ", ");
3367*67e74705SXin Li       fprintf(stderr, "'%s'", command_line_args[i]);
3368*67e74705SXin Li     }
3369*67e74705SXin Li     fprintf(stderr, "],\n");
3370*67e74705SXin Li     fprintf(stderr, "  'unsaved_files' : [");
3371*67e74705SXin Li     for (unsigned i = 0; i != num_unsaved_files; ++i) {
3372*67e74705SXin Li       if (i)
3373*67e74705SXin Li         fprintf(stderr, ", ");
3374*67e74705SXin Li       fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3375*67e74705SXin Li               unsaved_files[i].Length);
3376*67e74705SXin Li     }
3377*67e74705SXin Li     fprintf(stderr, "],\n");
3378*67e74705SXin Li     fprintf(stderr, "  'options' : %d,\n", options);
3379*67e74705SXin Li     fprintf(stderr, "}\n");
3380*67e74705SXin Li 
3381*67e74705SXin Li     return CXError_Crashed;
3382*67e74705SXin Li   } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3383*67e74705SXin Li     if (CXTranslationUnit *TU = out_TU)
3384*67e74705SXin Li       PrintLibclangResourceUsage(*TU);
3385*67e74705SXin Li   }
3386*67e74705SXin Li 
3387*67e74705SXin Li   return result;
3388*67e74705SXin Li }
3389*67e74705SXin Li 
clang_Type_getObjCEncoding(CXType CT)3390*67e74705SXin Li CXString clang_Type_getObjCEncoding(CXType CT) {
3391*67e74705SXin Li   CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3392*67e74705SXin Li   ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3393*67e74705SXin Li   std::string encoding;
3394*67e74705SXin Li   Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
3395*67e74705SXin Li                              encoding);
3396*67e74705SXin Li 
3397*67e74705SXin Li   return cxstring::createDup(encoding);
3398*67e74705SXin Li }
3399*67e74705SXin Li 
getMacroIdentifier(CXCursor C)3400*67e74705SXin Li static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3401*67e74705SXin Li   if (C.kind == CXCursor_MacroDefinition) {
3402*67e74705SXin Li     if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3403*67e74705SXin Li       return MDR->getName();
3404*67e74705SXin Li   } else if (C.kind == CXCursor_MacroExpansion) {
3405*67e74705SXin Li     MacroExpansionCursor ME = getCursorMacroExpansion(C);
3406*67e74705SXin Li     return ME.getName();
3407*67e74705SXin Li   }
3408*67e74705SXin Li   return nullptr;
3409*67e74705SXin Li }
3410*67e74705SXin Li 
clang_Cursor_isMacroFunctionLike(CXCursor C)3411*67e74705SXin Li unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3412*67e74705SXin Li   const IdentifierInfo *II = getMacroIdentifier(C);
3413*67e74705SXin Li   if (!II) {
3414*67e74705SXin Li     return false;
3415*67e74705SXin Li   }
3416*67e74705SXin Li   ASTUnit *ASTU = getCursorASTUnit(C);
3417*67e74705SXin Li   Preprocessor &PP = ASTU->getPreprocessor();
3418*67e74705SXin Li   if (const MacroInfo *MI = PP.getMacroInfo(II))
3419*67e74705SXin Li     return MI->isFunctionLike();
3420*67e74705SXin Li   return false;
3421*67e74705SXin Li }
3422*67e74705SXin Li 
clang_Cursor_isMacroBuiltin(CXCursor C)3423*67e74705SXin Li unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3424*67e74705SXin Li   const IdentifierInfo *II = getMacroIdentifier(C);
3425*67e74705SXin Li   if (!II) {
3426*67e74705SXin Li     return false;
3427*67e74705SXin Li   }
3428*67e74705SXin Li   ASTUnit *ASTU = getCursorASTUnit(C);
3429*67e74705SXin Li   Preprocessor &PP = ASTU->getPreprocessor();
3430*67e74705SXin Li   if (const MacroInfo *MI = PP.getMacroInfo(II))
3431*67e74705SXin Li     return MI->isBuiltinMacro();
3432*67e74705SXin Li   return false;
3433*67e74705SXin Li }
3434*67e74705SXin Li 
clang_Cursor_isFunctionInlined(CXCursor C)3435*67e74705SXin Li unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3436*67e74705SXin Li   const Decl *D = getCursorDecl(C);
3437*67e74705SXin Li   const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3438*67e74705SXin Li   if (!FD) {
3439*67e74705SXin Li     return false;
3440*67e74705SXin Li   }
3441*67e74705SXin Li   return FD->isInlined();
3442*67e74705SXin Li }
3443*67e74705SXin Li 
getCFSTR_value(CallExpr * callExpr)3444*67e74705SXin Li static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
3445*67e74705SXin Li   if (callExpr->getNumArgs() != 1) {
3446*67e74705SXin Li     return nullptr;
3447*67e74705SXin Li   }
3448*67e74705SXin Li 
3449*67e74705SXin Li   StringLiteral *S = nullptr;
3450*67e74705SXin Li   auto *arg = callExpr->getArg(0);
3451*67e74705SXin Li   if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3452*67e74705SXin Li     ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3453*67e74705SXin Li     auto *subExpr = I->getSubExprAsWritten();
3454*67e74705SXin Li 
3455*67e74705SXin Li     if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
3456*67e74705SXin Li       return nullptr;
3457*67e74705SXin Li     }
3458*67e74705SXin Li 
3459*67e74705SXin Li     S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3460*67e74705SXin Li   } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3461*67e74705SXin Li     S = static_cast<StringLiteral *>(callExpr->getArg(0));
3462*67e74705SXin Li   } else {
3463*67e74705SXin Li     return nullptr;
3464*67e74705SXin Li   }
3465*67e74705SXin Li   return S;
3466*67e74705SXin Li }
3467*67e74705SXin Li 
3468*67e74705SXin Li struct ExprEvalResult {
3469*67e74705SXin Li   CXEvalResultKind EvalType;
3470*67e74705SXin Li   union {
3471*67e74705SXin Li     int intVal;
3472*67e74705SXin Li     double floatVal;
3473*67e74705SXin Li     char *stringVal;
3474*67e74705SXin Li   } EvalData;
~ExprEvalResultExprEvalResult3475*67e74705SXin Li   ~ExprEvalResult() {
3476*67e74705SXin Li     if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3477*67e74705SXin Li         EvalType != CXEval_Int) {
3478*67e74705SXin Li       delete EvalData.stringVal;
3479*67e74705SXin Li     }
3480*67e74705SXin Li   }
3481*67e74705SXin Li };
3482*67e74705SXin Li 
clang_EvalResult_dispose(CXEvalResult E)3483*67e74705SXin Li void clang_EvalResult_dispose(CXEvalResult E) {
3484*67e74705SXin Li   delete static_cast<ExprEvalResult *>(E);
3485*67e74705SXin Li }
3486*67e74705SXin Li 
clang_EvalResult_getKind(CXEvalResult E)3487*67e74705SXin Li CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3488*67e74705SXin Li   if (!E) {
3489*67e74705SXin Li     return CXEval_UnExposed;
3490*67e74705SXin Li   }
3491*67e74705SXin Li   return ((ExprEvalResult *)E)->EvalType;
3492*67e74705SXin Li }
3493*67e74705SXin Li 
clang_EvalResult_getAsInt(CXEvalResult E)3494*67e74705SXin Li int clang_EvalResult_getAsInt(CXEvalResult E) {
3495*67e74705SXin Li   if (!E) {
3496*67e74705SXin Li     return 0;
3497*67e74705SXin Li   }
3498*67e74705SXin Li   return ((ExprEvalResult *)E)->EvalData.intVal;
3499*67e74705SXin Li }
3500*67e74705SXin Li 
clang_EvalResult_getAsDouble(CXEvalResult E)3501*67e74705SXin Li double clang_EvalResult_getAsDouble(CXEvalResult E) {
3502*67e74705SXin Li   if (!E) {
3503*67e74705SXin Li     return 0;
3504*67e74705SXin Li   }
3505*67e74705SXin Li   return ((ExprEvalResult *)E)->EvalData.floatVal;
3506*67e74705SXin Li }
3507*67e74705SXin Li 
clang_EvalResult_getAsStr(CXEvalResult E)3508*67e74705SXin Li const char* clang_EvalResult_getAsStr(CXEvalResult E) {
3509*67e74705SXin Li   if (!E) {
3510*67e74705SXin Li     return nullptr;
3511*67e74705SXin Li   }
3512*67e74705SXin Li   return ((ExprEvalResult *)E)->EvalData.stringVal;
3513*67e74705SXin Li }
3514*67e74705SXin Li 
evaluateExpr(Expr * expr,CXCursor C)3515*67e74705SXin Li static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
3516*67e74705SXin Li   Expr::EvalResult ER;
3517*67e74705SXin Li   ASTContext &ctx = getCursorContext(C);
3518*67e74705SXin Li   if (!expr)
3519*67e74705SXin Li     return nullptr;
3520*67e74705SXin Li 
3521*67e74705SXin Li   expr = expr->IgnoreParens();
3522*67e74705SXin Li   if (!expr->EvaluateAsRValue(ER, ctx))
3523*67e74705SXin Li     return nullptr;
3524*67e74705SXin Li 
3525*67e74705SXin Li   QualType rettype;
3526*67e74705SXin Li   CallExpr *callExpr;
3527*67e74705SXin Li   auto result = llvm::make_unique<ExprEvalResult>();
3528*67e74705SXin Li   result->EvalType = CXEval_UnExposed;
3529*67e74705SXin Li 
3530*67e74705SXin Li   if (ER.Val.isInt()) {
3531*67e74705SXin Li     result->EvalType = CXEval_Int;
3532*67e74705SXin Li     result->EvalData.intVal = ER.Val.getInt().getExtValue();
3533*67e74705SXin Li     return result.release();
3534*67e74705SXin Li   }
3535*67e74705SXin Li 
3536*67e74705SXin Li   if (ER.Val.isFloat()) {
3537*67e74705SXin Li     llvm::SmallVector<char, 100> Buffer;
3538*67e74705SXin Li     ER.Val.getFloat().toString(Buffer);
3539*67e74705SXin Li     std::string floatStr(Buffer.data(), Buffer.size());
3540*67e74705SXin Li     result->EvalType = CXEval_Float;
3541*67e74705SXin Li     bool ignored;
3542*67e74705SXin Li     llvm::APFloat apFloat = ER.Val.getFloat();
3543*67e74705SXin Li     apFloat.convert(llvm::APFloat::IEEEdouble,
3544*67e74705SXin Li                     llvm::APFloat::rmNearestTiesToEven, &ignored);
3545*67e74705SXin Li     result->EvalData.floatVal = apFloat.convertToDouble();
3546*67e74705SXin Li     return result.release();
3547*67e74705SXin Li   }
3548*67e74705SXin Li 
3549*67e74705SXin Li   if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3550*67e74705SXin Li     const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3551*67e74705SXin Li     auto *subExpr = I->getSubExprAsWritten();
3552*67e74705SXin Li     if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3553*67e74705SXin Li         subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
3554*67e74705SXin Li       const StringLiteral *StrE = nullptr;
3555*67e74705SXin Li       const ObjCStringLiteral *ObjCExpr;
3556*67e74705SXin Li       ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
3557*67e74705SXin Li 
3558*67e74705SXin Li       if (ObjCExpr) {
3559*67e74705SXin Li         StrE = ObjCExpr->getString();
3560*67e74705SXin Li         result->EvalType = CXEval_ObjCStrLiteral;
3561*67e74705SXin Li       } else {
3562*67e74705SXin Li         StrE = cast<StringLiteral>(I->getSubExprAsWritten());
3563*67e74705SXin Li         result->EvalType = CXEval_StrLiteral;
3564*67e74705SXin Li       }
3565*67e74705SXin Li 
3566*67e74705SXin Li       std::string strRef(StrE->getString().str());
3567*67e74705SXin Li       result->EvalData.stringVal = new char[strRef.size() + 1];
3568*67e74705SXin Li       strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3569*67e74705SXin Li               strRef.size());
3570*67e74705SXin Li       result->EvalData.stringVal[strRef.size()] = '\0';
3571*67e74705SXin Li       return result.release();
3572*67e74705SXin Li     }
3573*67e74705SXin Li   } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3574*67e74705SXin Li              expr->getStmtClass() == Stmt::StringLiteralClass) {
3575*67e74705SXin Li     const StringLiteral *StrE = nullptr;
3576*67e74705SXin Li     const ObjCStringLiteral *ObjCExpr;
3577*67e74705SXin Li     ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
3578*67e74705SXin Li 
3579*67e74705SXin Li     if (ObjCExpr) {
3580*67e74705SXin Li       StrE = ObjCExpr->getString();
3581*67e74705SXin Li       result->EvalType = CXEval_ObjCStrLiteral;
3582*67e74705SXin Li     } else {
3583*67e74705SXin Li       StrE = cast<StringLiteral>(expr);
3584*67e74705SXin Li       result->EvalType = CXEval_StrLiteral;
3585*67e74705SXin Li     }
3586*67e74705SXin Li 
3587*67e74705SXin Li     std::string strRef(StrE->getString().str());
3588*67e74705SXin Li     result->EvalData.stringVal = new char[strRef.size() + 1];
3589*67e74705SXin Li     strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3590*67e74705SXin Li     result->EvalData.stringVal[strRef.size()] = '\0';
3591*67e74705SXin Li     return result.release();
3592*67e74705SXin Li   }
3593*67e74705SXin Li 
3594*67e74705SXin Li   if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3595*67e74705SXin Li     CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
3596*67e74705SXin Li 
3597*67e74705SXin Li     rettype = CC->getType();
3598*67e74705SXin Li     if (rettype.getAsString() == "CFStringRef" &&
3599*67e74705SXin Li         CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
3600*67e74705SXin Li 
3601*67e74705SXin Li       callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3602*67e74705SXin Li       StringLiteral *S = getCFSTR_value(callExpr);
3603*67e74705SXin Li       if (S) {
3604*67e74705SXin Li         std::string strLiteral(S->getString().str());
3605*67e74705SXin Li         result->EvalType = CXEval_CFStr;
3606*67e74705SXin Li 
3607*67e74705SXin Li         result->EvalData.stringVal = new char[strLiteral.size() + 1];
3608*67e74705SXin Li         strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3609*67e74705SXin Li                 strLiteral.size());
3610*67e74705SXin Li         result->EvalData.stringVal[strLiteral.size()] = '\0';
3611*67e74705SXin Li         return result.release();
3612*67e74705SXin Li       }
3613*67e74705SXin Li     }
3614*67e74705SXin Li 
3615*67e74705SXin Li   } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3616*67e74705SXin Li     callExpr = static_cast<CallExpr *>(expr);
3617*67e74705SXin Li     rettype = callExpr->getCallReturnType(ctx);
3618*67e74705SXin Li 
3619*67e74705SXin Li     if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
3620*67e74705SXin Li       return nullptr;
3621*67e74705SXin Li 
3622*67e74705SXin Li     if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3623*67e74705SXin Li       if (callExpr->getNumArgs() == 1 &&
3624*67e74705SXin Li           !callExpr->getArg(0)->getType()->isIntegralType(ctx))
3625*67e74705SXin Li         return nullptr;
3626*67e74705SXin Li     } else if (rettype.getAsString() == "CFStringRef") {
3627*67e74705SXin Li 
3628*67e74705SXin Li       StringLiteral *S = getCFSTR_value(callExpr);
3629*67e74705SXin Li       if (S) {
3630*67e74705SXin Li         std::string strLiteral(S->getString().str());
3631*67e74705SXin Li         result->EvalType = CXEval_CFStr;
3632*67e74705SXin Li         result->EvalData.stringVal = new char[strLiteral.size() + 1];
3633*67e74705SXin Li         strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3634*67e74705SXin Li                 strLiteral.size());
3635*67e74705SXin Li         result->EvalData.stringVal[strLiteral.size()] = '\0';
3636*67e74705SXin Li         return result.release();
3637*67e74705SXin Li       }
3638*67e74705SXin Li     }
3639*67e74705SXin Li   } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3640*67e74705SXin Li     DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3641*67e74705SXin Li     ValueDecl *V = D->getDecl();
3642*67e74705SXin Li     if (V->getKind() == Decl::Function) {
3643*67e74705SXin Li       std::string strName = V->getNameAsString();
3644*67e74705SXin Li       result->EvalType = CXEval_Other;
3645*67e74705SXin Li       result->EvalData.stringVal = new char[strName.size() + 1];
3646*67e74705SXin Li       strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
3647*67e74705SXin Li       result->EvalData.stringVal[strName.size()] = '\0';
3648*67e74705SXin Li       return result.release();
3649*67e74705SXin Li     }
3650*67e74705SXin Li   }
3651*67e74705SXin Li 
3652*67e74705SXin Li   return nullptr;
3653*67e74705SXin Li }
3654*67e74705SXin Li 
clang_Cursor_Evaluate(CXCursor C)3655*67e74705SXin Li CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
3656*67e74705SXin Li   const Decl *D = getCursorDecl(C);
3657*67e74705SXin Li   if (D) {
3658*67e74705SXin Li     const Expr *expr = nullptr;
3659*67e74705SXin Li     if (auto *Var = dyn_cast<VarDecl>(D)) {
3660*67e74705SXin Li       expr = Var->getInit();
3661*67e74705SXin Li     } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
3662*67e74705SXin Li       expr = Field->getInClassInitializer();
3663*67e74705SXin Li     }
3664*67e74705SXin Li     if (expr)
3665*67e74705SXin Li       return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
3666*67e74705SXin Li           evaluateExpr(const_cast<Expr *>(expr), C)));
3667*67e74705SXin Li     return nullptr;
3668*67e74705SXin Li   }
3669*67e74705SXin Li 
3670*67e74705SXin Li   const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
3671*67e74705SXin Li   if (compoundStmt) {
3672*67e74705SXin Li     Expr *expr = nullptr;
3673*67e74705SXin Li     for (auto *bodyIterator : compoundStmt->body()) {
3674*67e74705SXin Li       if ((expr = dyn_cast<Expr>(bodyIterator))) {
3675*67e74705SXin Li         break;
3676*67e74705SXin Li       }
3677*67e74705SXin Li     }
3678*67e74705SXin Li     if (expr)
3679*67e74705SXin Li       return const_cast<CXEvalResult>(
3680*67e74705SXin Li           reinterpret_cast<const void *>(evaluateExpr(expr, C)));
3681*67e74705SXin Li   }
3682*67e74705SXin Li   return nullptr;
3683*67e74705SXin Li }
3684*67e74705SXin Li 
clang_Cursor_hasAttrs(CXCursor C)3685*67e74705SXin Li unsigned clang_Cursor_hasAttrs(CXCursor C) {
3686*67e74705SXin Li   const Decl *D = getCursorDecl(C);
3687*67e74705SXin Li   if (!D) {
3688*67e74705SXin Li     return 0;
3689*67e74705SXin Li   }
3690*67e74705SXin Li 
3691*67e74705SXin Li   if (D->hasAttrs()) {
3692*67e74705SXin Li     return 1;
3693*67e74705SXin Li   }
3694*67e74705SXin Li 
3695*67e74705SXin Li   return 0;
3696*67e74705SXin Li }
clang_defaultSaveOptions(CXTranslationUnit TU)3697*67e74705SXin Li unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3698*67e74705SXin Li   return CXSaveTranslationUnit_None;
3699*67e74705SXin Li }
3700*67e74705SXin Li 
clang_saveTranslationUnit_Impl(CXTranslationUnit TU,const char * FileName,unsigned options)3701*67e74705SXin Li static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3702*67e74705SXin Li                                                   const char *FileName,
3703*67e74705SXin Li                                                   unsigned options) {
3704*67e74705SXin Li   CIndexer *CXXIdx = TU->CIdx;
3705*67e74705SXin Li   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3706*67e74705SXin Li     setThreadBackgroundPriority();
3707*67e74705SXin Li 
3708*67e74705SXin Li   bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3709*67e74705SXin Li   return hadError ? CXSaveError_Unknown : CXSaveError_None;
3710*67e74705SXin Li }
3711*67e74705SXin Li 
clang_saveTranslationUnit(CXTranslationUnit TU,const char * FileName,unsigned options)3712*67e74705SXin Li int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3713*67e74705SXin Li                               unsigned options) {
3714*67e74705SXin Li   LOG_FUNC_SECTION {
3715*67e74705SXin Li     *Log << TU << ' ' << FileName;
3716*67e74705SXin Li   }
3717*67e74705SXin Li 
3718*67e74705SXin Li   if (isNotUsableTU(TU)) {
3719*67e74705SXin Li     LOG_BAD_TU(TU);
3720*67e74705SXin Li     return CXSaveError_InvalidTU;
3721*67e74705SXin Li   }
3722*67e74705SXin Li 
3723*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3724*67e74705SXin Li   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3725*67e74705SXin Li   if (!CXXUnit->hasSema())
3726*67e74705SXin Li     return CXSaveError_InvalidTU;
3727*67e74705SXin Li 
3728*67e74705SXin Li   CXSaveError result;
3729*67e74705SXin Li   auto SaveTranslationUnitImpl = [=, &result]() {
3730*67e74705SXin Li     result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3731*67e74705SXin Li   };
3732*67e74705SXin Li 
3733*67e74705SXin Li   if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3734*67e74705SXin Li       getenv("LIBCLANG_NOTHREADS")) {
3735*67e74705SXin Li     SaveTranslationUnitImpl();
3736*67e74705SXin Li 
3737*67e74705SXin Li     if (getenv("LIBCLANG_RESOURCE_USAGE"))
3738*67e74705SXin Li       PrintLibclangResourceUsage(TU);
3739*67e74705SXin Li 
3740*67e74705SXin Li     return result;
3741*67e74705SXin Li   }
3742*67e74705SXin Li 
3743*67e74705SXin Li   // We have an AST that has invalid nodes due to compiler errors.
3744*67e74705SXin Li   // Use a crash recovery thread for protection.
3745*67e74705SXin Li 
3746*67e74705SXin Li   llvm::CrashRecoveryContext CRC;
3747*67e74705SXin Li 
3748*67e74705SXin Li   if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
3749*67e74705SXin Li     fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3750*67e74705SXin Li     fprintf(stderr, "  'filename' : '%s'\n", FileName);
3751*67e74705SXin Li     fprintf(stderr, "  'options' : %d,\n", options);
3752*67e74705SXin Li     fprintf(stderr, "}\n");
3753*67e74705SXin Li 
3754*67e74705SXin Li     return CXSaveError_Unknown;
3755*67e74705SXin Li 
3756*67e74705SXin Li   } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3757*67e74705SXin Li     PrintLibclangResourceUsage(TU);
3758*67e74705SXin Li   }
3759*67e74705SXin Li 
3760*67e74705SXin Li   return result;
3761*67e74705SXin Li }
3762*67e74705SXin Li 
clang_disposeTranslationUnit(CXTranslationUnit CTUnit)3763*67e74705SXin Li void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3764*67e74705SXin Li   if (CTUnit) {
3765*67e74705SXin Li     // If the translation unit has been marked as unsafe to free, just discard
3766*67e74705SXin Li     // it.
3767*67e74705SXin Li     ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3768*67e74705SXin Li     if (Unit && Unit->isUnsafeToFree())
3769*67e74705SXin Li       return;
3770*67e74705SXin Li 
3771*67e74705SXin Li     delete cxtu::getASTUnit(CTUnit);
3772*67e74705SXin Li     delete CTUnit->StringPool;
3773*67e74705SXin Li     delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3774*67e74705SXin Li     disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
3775*67e74705SXin Li     delete CTUnit->CommentToXML;
3776*67e74705SXin Li     delete CTUnit;
3777*67e74705SXin Li   }
3778*67e74705SXin Li }
3779*67e74705SXin Li 
clang_defaultReparseOptions(CXTranslationUnit TU)3780*67e74705SXin Li unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3781*67e74705SXin Li   return CXReparse_None;
3782*67e74705SXin Li }
3783*67e74705SXin Li 
3784*67e74705SXin Li static CXErrorCode
clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,ArrayRef<CXUnsavedFile> unsaved_files,unsigned options)3785*67e74705SXin Li clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3786*67e74705SXin Li                                   ArrayRef<CXUnsavedFile> unsaved_files,
3787*67e74705SXin Li                                   unsigned options) {
3788*67e74705SXin Li   // Check arguments.
3789*67e74705SXin Li   if (isNotUsableTU(TU)) {
3790*67e74705SXin Li     LOG_BAD_TU(TU);
3791*67e74705SXin Li     return CXError_InvalidArguments;
3792*67e74705SXin Li   }
3793*67e74705SXin Li 
3794*67e74705SXin Li   // Reset the associated diagnostics.
3795*67e74705SXin Li   delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3796*67e74705SXin Li   TU->Diagnostics = nullptr;
3797*67e74705SXin Li 
3798*67e74705SXin Li   CIndexer *CXXIdx = TU->CIdx;
3799*67e74705SXin Li   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3800*67e74705SXin Li     setThreadBackgroundPriority();
3801*67e74705SXin Li 
3802*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3803*67e74705SXin Li   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3804*67e74705SXin Li 
3805*67e74705SXin Li   std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3806*67e74705SXin Li       new std::vector<ASTUnit::RemappedFile>());
3807*67e74705SXin Li 
3808*67e74705SXin Li   // Recover resources if we crash before exiting this function.
3809*67e74705SXin Li   llvm::CrashRecoveryContextCleanupRegistrar<
3810*67e74705SXin Li     std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3811*67e74705SXin Li 
3812*67e74705SXin Li   for (auto &UF : unsaved_files) {
3813*67e74705SXin Li     std::unique_ptr<llvm::MemoryBuffer> MB =
3814*67e74705SXin Li         llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3815*67e74705SXin Li     RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
3816*67e74705SXin Li   }
3817*67e74705SXin Li 
3818*67e74705SXin Li   if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3819*67e74705SXin Li                         *RemappedFiles.get()))
3820*67e74705SXin Li     return CXError_Success;
3821*67e74705SXin Li   if (isASTReadError(CXXUnit))
3822*67e74705SXin Li     return CXError_ASTReadError;
3823*67e74705SXin Li   return CXError_Failure;
3824*67e74705SXin Li }
3825*67e74705SXin Li 
clang_reparseTranslationUnit(CXTranslationUnit TU,unsigned num_unsaved_files,struct CXUnsavedFile * unsaved_files,unsigned options)3826*67e74705SXin Li int clang_reparseTranslationUnit(CXTranslationUnit TU,
3827*67e74705SXin Li                                  unsigned num_unsaved_files,
3828*67e74705SXin Li                                  struct CXUnsavedFile *unsaved_files,
3829*67e74705SXin Li                                  unsigned options) {
3830*67e74705SXin Li   LOG_FUNC_SECTION {
3831*67e74705SXin Li     *Log << TU;
3832*67e74705SXin Li   }
3833*67e74705SXin Li 
3834*67e74705SXin Li   if (num_unsaved_files && !unsaved_files)
3835*67e74705SXin Li     return CXError_InvalidArguments;
3836*67e74705SXin Li 
3837*67e74705SXin Li   CXErrorCode result;
3838*67e74705SXin Li   auto ReparseTranslationUnitImpl = [=, &result]() {
3839*67e74705SXin Li     result = clang_reparseTranslationUnit_Impl(
3840*67e74705SXin Li         TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3841*67e74705SXin Li   };
3842*67e74705SXin Li 
3843*67e74705SXin Li   if (getenv("LIBCLANG_NOTHREADS")) {
3844*67e74705SXin Li     ReparseTranslationUnitImpl();
3845*67e74705SXin Li     return result;
3846*67e74705SXin Li   }
3847*67e74705SXin Li 
3848*67e74705SXin Li   llvm::CrashRecoveryContext CRC;
3849*67e74705SXin Li 
3850*67e74705SXin Li   if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
3851*67e74705SXin Li     fprintf(stderr, "libclang: crash detected during reparsing\n");
3852*67e74705SXin Li     cxtu::getASTUnit(TU)->setUnsafeToFree(true);
3853*67e74705SXin Li     return CXError_Crashed;
3854*67e74705SXin Li   } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3855*67e74705SXin Li     PrintLibclangResourceUsage(TU);
3856*67e74705SXin Li 
3857*67e74705SXin Li   return result;
3858*67e74705SXin Li }
3859*67e74705SXin Li 
3860*67e74705SXin Li 
clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit)3861*67e74705SXin Li CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
3862*67e74705SXin Li   if (isNotUsableTU(CTUnit)) {
3863*67e74705SXin Li     LOG_BAD_TU(CTUnit);
3864*67e74705SXin Li     return cxstring::createEmpty();
3865*67e74705SXin Li   }
3866*67e74705SXin Li 
3867*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
3868*67e74705SXin Li   return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
3869*67e74705SXin Li }
3870*67e74705SXin Li 
clang_getTranslationUnitCursor(CXTranslationUnit TU)3871*67e74705SXin Li CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
3872*67e74705SXin Li   if (isNotUsableTU(TU)) {
3873*67e74705SXin Li     LOG_BAD_TU(TU);
3874*67e74705SXin Li     return clang_getNullCursor();
3875*67e74705SXin Li   }
3876*67e74705SXin Li 
3877*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3878*67e74705SXin Li   return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3879*67e74705SXin Li }
3880*67e74705SXin Li 
3881*67e74705SXin Li } // end: extern "C"
3882*67e74705SXin Li 
3883*67e74705SXin Li //===----------------------------------------------------------------------===//
3884*67e74705SXin Li // CXFile Operations.
3885*67e74705SXin Li //===----------------------------------------------------------------------===//
3886*67e74705SXin Li 
3887*67e74705SXin Li extern "C" {
clang_getFileName(CXFile SFile)3888*67e74705SXin Li CXString clang_getFileName(CXFile SFile) {
3889*67e74705SXin Li   if (!SFile)
3890*67e74705SXin Li     return cxstring::createNull();
3891*67e74705SXin Li 
3892*67e74705SXin Li   FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3893*67e74705SXin Li   return cxstring::createRef(FEnt->getName());
3894*67e74705SXin Li }
3895*67e74705SXin Li 
clang_getFileTime(CXFile SFile)3896*67e74705SXin Li time_t clang_getFileTime(CXFile SFile) {
3897*67e74705SXin Li   if (!SFile)
3898*67e74705SXin Li     return 0;
3899*67e74705SXin Li 
3900*67e74705SXin Li   FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3901*67e74705SXin Li   return FEnt->getModificationTime();
3902*67e74705SXin Li }
3903*67e74705SXin Li 
clang_getFile(CXTranslationUnit TU,const char * file_name)3904*67e74705SXin Li CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
3905*67e74705SXin Li   if (isNotUsableTU(TU)) {
3906*67e74705SXin Li     LOG_BAD_TU(TU);
3907*67e74705SXin Li     return nullptr;
3908*67e74705SXin Li   }
3909*67e74705SXin Li 
3910*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3911*67e74705SXin Li 
3912*67e74705SXin Li   FileManager &FMgr = CXXUnit->getFileManager();
3913*67e74705SXin Li   return const_cast<FileEntry *>(FMgr.getFile(file_name));
3914*67e74705SXin Li }
3915*67e74705SXin Li 
clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,CXFile file)3916*67e74705SXin Li unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3917*67e74705SXin Li                                             CXFile file) {
3918*67e74705SXin Li   if (isNotUsableTU(TU)) {
3919*67e74705SXin Li     LOG_BAD_TU(TU);
3920*67e74705SXin Li     return 0;
3921*67e74705SXin Li   }
3922*67e74705SXin Li 
3923*67e74705SXin Li   if (!file)
3924*67e74705SXin Li     return 0;
3925*67e74705SXin Li 
3926*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
3927*67e74705SXin Li   FileEntry *FEnt = static_cast<FileEntry *>(file);
3928*67e74705SXin Li   return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3929*67e74705SXin Li                                           .isFileMultipleIncludeGuarded(FEnt);
3930*67e74705SXin Li }
3931*67e74705SXin Li 
clang_getFileUniqueID(CXFile file,CXFileUniqueID * outID)3932*67e74705SXin Li int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3933*67e74705SXin Li   if (!file || !outID)
3934*67e74705SXin Li     return 1;
3935*67e74705SXin Li 
3936*67e74705SXin Li   FileEntry *FEnt = static_cast<FileEntry *>(file);
3937*67e74705SXin Li   const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3938*67e74705SXin Li   outID->data[0] = ID.getDevice();
3939*67e74705SXin Li   outID->data[1] = ID.getFile();
3940*67e74705SXin Li   outID->data[2] = FEnt->getModificationTime();
3941*67e74705SXin Li   return 0;
3942*67e74705SXin Li }
3943*67e74705SXin Li 
clang_File_isEqual(CXFile file1,CXFile file2)3944*67e74705SXin Li int clang_File_isEqual(CXFile file1, CXFile file2) {
3945*67e74705SXin Li   if (file1 == file2)
3946*67e74705SXin Li     return true;
3947*67e74705SXin Li 
3948*67e74705SXin Li   if (!file1 || !file2)
3949*67e74705SXin Li     return false;
3950*67e74705SXin Li 
3951*67e74705SXin Li   FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3952*67e74705SXin Li   FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3953*67e74705SXin Li   return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3954*67e74705SXin Li }
3955*67e74705SXin Li 
3956*67e74705SXin Li } // end: extern "C"
3957*67e74705SXin Li 
3958*67e74705SXin Li //===----------------------------------------------------------------------===//
3959*67e74705SXin Li // CXCursor Operations.
3960*67e74705SXin Li //===----------------------------------------------------------------------===//
3961*67e74705SXin Li 
getDeclFromExpr(const Stmt * E)3962*67e74705SXin Li static const Decl *getDeclFromExpr(const Stmt *E) {
3963*67e74705SXin Li   if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
3964*67e74705SXin Li     return getDeclFromExpr(CE->getSubExpr());
3965*67e74705SXin Li 
3966*67e74705SXin Li   if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
3967*67e74705SXin Li     return RefExpr->getDecl();
3968*67e74705SXin Li   if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
3969*67e74705SXin Li     return ME->getMemberDecl();
3970*67e74705SXin Li   if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
3971*67e74705SXin Li     return RE->getDecl();
3972*67e74705SXin Li   if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
3973*67e74705SXin Li     if (PRE->isExplicitProperty())
3974*67e74705SXin Li       return PRE->getExplicitProperty();
3975*67e74705SXin Li     // It could be messaging both getter and setter as in:
3976*67e74705SXin Li     // ++myobj.myprop;
3977*67e74705SXin Li     // in which case prefer to associate the setter since it is less obvious
3978*67e74705SXin Li     // from inspecting the source that the setter is going to get called.
3979*67e74705SXin Li     if (PRE->isMessagingSetter())
3980*67e74705SXin Li       return PRE->getImplicitPropertySetter();
3981*67e74705SXin Li     return PRE->getImplicitPropertyGetter();
3982*67e74705SXin Li   }
3983*67e74705SXin Li   if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
3984*67e74705SXin Li     return getDeclFromExpr(POE->getSyntacticForm());
3985*67e74705SXin Li   if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
3986*67e74705SXin Li     if (Expr *Src = OVE->getSourceExpr())
3987*67e74705SXin Li       return getDeclFromExpr(Src);
3988*67e74705SXin Li 
3989*67e74705SXin Li   if (const CallExpr *CE = dyn_cast<CallExpr>(E))
3990*67e74705SXin Li     return getDeclFromExpr(CE->getCallee());
3991*67e74705SXin Li   if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
3992*67e74705SXin Li     if (!CE->isElidable())
3993*67e74705SXin Li     return CE->getConstructor();
3994*67e74705SXin Li   if (const CXXInheritedCtorInitExpr *CE =
3995*67e74705SXin Li           dyn_cast<CXXInheritedCtorInitExpr>(E))
3996*67e74705SXin Li     return CE->getConstructor();
3997*67e74705SXin Li   if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
3998*67e74705SXin Li     return OME->getMethodDecl();
3999*67e74705SXin Li 
4000*67e74705SXin Li   if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
4001*67e74705SXin Li     return PE->getProtocol();
4002*67e74705SXin Li   if (const SubstNonTypeTemplateParmPackExpr *NTTP
4003*67e74705SXin Li                               = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
4004*67e74705SXin Li     return NTTP->getParameterPack();
4005*67e74705SXin Li   if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
4006*67e74705SXin Li     if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
4007*67e74705SXin Li         isa<ParmVarDecl>(SizeOfPack->getPack()))
4008*67e74705SXin Li       return SizeOfPack->getPack();
4009*67e74705SXin Li 
4010*67e74705SXin Li   return nullptr;
4011*67e74705SXin Li }
4012*67e74705SXin Li 
getLocationFromExpr(const Expr * E)4013*67e74705SXin Li static SourceLocation getLocationFromExpr(const Expr *E) {
4014*67e74705SXin Li   if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
4015*67e74705SXin Li     return getLocationFromExpr(CE->getSubExpr());
4016*67e74705SXin Li 
4017*67e74705SXin Li   if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
4018*67e74705SXin Li     return /*FIXME:*/Msg->getLeftLoc();
4019*67e74705SXin Li   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
4020*67e74705SXin Li     return DRE->getLocation();
4021*67e74705SXin Li   if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
4022*67e74705SXin Li     return Member->getMemberLoc();
4023*67e74705SXin Li   if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
4024*67e74705SXin Li     return Ivar->getLocation();
4025*67e74705SXin Li   if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
4026*67e74705SXin Li     return SizeOfPack->getPackLoc();
4027*67e74705SXin Li   if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
4028*67e74705SXin Li     return PropRef->getLocation();
4029*67e74705SXin Li 
4030*67e74705SXin Li   return E->getLocStart();
4031*67e74705SXin Li }
4032*67e74705SXin Li 
4033*67e74705SXin Li extern "C" {
4034*67e74705SXin Li 
clang_visitChildren(CXCursor parent,CXCursorVisitor visitor,CXClientData client_data)4035*67e74705SXin Li unsigned clang_visitChildren(CXCursor parent,
4036*67e74705SXin Li                              CXCursorVisitor visitor,
4037*67e74705SXin Li                              CXClientData client_data) {
4038*67e74705SXin Li   CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4039*67e74705SXin Li                           /*VisitPreprocessorLast=*/false);
4040*67e74705SXin Li   return CursorVis.VisitChildren(parent);
4041*67e74705SXin Li }
4042*67e74705SXin Li 
4043*67e74705SXin Li #ifndef __has_feature
4044*67e74705SXin Li #define __has_feature(x) 0
4045*67e74705SXin Li #endif
4046*67e74705SXin Li #if __has_feature(blocks)
4047*67e74705SXin Li typedef enum CXChildVisitResult
4048*67e74705SXin Li      (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
4049*67e74705SXin Li 
visitWithBlock(CXCursor cursor,CXCursor parent,CXClientData client_data)4050*67e74705SXin Li static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4051*67e74705SXin Li     CXClientData client_data) {
4052*67e74705SXin Li   CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4053*67e74705SXin Li   return block(cursor, parent);
4054*67e74705SXin Li }
4055*67e74705SXin Li #else
4056*67e74705SXin Li // If we are compiled with a compiler that doesn't have native blocks support,
4057*67e74705SXin Li // define and call the block manually, so the
4058*67e74705SXin Li typedef struct _CXChildVisitResult
4059*67e74705SXin Li {
4060*67e74705SXin Li 	void *isa;
4061*67e74705SXin Li 	int flags;
4062*67e74705SXin Li 	int reserved;
4063*67e74705SXin Li 	enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
4064*67e74705SXin Li                                          CXCursor);
4065*67e74705SXin Li } *CXCursorVisitorBlock;
4066*67e74705SXin Li 
visitWithBlock(CXCursor cursor,CXCursor parent,CXClientData client_data)4067*67e74705SXin Li static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4068*67e74705SXin Li     CXClientData client_data) {
4069*67e74705SXin Li   CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4070*67e74705SXin Li   return block->invoke(block, cursor, parent);
4071*67e74705SXin Li }
4072*67e74705SXin Li #endif
4073*67e74705SXin Li 
4074*67e74705SXin Li 
clang_visitChildrenWithBlock(CXCursor parent,CXCursorVisitorBlock block)4075*67e74705SXin Li unsigned clang_visitChildrenWithBlock(CXCursor parent,
4076*67e74705SXin Li                                       CXCursorVisitorBlock block) {
4077*67e74705SXin Li   return clang_visitChildren(parent, visitWithBlock, block);
4078*67e74705SXin Li }
4079*67e74705SXin Li 
getDeclSpelling(const Decl * D)4080*67e74705SXin Li static CXString getDeclSpelling(const Decl *D) {
4081*67e74705SXin Li   if (!D)
4082*67e74705SXin Li     return cxstring::createEmpty();
4083*67e74705SXin Li 
4084*67e74705SXin Li   const NamedDecl *ND = dyn_cast<NamedDecl>(D);
4085*67e74705SXin Li   if (!ND) {
4086*67e74705SXin Li     if (const ObjCPropertyImplDecl *PropImpl =
4087*67e74705SXin Li             dyn_cast<ObjCPropertyImplDecl>(D))
4088*67e74705SXin Li       if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4089*67e74705SXin Li         return cxstring::createDup(Property->getIdentifier()->getName());
4090*67e74705SXin Li 
4091*67e74705SXin Li     if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
4092*67e74705SXin Li       if (Module *Mod = ImportD->getImportedModule())
4093*67e74705SXin Li         return cxstring::createDup(Mod->getFullModuleName());
4094*67e74705SXin Li 
4095*67e74705SXin Li     return cxstring::createEmpty();
4096*67e74705SXin Li   }
4097*67e74705SXin Li 
4098*67e74705SXin Li   if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
4099*67e74705SXin Li     return cxstring::createDup(OMD->getSelector().getAsString());
4100*67e74705SXin Li 
4101*67e74705SXin Li   if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
4102*67e74705SXin Li     // No, this isn't the same as the code below. getIdentifier() is non-virtual
4103*67e74705SXin Li     // and returns different names. NamedDecl returns the class name and
4104*67e74705SXin Li     // ObjCCategoryImplDecl returns the category name.
4105*67e74705SXin Li     return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
4106*67e74705SXin Li 
4107*67e74705SXin Li   if (isa<UsingDirectiveDecl>(D))
4108*67e74705SXin Li     return cxstring::createEmpty();
4109*67e74705SXin Li 
4110*67e74705SXin Li   SmallString<1024> S;
4111*67e74705SXin Li   llvm::raw_svector_ostream os(S);
4112*67e74705SXin Li   ND->printName(os);
4113*67e74705SXin Li 
4114*67e74705SXin Li   return cxstring::createDup(os.str());
4115*67e74705SXin Li }
4116*67e74705SXin Li 
clang_getCursorSpelling(CXCursor C)4117*67e74705SXin Li CXString clang_getCursorSpelling(CXCursor C) {
4118*67e74705SXin Li   if (clang_isTranslationUnit(C.kind))
4119*67e74705SXin Li     return clang_getTranslationUnitSpelling(getCursorTU(C));
4120*67e74705SXin Li 
4121*67e74705SXin Li   if (clang_isReference(C.kind)) {
4122*67e74705SXin Li     switch (C.kind) {
4123*67e74705SXin Li     case CXCursor_ObjCSuperClassRef: {
4124*67e74705SXin Li       const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
4125*67e74705SXin Li       return cxstring::createRef(Super->getIdentifier()->getNameStart());
4126*67e74705SXin Li     }
4127*67e74705SXin Li     case CXCursor_ObjCClassRef: {
4128*67e74705SXin Li       const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4129*67e74705SXin Li       return cxstring::createRef(Class->getIdentifier()->getNameStart());
4130*67e74705SXin Li     }
4131*67e74705SXin Li     case CXCursor_ObjCProtocolRef: {
4132*67e74705SXin Li       const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
4133*67e74705SXin Li       assert(OID && "getCursorSpelling(): Missing protocol decl");
4134*67e74705SXin Li       return cxstring::createRef(OID->getIdentifier()->getNameStart());
4135*67e74705SXin Li     }
4136*67e74705SXin Li     case CXCursor_CXXBaseSpecifier: {
4137*67e74705SXin Li       const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
4138*67e74705SXin Li       return cxstring::createDup(B->getType().getAsString());
4139*67e74705SXin Li     }
4140*67e74705SXin Li     case CXCursor_TypeRef: {
4141*67e74705SXin Li       const TypeDecl *Type = getCursorTypeRef(C).first;
4142*67e74705SXin Li       assert(Type && "Missing type decl");
4143*67e74705SXin Li 
4144*67e74705SXin Li       return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
4145*67e74705SXin Li                               getAsString());
4146*67e74705SXin Li     }
4147*67e74705SXin Li     case CXCursor_TemplateRef: {
4148*67e74705SXin Li       const TemplateDecl *Template = getCursorTemplateRef(C).first;
4149*67e74705SXin Li       assert(Template && "Missing template decl");
4150*67e74705SXin Li 
4151*67e74705SXin Li       return cxstring::createDup(Template->getNameAsString());
4152*67e74705SXin Li     }
4153*67e74705SXin Li 
4154*67e74705SXin Li     case CXCursor_NamespaceRef: {
4155*67e74705SXin Li       const NamedDecl *NS = getCursorNamespaceRef(C).first;
4156*67e74705SXin Li       assert(NS && "Missing namespace decl");
4157*67e74705SXin Li 
4158*67e74705SXin Li       return cxstring::createDup(NS->getNameAsString());
4159*67e74705SXin Li     }
4160*67e74705SXin Li 
4161*67e74705SXin Li     case CXCursor_MemberRef: {
4162*67e74705SXin Li       const FieldDecl *Field = getCursorMemberRef(C).first;
4163*67e74705SXin Li       assert(Field && "Missing member decl");
4164*67e74705SXin Li 
4165*67e74705SXin Li       return cxstring::createDup(Field->getNameAsString());
4166*67e74705SXin Li     }
4167*67e74705SXin Li 
4168*67e74705SXin Li     case CXCursor_LabelRef: {
4169*67e74705SXin Li       const LabelStmt *Label = getCursorLabelRef(C).first;
4170*67e74705SXin Li       assert(Label && "Missing label");
4171*67e74705SXin Li 
4172*67e74705SXin Li       return cxstring::createRef(Label->getName());
4173*67e74705SXin Li     }
4174*67e74705SXin Li 
4175*67e74705SXin Li     case CXCursor_OverloadedDeclRef: {
4176*67e74705SXin Li       OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4177*67e74705SXin Li       if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4178*67e74705SXin Li         if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
4179*67e74705SXin Li           return cxstring::createDup(ND->getNameAsString());
4180*67e74705SXin Li         return cxstring::createEmpty();
4181*67e74705SXin Li       }
4182*67e74705SXin Li       if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
4183*67e74705SXin Li         return cxstring::createDup(E->getName().getAsString());
4184*67e74705SXin Li       OverloadedTemplateStorage *Ovl
4185*67e74705SXin Li         = Storage.get<OverloadedTemplateStorage*>();
4186*67e74705SXin Li       if (Ovl->size() == 0)
4187*67e74705SXin Li         return cxstring::createEmpty();
4188*67e74705SXin Li       return cxstring::createDup((*Ovl->begin())->getNameAsString());
4189*67e74705SXin Li     }
4190*67e74705SXin Li 
4191*67e74705SXin Li     case CXCursor_VariableRef: {
4192*67e74705SXin Li       const VarDecl *Var = getCursorVariableRef(C).first;
4193*67e74705SXin Li       assert(Var && "Missing variable decl");
4194*67e74705SXin Li 
4195*67e74705SXin Li       return cxstring::createDup(Var->getNameAsString());
4196*67e74705SXin Li     }
4197*67e74705SXin Li 
4198*67e74705SXin Li     default:
4199*67e74705SXin Li       return cxstring::createRef("<not implemented>");
4200*67e74705SXin Li     }
4201*67e74705SXin Li   }
4202*67e74705SXin Li 
4203*67e74705SXin Li   if (clang_isExpression(C.kind)) {
4204*67e74705SXin Li     const Expr *E = getCursorExpr(C);
4205*67e74705SXin Li 
4206*67e74705SXin Li     if (C.kind == CXCursor_ObjCStringLiteral ||
4207*67e74705SXin Li         C.kind == CXCursor_StringLiteral) {
4208*67e74705SXin Li       const StringLiteral *SLit;
4209*67e74705SXin Li       if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4210*67e74705SXin Li         SLit = OSL->getString();
4211*67e74705SXin Li       } else {
4212*67e74705SXin Li         SLit = cast<StringLiteral>(E);
4213*67e74705SXin Li       }
4214*67e74705SXin Li       SmallString<256> Buf;
4215*67e74705SXin Li       llvm::raw_svector_ostream OS(Buf);
4216*67e74705SXin Li       SLit->outputString(OS);
4217*67e74705SXin Li       return cxstring::createDup(OS.str());
4218*67e74705SXin Li     }
4219*67e74705SXin Li 
4220*67e74705SXin Li     const Decl *D = getDeclFromExpr(getCursorExpr(C));
4221*67e74705SXin Li     if (D)
4222*67e74705SXin Li       return getDeclSpelling(D);
4223*67e74705SXin Li     return cxstring::createEmpty();
4224*67e74705SXin Li   }
4225*67e74705SXin Li 
4226*67e74705SXin Li   if (clang_isStatement(C.kind)) {
4227*67e74705SXin Li     const Stmt *S = getCursorStmt(C);
4228*67e74705SXin Li     if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
4229*67e74705SXin Li       return cxstring::createRef(Label->getName());
4230*67e74705SXin Li 
4231*67e74705SXin Li     return cxstring::createEmpty();
4232*67e74705SXin Li   }
4233*67e74705SXin Li 
4234*67e74705SXin Li   if (C.kind == CXCursor_MacroExpansion)
4235*67e74705SXin Li     return cxstring::createRef(getCursorMacroExpansion(C).getName()
4236*67e74705SXin Li                                                            ->getNameStart());
4237*67e74705SXin Li 
4238*67e74705SXin Li   if (C.kind == CXCursor_MacroDefinition)
4239*67e74705SXin Li     return cxstring::createRef(getCursorMacroDefinition(C)->getName()
4240*67e74705SXin Li                                                            ->getNameStart());
4241*67e74705SXin Li 
4242*67e74705SXin Li   if (C.kind == CXCursor_InclusionDirective)
4243*67e74705SXin Li     return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
4244*67e74705SXin Li 
4245*67e74705SXin Li   if (clang_isDeclaration(C.kind))
4246*67e74705SXin Li     return getDeclSpelling(getCursorDecl(C));
4247*67e74705SXin Li 
4248*67e74705SXin Li   if (C.kind == CXCursor_AnnotateAttr) {
4249*67e74705SXin Li     const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
4250*67e74705SXin Li     return cxstring::createDup(AA->getAnnotation());
4251*67e74705SXin Li   }
4252*67e74705SXin Li 
4253*67e74705SXin Li   if (C.kind == CXCursor_AsmLabelAttr) {
4254*67e74705SXin Li     const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
4255*67e74705SXin Li     return cxstring::createDup(AA->getLabel());
4256*67e74705SXin Li   }
4257*67e74705SXin Li 
4258*67e74705SXin Li   if (C.kind == CXCursor_PackedAttr) {
4259*67e74705SXin Li     return cxstring::createRef("packed");
4260*67e74705SXin Li   }
4261*67e74705SXin Li 
4262*67e74705SXin Li   if (C.kind == CXCursor_VisibilityAttr) {
4263*67e74705SXin Li     const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4264*67e74705SXin Li     switch (AA->getVisibility()) {
4265*67e74705SXin Li     case VisibilityAttr::VisibilityType::Default:
4266*67e74705SXin Li       return cxstring::createRef("default");
4267*67e74705SXin Li     case VisibilityAttr::VisibilityType::Hidden:
4268*67e74705SXin Li       return cxstring::createRef("hidden");
4269*67e74705SXin Li     case VisibilityAttr::VisibilityType::Protected:
4270*67e74705SXin Li       return cxstring::createRef("protected");
4271*67e74705SXin Li     }
4272*67e74705SXin Li     llvm_unreachable("unknown visibility type");
4273*67e74705SXin Li   }
4274*67e74705SXin Li 
4275*67e74705SXin Li   return cxstring::createEmpty();
4276*67e74705SXin Li }
4277*67e74705SXin Li 
clang_Cursor_getSpellingNameRange(CXCursor C,unsigned pieceIndex,unsigned options)4278*67e74705SXin Li CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
4279*67e74705SXin Li                                                 unsigned pieceIndex,
4280*67e74705SXin Li                                                 unsigned options) {
4281*67e74705SXin Li   if (clang_Cursor_isNull(C))
4282*67e74705SXin Li     return clang_getNullRange();
4283*67e74705SXin Li 
4284*67e74705SXin Li   ASTContext &Ctx = getCursorContext(C);
4285*67e74705SXin Li 
4286*67e74705SXin Li   if (clang_isStatement(C.kind)) {
4287*67e74705SXin Li     const Stmt *S = getCursorStmt(C);
4288*67e74705SXin Li     if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
4289*67e74705SXin Li       if (pieceIndex > 0)
4290*67e74705SXin Li         return clang_getNullRange();
4291*67e74705SXin Li       return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4292*67e74705SXin Li     }
4293*67e74705SXin Li 
4294*67e74705SXin Li     return clang_getNullRange();
4295*67e74705SXin Li   }
4296*67e74705SXin Li 
4297*67e74705SXin Li   if (C.kind == CXCursor_ObjCMessageExpr) {
4298*67e74705SXin Li     if (const ObjCMessageExpr *
4299*67e74705SXin Li           ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
4300*67e74705SXin Li       if (pieceIndex >= ME->getNumSelectorLocs())
4301*67e74705SXin Li         return clang_getNullRange();
4302*67e74705SXin Li       return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4303*67e74705SXin Li     }
4304*67e74705SXin Li   }
4305*67e74705SXin Li 
4306*67e74705SXin Li   if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4307*67e74705SXin Li       C.kind == CXCursor_ObjCClassMethodDecl) {
4308*67e74705SXin Li     if (const ObjCMethodDecl *
4309*67e74705SXin Li           MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
4310*67e74705SXin Li       if (pieceIndex >= MD->getNumSelectorLocs())
4311*67e74705SXin Li         return clang_getNullRange();
4312*67e74705SXin Li       return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4313*67e74705SXin Li     }
4314*67e74705SXin Li   }
4315*67e74705SXin Li 
4316*67e74705SXin Li   if (C.kind == CXCursor_ObjCCategoryDecl ||
4317*67e74705SXin Li       C.kind == CXCursor_ObjCCategoryImplDecl) {
4318*67e74705SXin Li     if (pieceIndex > 0)
4319*67e74705SXin Li       return clang_getNullRange();
4320*67e74705SXin Li     if (const ObjCCategoryDecl *
4321*67e74705SXin Li           CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
4322*67e74705SXin Li       return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
4323*67e74705SXin Li     if (const ObjCCategoryImplDecl *
4324*67e74705SXin Li           CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
4325*67e74705SXin Li       return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4326*67e74705SXin Li   }
4327*67e74705SXin Li 
4328*67e74705SXin Li   if (C.kind == CXCursor_ModuleImportDecl) {
4329*67e74705SXin Li     if (pieceIndex > 0)
4330*67e74705SXin Li       return clang_getNullRange();
4331*67e74705SXin Li     if (const ImportDecl *ImportD =
4332*67e74705SXin Li             dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
4333*67e74705SXin Li       ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4334*67e74705SXin Li       if (!Locs.empty())
4335*67e74705SXin Li         return cxloc::translateSourceRange(Ctx,
4336*67e74705SXin Li                                          SourceRange(Locs.front(), Locs.back()));
4337*67e74705SXin Li     }
4338*67e74705SXin Li     return clang_getNullRange();
4339*67e74705SXin Li   }
4340*67e74705SXin Li 
4341*67e74705SXin Li   if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
4342*67e74705SXin Li       C.kind == CXCursor_ConversionFunction) {
4343*67e74705SXin Li     if (pieceIndex > 0)
4344*67e74705SXin Li       return clang_getNullRange();
4345*67e74705SXin Li     if (const FunctionDecl *FD =
4346*67e74705SXin Li             dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4347*67e74705SXin Li       DeclarationNameInfo FunctionName = FD->getNameInfo();
4348*67e74705SXin Li       return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4349*67e74705SXin Li     }
4350*67e74705SXin Li     return clang_getNullRange();
4351*67e74705SXin Li   }
4352*67e74705SXin Li 
4353*67e74705SXin Li   // FIXME: A CXCursor_InclusionDirective should give the location of the
4354*67e74705SXin Li   // filename, but we don't keep track of this.
4355*67e74705SXin Li 
4356*67e74705SXin Li   // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4357*67e74705SXin Li   // but we don't keep track of this.
4358*67e74705SXin Li 
4359*67e74705SXin Li   // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4360*67e74705SXin Li   // but we don't keep track of this.
4361*67e74705SXin Li 
4362*67e74705SXin Li   // Default handling, give the location of the cursor.
4363*67e74705SXin Li 
4364*67e74705SXin Li   if (pieceIndex > 0)
4365*67e74705SXin Li     return clang_getNullRange();
4366*67e74705SXin Li 
4367*67e74705SXin Li   CXSourceLocation CXLoc = clang_getCursorLocation(C);
4368*67e74705SXin Li   SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4369*67e74705SXin Li   return cxloc::translateSourceRange(Ctx, Loc);
4370*67e74705SXin Li }
4371*67e74705SXin Li 
clang_Cursor_getMangling(CXCursor C)4372*67e74705SXin Li CXString clang_Cursor_getMangling(CXCursor C) {
4373*67e74705SXin Li   if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4374*67e74705SXin Li     return cxstring::createEmpty();
4375*67e74705SXin Li 
4376*67e74705SXin Li   // Mangling only works for functions and variables.
4377*67e74705SXin Li   const Decl *D = getCursorDecl(C);
4378*67e74705SXin Li   if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4379*67e74705SXin Li     return cxstring::createEmpty();
4380*67e74705SXin Li 
4381*67e74705SXin Li   ASTContext &Ctx = D->getASTContext();
4382*67e74705SXin Li   index::CodegenNameGenerator CGNameGen(Ctx);
4383*67e74705SXin Li   return cxstring::createDup(CGNameGen.getName(D));
4384*67e74705SXin Li }
4385*67e74705SXin Li 
clang_Cursor_getCXXManglings(CXCursor C)4386*67e74705SXin Li CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4387*67e74705SXin Li   if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4388*67e74705SXin Li     return nullptr;
4389*67e74705SXin Li 
4390*67e74705SXin Li   const Decl *D = getCursorDecl(C);
4391*67e74705SXin Li   if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4392*67e74705SXin Li     return nullptr;
4393*67e74705SXin Li 
4394*67e74705SXin Li   ASTContext &Ctx = D->getASTContext();
4395*67e74705SXin Li   index::CodegenNameGenerator CGNameGen(Ctx);
4396*67e74705SXin Li   std::vector<std::string> Manglings = CGNameGen.getAllManglings(D);
4397*67e74705SXin Li   return cxstring::createSet(Manglings);
4398*67e74705SXin Li }
4399*67e74705SXin Li 
clang_getCursorDisplayName(CXCursor C)4400*67e74705SXin Li CXString clang_getCursorDisplayName(CXCursor C) {
4401*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
4402*67e74705SXin Li     return clang_getCursorSpelling(C);
4403*67e74705SXin Li 
4404*67e74705SXin Li   const Decl *D = getCursorDecl(C);
4405*67e74705SXin Li   if (!D)
4406*67e74705SXin Li     return cxstring::createEmpty();
4407*67e74705SXin Li 
4408*67e74705SXin Li   PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
4409*67e74705SXin Li   if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
4410*67e74705SXin Li     D = FunTmpl->getTemplatedDecl();
4411*67e74705SXin Li 
4412*67e74705SXin Li   if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
4413*67e74705SXin Li     SmallString<64> Str;
4414*67e74705SXin Li     llvm::raw_svector_ostream OS(Str);
4415*67e74705SXin Li     OS << *Function;
4416*67e74705SXin Li     if (Function->getPrimaryTemplate())
4417*67e74705SXin Li       OS << "<>";
4418*67e74705SXin Li     OS << "(";
4419*67e74705SXin Li     for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
4420*67e74705SXin Li       if (I)
4421*67e74705SXin Li         OS << ", ";
4422*67e74705SXin Li       OS << Function->getParamDecl(I)->getType().getAsString(Policy);
4423*67e74705SXin Li     }
4424*67e74705SXin Li 
4425*67e74705SXin Li     if (Function->isVariadic()) {
4426*67e74705SXin Li       if (Function->getNumParams())
4427*67e74705SXin Li         OS << ", ";
4428*67e74705SXin Li       OS << "...";
4429*67e74705SXin Li     }
4430*67e74705SXin Li     OS << ")";
4431*67e74705SXin Li     return cxstring::createDup(OS.str());
4432*67e74705SXin Li   }
4433*67e74705SXin Li 
4434*67e74705SXin Li   if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
4435*67e74705SXin Li     SmallString<64> Str;
4436*67e74705SXin Li     llvm::raw_svector_ostream OS(Str);
4437*67e74705SXin Li     OS << *ClassTemplate;
4438*67e74705SXin Li     OS << "<";
4439*67e74705SXin Li     TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
4440*67e74705SXin Li     for (unsigned I = 0, N = Params->size(); I != N; ++I) {
4441*67e74705SXin Li       if (I)
4442*67e74705SXin Li         OS << ", ";
4443*67e74705SXin Li 
4444*67e74705SXin Li       NamedDecl *Param = Params->getParam(I);
4445*67e74705SXin Li       if (Param->getIdentifier()) {
4446*67e74705SXin Li         OS << Param->getIdentifier()->getName();
4447*67e74705SXin Li         continue;
4448*67e74705SXin Li       }
4449*67e74705SXin Li 
4450*67e74705SXin Li       // There is no parameter name, which makes this tricky. Try to come up
4451*67e74705SXin Li       // with something useful that isn't too long.
4452*67e74705SXin Li       if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
4453*67e74705SXin Li         OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
4454*67e74705SXin Li       else if (NonTypeTemplateParmDecl *NTTP
4455*67e74705SXin Li                                     = dyn_cast<NonTypeTemplateParmDecl>(Param))
4456*67e74705SXin Li         OS << NTTP->getType().getAsString(Policy);
4457*67e74705SXin Li       else
4458*67e74705SXin Li         OS << "template<...> class";
4459*67e74705SXin Li     }
4460*67e74705SXin Li 
4461*67e74705SXin Li     OS << ">";
4462*67e74705SXin Li     return cxstring::createDup(OS.str());
4463*67e74705SXin Li   }
4464*67e74705SXin Li 
4465*67e74705SXin Li   if (const ClassTemplateSpecializationDecl *ClassSpec
4466*67e74705SXin Li                               = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
4467*67e74705SXin Li     // If the type was explicitly written, use that.
4468*67e74705SXin Li     if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
4469*67e74705SXin Li       return cxstring::createDup(TSInfo->getType().getAsString(Policy));
4470*67e74705SXin Li 
4471*67e74705SXin Li     SmallString<128> Str;
4472*67e74705SXin Li     llvm::raw_svector_ostream OS(Str);
4473*67e74705SXin Li     OS << *ClassSpec;
4474*67e74705SXin Li     TemplateSpecializationType::PrintTemplateArgumentList(
4475*67e74705SXin Li         OS, ClassSpec->getTemplateArgs().asArray(), Policy);
4476*67e74705SXin Li     return cxstring::createDup(OS.str());
4477*67e74705SXin Li   }
4478*67e74705SXin Li 
4479*67e74705SXin Li   return clang_getCursorSpelling(C);
4480*67e74705SXin Li }
4481*67e74705SXin Li 
clang_getCursorKindSpelling(enum CXCursorKind Kind)4482*67e74705SXin Li CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
4483*67e74705SXin Li   switch (Kind) {
4484*67e74705SXin Li   case CXCursor_FunctionDecl:
4485*67e74705SXin Li       return cxstring::createRef("FunctionDecl");
4486*67e74705SXin Li   case CXCursor_TypedefDecl:
4487*67e74705SXin Li       return cxstring::createRef("TypedefDecl");
4488*67e74705SXin Li   case CXCursor_EnumDecl:
4489*67e74705SXin Li       return cxstring::createRef("EnumDecl");
4490*67e74705SXin Li   case CXCursor_EnumConstantDecl:
4491*67e74705SXin Li       return cxstring::createRef("EnumConstantDecl");
4492*67e74705SXin Li   case CXCursor_StructDecl:
4493*67e74705SXin Li       return cxstring::createRef("StructDecl");
4494*67e74705SXin Li   case CXCursor_UnionDecl:
4495*67e74705SXin Li       return cxstring::createRef("UnionDecl");
4496*67e74705SXin Li   case CXCursor_ClassDecl:
4497*67e74705SXin Li       return cxstring::createRef("ClassDecl");
4498*67e74705SXin Li   case CXCursor_FieldDecl:
4499*67e74705SXin Li       return cxstring::createRef("FieldDecl");
4500*67e74705SXin Li   case CXCursor_VarDecl:
4501*67e74705SXin Li       return cxstring::createRef("VarDecl");
4502*67e74705SXin Li   case CXCursor_ParmDecl:
4503*67e74705SXin Li       return cxstring::createRef("ParmDecl");
4504*67e74705SXin Li   case CXCursor_ObjCInterfaceDecl:
4505*67e74705SXin Li       return cxstring::createRef("ObjCInterfaceDecl");
4506*67e74705SXin Li   case CXCursor_ObjCCategoryDecl:
4507*67e74705SXin Li       return cxstring::createRef("ObjCCategoryDecl");
4508*67e74705SXin Li   case CXCursor_ObjCProtocolDecl:
4509*67e74705SXin Li       return cxstring::createRef("ObjCProtocolDecl");
4510*67e74705SXin Li   case CXCursor_ObjCPropertyDecl:
4511*67e74705SXin Li       return cxstring::createRef("ObjCPropertyDecl");
4512*67e74705SXin Li   case CXCursor_ObjCIvarDecl:
4513*67e74705SXin Li       return cxstring::createRef("ObjCIvarDecl");
4514*67e74705SXin Li   case CXCursor_ObjCInstanceMethodDecl:
4515*67e74705SXin Li       return cxstring::createRef("ObjCInstanceMethodDecl");
4516*67e74705SXin Li   case CXCursor_ObjCClassMethodDecl:
4517*67e74705SXin Li       return cxstring::createRef("ObjCClassMethodDecl");
4518*67e74705SXin Li   case CXCursor_ObjCImplementationDecl:
4519*67e74705SXin Li       return cxstring::createRef("ObjCImplementationDecl");
4520*67e74705SXin Li   case CXCursor_ObjCCategoryImplDecl:
4521*67e74705SXin Li       return cxstring::createRef("ObjCCategoryImplDecl");
4522*67e74705SXin Li   case CXCursor_CXXMethod:
4523*67e74705SXin Li       return cxstring::createRef("CXXMethod");
4524*67e74705SXin Li   case CXCursor_UnexposedDecl:
4525*67e74705SXin Li       return cxstring::createRef("UnexposedDecl");
4526*67e74705SXin Li   case CXCursor_ObjCSuperClassRef:
4527*67e74705SXin Li       return cxstring::createRef("ObjCSuperClassRef");
4528*67e74705SXin Li   case CXCursor_ObjCProtocolRef:
4529*67e74705SXin Li       return cxstring::createRef("ObjCProtocolRef");
4530*67e74705SXin Li   case CXCursor_ObjCClassRef:
4531*67e74705SXin Li       return cxstring::createRef("ObjCClassRef");
4532*67e74705SXin Li   case CXCursor_TypeRef:
4533*67e74705SXin Li       return cxstring::createRef("TypeRef");
4534*67e74705SXin Li   case CXCursor_TemplateRef:
4535*67e74705SXin Li       return cxstring::createRef("TemplateRef");
4536*67e74705SXin Li   case CXCursor_NamespaceRef:
4537*67e74705SXin Li     return cxstring::createRef("NamespaceRef");
4538*67e74705SXin Li   case CXCursor_MemberRef:
4539*67e74705SXin Li     return cxstring::createRef("MemberRef");
4540*67e74705SXin Li   case CXCursor_LabelRef:
4541*67e74705SXin Li     return cxstring::createRef("LabelRef");
4542*67e74705SXin Li   case CXCursor_OverloadedDeclRef:
4543*67e74705SXin Li     return cxstring::createRef("OverloadedDeclRef");
4544*67e74705SXin Li   case CXCursor_VariableRef:
4545*67e74705SXin Li     return cxstring::createRef("VariableRef");
4546*67e74705SXin Li   case CXCursor_IntegerLiteral:
4547*67e74705SXin Li       return cxstring::createRef("IntegerLiteral");
4548*67e74705SXin Li   case CXCursor_FloatingLiteral:
4549*67e74705SXin Li       return cxstring::createRef("FloatingLiteral");
4550*67e74705SXin Li   case CXCursor_ImaginaryLiteral:
4551*67e74705SXin Li       return cxstring::createRef("ImaginaryLiteral");
4552*67e74705SXin Li   case CXCursor_StringLiteral:
4553*67e74705SXin Li       return cxstring::createRef("StringLiteral");
4554*67e74705SXin Li   case CXCursor_CharacterLiteral:
4555*67e74705SXin Li       return cxstring::createRef("CharacterLiteral");
4556*67e74705SXin Li   case CXCursor_ParenExpr:
4557*67e74705SXin Li       return cxstring::createRef("ParenExpr");
4558*67e74705SXin Li   case CXCursor_UnaryOperator:
4559*67e74705SXin Li       return cxstring::createRef("UnaryOperator");
4560*67e74705SXin Li   case CXCursor_ArraySubscriptExpr:
4561*67e74705SXin Li       return cxstring::createRef("ArraySubscriptExpr");
4562*67e74705SXin Li   case CXCursor_OMPArraySectionExpr:
4563*67e74705SXin Li       return cxstring::createRef("OMPArraySectionExpr");
4564*67e74705SXin Li   case CXCursor_BinaryOperator:
4565*67e74705SXin Li       return cxstring::createRef("BinaryOperator");
4566*67e74705SXin Li   case CXCursor_CompoundAssignOperator:
4567*67e74705SXin Li       return cxstring::createRef("CompoundAssignOperator");
4568*67e74705SXin Li   case CXCursor_ConditionalOperator:
4569*67e74705SXin Li       return cxstring::createRef("ConditionalOperator");
4570*67e74705SXin Li   case CXCursor_CStyleCastExpr:
4571*67e74705SXin Li       return cxstring::createRef("CStyleCastExpr");
4572*67e74705SXin Li   case CXCursor_CompoundLiteralExpr:
4573*67e74705SXin Li       return cxstring::createRef("CompoundLiteralExpr");
4574*67e74705SXin Li   case CXCursor_InitListExpr:
4575*67e74705SXin Li       return cxstring::createRef("InitListExpr");
4576*67e74705SXin Li   case CXCursor_AddrLabelExpr:
4577*67e74705SXin Li       return cxstring::createRef("AddrLabelExpr");
4578*67e74705SXin Li   case CXCursor_StmtExpr:
4579*67e74705SXin Li       return cxstring::createRef("StmtExpr");
4580*67e74705SXin Li   case CXCursor_GenericSelectionExpr:
4581*67e74705SXin Li       return cxstring::createRef("GenericSelectionExpr");
4582*67e74705SXin Li   case CXCursor_GNUNullExpr:
4583*67e74705SXin Li       return cxstring::createRef("GNUNullExpr");
4584*67e74705SXin Li   case CXCursor_CXXStaticCastExpr:
4585*67e74705SXin Li       return cxstring::createRef("CXXStaticCastExpr");
4586*67e74705SXin Li   case CXCursor_CXXDynamicCastExpr:
4587*67e74705SXin Li       return cxstring::createRef("CXXDynamicCastExpr");
4588*67e74705SXin Li   case CXCursor_CXXReinterpretCastExpr:
4589*67e74705SXin Li       return cxstring::createRef("CXXReinterpretCastExpr");
4590*67e74705SXin Li   case CXCursor_CXXConstCastExpr:
4591*67e74705SXin Li       return cxstring::createRef("CXXConstCastExpr");
4592*67e74705SXin Li   case CXCursor_CXXFunctionalCastExpr:
4593*67e74705SXin Li       return cxstring::createRef("CXXFunctionalCastExpr");
4594*67e74705SXin Li   case CXCursor_CXXTypeidExpr:
4595*67e74705SXin Li       return cxstring::createRef("CXXTypeidExpr");
4596*67e74705SXin Li   case CXCursor_CXXBoolLiteralExpr:
4597*67e74705SXin Li       return cxstring::createRef("CXXBoolLiteralExpr");
4598*67e74705SXin Li   case CXCursor_CXXNullPtrLiteralExpr:
4599*67e74705SXin Li       return cxstring::createRef("CXXNullPtrLiteralExpr");
4600*67e74705SXin Li   case CXCursor_CXXThisExpr:
4601*67e74705SXin Li       return cxstring::createRef("CXXThisExpr");
4602*67e74705SXin Li   case CXCursor_CXXThrowExpr:
4603*67e74705SXin Li       return cxstring::createRef("CXXThrowExpr");
4604*67e74705SXin Li   case CXCursor_CXXNewExpr:
4605*67e74705SXin Li       return cxstring::createRef("CXXNewExpr");
4606*67e74705SXin Li   case CXCursor_CXXDeleteExpr:
4607*67e74705SXin Li       return cxstring::createRef("CXXDeleteExpr");
4608*67e74705SXin Li   case CXCursor_UnaryExpr:
4609*67e74705SXin Li       return cxstring::createRef("UnaryExpr");
4610*67e74705SXin Li   case CXCursor_ObjCStringLiteral:
4611*67e74705SXin Li       return cxstring::createRef("ObjCStringLiteral");
4612*67e74705SXin Li   case CXCursor_ObjCBoolLiteralExpr:
4613*67e74705SXin Li       return cxstring::createRef("ObjCBoolLiteralExpr");
4614*67e74705SXin Li   case CXCursor_ObjCSelfExpr:
4615*67e74705SXin Li       return cxstring::createRef("ObjCSelfExpr");
4616*67e74705SXin Li   case CXCursor_ObjCEncodeExpr:
4617*67e74705SXin Li       return cxstring::createRef("ObjCEncodeExpr");
4618*67e74705SXin Li   case CXCursor_ObjCSelectorExpr:
4619*67e74705SXin Li       return cxstring::createRef("ObjCSelectorExpr");
4620*67e74705SXin Li   case CXCursor_ObjCProtocolExpr:
4621*67e74705SXin Li       return cxstring::createRef("ObjCProtocolExpr");
4622*67e74705SXin Li   case CXCursor_ObjCBridgedCastExpr:
4623*67e74705SXin Li       return cxstring::createRef("ObjCBridgedCastExpr");
4624*67e74705SXin Li   case CXCursor_BlockExpr:
4625*67e74705SXin Li       return cxstring::createRef("BlockExpr");
4626*67e74705SXin Li   case CXCursor_PackExpansionExpr:
4627*67e74705SXin Li       return cxstring::createRef("PackExpansionExpr");
4628*67e74705SXin Li   case CXCursor_SizeOfPackExpr:
4629*67e74705SXin Li       return cxstring::createRef("SizeOfPackExpr");
4630*67e74705SXin Li   case CXCursor_LambdaExpr:
4631*67e74705SXin Li     return cxstring::createRef("LambdaExpr");
4632*67e74705SXin Li   case CXCursor_UnexposedExpr:
4633*67e74705SXin Li       return cxstring::createRef("UnexposedExpr");
4634*67e74705SXin Li   case CXCursor_DeclRefExpr:
4635*67e74705SXin Li       return cxstring::createRef("DeclRefExpr");
4636*67e74705SXin Li   case CXCursor_MemberRefExpr:
4637*67e74705SXin Li       return cxstring::createRef("MemberRefExpr");
4638*67e74705SXin Li   case CXCursor_CallExpr:
4639*67e74705SXin Li       return cxstring::createRef("CallExpr");
4640*67e74705SXin Li   case CXCursor_ObjCMessageExpr:
4641*67e74705SXin Li       return cxstring::createRef("ObjCMessageExpr");
4642*67e74705SXin Li   case CXCursor_UnexposedStmt:
4643*67e74705SXin Li       return cxstring::createRef("UnexposedStmt");
4644*67e74705SXin Li   case CXCursor_DeclStmt:
4645*67e74705SXin Li       return cxstring::createRef("DeclStmt");
4646*67e74705SXin Li   case CXCursor_LabelStmt:
4647*67e74705SXin Li       return cxstring::createRef("LabelStmt");
4648*67e74705SXin Li   case CXCursor_CompoundStmt:
4649*67e74705SXin Li       return cxstring::createRef("CompoundStmt");
4650*67e74705SXin Li   case CXCursor_CaseStmt:
4651*67e74705SXin Li       return cxstring::createRef("CaseStmt");
4652*67e74705SXin Li   case CXCursor_DefaultStmt:
4653*67e74705SXin Li       return cxstring::createRef("DefaultStmt");
4654*67e74705SXin Li   case CXCursor_IfStmt:
4655*67e74705SXin Li       return cxstring::createRef("IfStmt");
4656*67e74705SXin Li   case CXCursor_SwitchStmt:
4657*67e74705SXin Li       return cxstring::createRef("SwitchStmt");
4658*67e74705SXin Li   case CXCursor_WhileStmt:
4659*67e74705SXin Li       return cxstring::createRef("WhileStmt");
4660*67e74705SXin Li   case CXCursor_DoStmt:
4661*67e74705SXin Li       return cxstring::createRef("DoStmt");
4662*67e74705SXin Li   case CXCursor_ForStmt:
4663*67e74705SXin Li       return cxstring::createRef("ForStmt");
4664*67e74705SXin Li   case CXCursor_GotoStmt:
4665*67e74705SXin Li       return cxstring::createRef("GotoStmt");
4666*67e74705SXin Li   case CXCursor_IndirectGotoStmt:
4667*67e74705SXin Li       return cxstring::createRef("IndirectGotoStmt");
4668*67e74705SXin Li   case CXCursor_ContinueStmt:
4669*67e74705SXin Li       return cxstring::createRef("ContinueStmt");
4670*67e74705SXin Li   case CXCursor_BreakStmt:
4671*67e74705SXin Li       return cxstring::createRef("BreakStmt");
4672*67e74705SXin Li   case CXCursor_ReturnStmt:
4673*67e74705SXin Li       return cxstring::createRef("ReturnStmt");
4674*67e74705SXin Li   case CXCursor_GCCAsmStmt:
4675*67e74705SXin Li       return cxstring::createRef("GCCAsmStmt");
4676*67e74705SXin Li   case CXCursor_MSAsmStmt:
4677*67e74705SXin Li       return cxstring::createRef("MSAsmStmt");
4678*67e74705SXin Li   case CXCursor_ObjCAtTryStmt:
4679*67e74705SXin Li       return cxstring::createRef("ObjCAtTryStmt");
4680*67e74705SXin Li   case CXCursor_ObjCAtCatchStmt:
4681*67e74705SXin Li       return cxstring::createRef("ObjCAtCatchStmt");
4682*67e74705SXin Li   case CXCursor_ObjCAtFinallyStmt:
4683*67e74705SXin Li       return cxstring::createRef("ObjCAtFinallyStmt");
4684*67e74705SXin Li   case CXCursor_ObjCAtThrowStmt:
4685*67e74705SXin Li       return cxstring::createRef("ObjCAtThrowStmt");
4686*67e74705SXin Li   case CXCursor_ObjCAtSynchronizedStmt:
4687*67e74705SXin Li       return cxstring::createRef("ObjCAtSynchronizedStmt");
4688*67e74705SXin Li   case CXCursor_ObjCAutoreleasePoolStmt:
4689*67e74705SXin Li       return cxstring::createRef("ObjCAutoreleasePoolStmt");
4690*67e74705SXin Li   case CXCursor_ObjCForCollectionStmt:
4691*67e74705SXin Li       return cxstring::createRef("ObjCForCollectionStmt");
4692*67e74705SXin Li   case CXCursor_CXXCatchStmt:
4693*67e74705SXin Li       return cxstring::createRef("CXXCatchStmt");
4694*67e74705SXin Li   case CXCursor_CXXTryStmt:
4695*67e74705SXin Li       return cxstring::createRef("CXXTryStmt");
4696*67e74705SXin Li   case CXCursor_CXXForRangeStmt:
4697*67e74705SXin Li       return cxstring::createRef("CXXForRangeStmt");
4698*67e74705SXin Li   case CXCursor_SEHTryStmt:
4699*67e74705SXin Li       return cxstring::createRef("SEHTryStmt");
4700*67e74705SXin Li   case CXCursor_SEHExceptStmt:
4701*67e74705SXin Li       return cxstring::createRef("SEHExceptStmt");
4702*67e74705SXin Li   case CXCursor_SEHFinallyStmt:
4703*67e74705SXin Li       return cxstring::createRef("SEHFinallyStmt");
4704*67e74705SXin Li   case CXCursor_SEHLeaveStmt:
4705*67e74705SXin Li       return cxstring::createRef("SEHLeaveStmt");
4706*67e74705SXin Li   case CXCursor_NullStmt:
4707*67e74705SXin Li       return cxstring::createRef("NullStmt");
4708*67e74705SXin Li   case CXCursor_InvalidFile:
4709*67e74705SXin Li       return cxstring::createRef("InvalidFile");
4710*67e74705SXin Li   case CXCursor_InvalidCode:
4711*67e74705SXin Li     return cxstring::createRef("InvalidCode");
4712*67e74705SXin Li   case CXCursor_NoDeclFound:
4713*67e74705SXin Li       return cxstring::createRef("NoDeclFound");
4714*67e74705SXin Li   case CXCursor_NotImplemented:
4715*67e74705SXin Li       return cxstring::createRef("NotImplemented");
4716*67e74705SXin Li   case CXCursor_TranslationUnit:
4717*67e74705SXin Li       return cxstring::createRef("TranslationUnit");
4718*67e74705SXin Li   case CXCursor_UnexposedAttr:
4719*67e74705SXin Li       return cxstring::createRef("UnexposedAttr");
4720*67e74705SXin Li   case CXCursor_IBActionAttr:
4721*67e74705SXin Li       return cxstring::createRef("attribute(ibaction)");
4722*67e74705SXin Li   case CXCursor_IBOutletAttr:
4723*67e74705SXin Li      return cxstring::createRef("attribute(iboutlet)");
4724*67e74705SXin Li   case CXCursor_IBOutletCollectionAttr:
4725*67e74705SXin Li       return cxstring::createRef("attribute(iboutletcollection)");
4726*67e74705SXin Li   case CXCursor_CXXFinalAttr:
4727*67e74705SXin Li       return cxstring::createRef("attribute(final)");
4728*67e74705SXin Li   case CXCursor_CXXOverrideAttr:
4729*67e74705SXin Li       return cxstring::createRef("attribute(override)");
4730*67e74705SXin Li   case CXCursor_AnnotateAttr:
4731*67e74705SXin Li     return cxstring::createRef("attribute(annotate)");
4732*67e74705SXin Li   case CXCursor_AsmLabelAttr:
4733*67e74705SXin Li     return cxstring::createRef("asm label");
4734*67e74705SXin Li   case CXCursor_PackedAttr:
4735*67e74705SXin Li     return cxstring::createRef("attribute(packed)");
4736*67e74705SXin Li   case CXCursor_PureAttr:
4737*67e74705SXin Li     return cxstring::createRef("attribute(pure)");
4738*67e74705SXin Li   case CXCursor_ConstAttr:
4739*67e74705SXin Li     return cxstring::createRef("attribute(const)");
4740*67e74705SXin Li   case CXCursor_NoDuplicateAttr:
4741*67e74705SXin Li     return cxstring::createRef("attribute(noduplicate)");
4742*67e74705SXin Li   case CXCursor_CUDAConstantAttr:
4743*67e74705SXin Li     return cxstring::createRef("attribute(constant)");
4744*67e74705SXin Li   case CXCursor_CUDADeviceAttr:
4745*67e74705SXin Li     return cxstring::createRef("attribute(device)");
4746*67e74705SXin Li   case CXCursor_CUDAGlobalAttr:
4747*67e74705SXin Li     return cxstring::createRef("attribute(global)");
4748*67e74705SXin Li   case CXCursor_CUDAHostAttr:
4749*67e74705SXin Li     return cxstring::createRef("attribute(host)");
4750*67e74705SXin Li   case CXCursor_CUDASharedAttr:
4751*67e74705SXin Li     return cxstring::createRef("attribute(shared)");
4752*67e74705SXin Li   case CXCursor_VisibilityAttr:
4753*67e74705SXin Li     return cxstring::createRef("attribute(visibility)");
4754*67e74705SXin Li   case CXCursor_DLLExport:
4755*67e74705SXin Li     return cxstring::createRef("attribute(dllexport)");
4756*67e74705SXin Li   case CXCursor_DLLImport:
4757*67e74705SXin Li     return cxstring::createRef("attribute(dllimport)");
4758*67e74705SXin Li   case CXCursor_PreprocessingDirective:
4759*67e74705SXin Li     return cxstring::createRef("preprocessing directive");
4760*67e74705SXin Li   case CXCursor_MacroDefinition:
4761*67e74705SXin Li     return cxstring::createRef("macro definition");
4762*67e74705SXin Li   case CXCursor_MacroExpansion:
4763*67e74705SXin Li     return cxstring::createRef("macro expansion");
4764*67e74705SXin Li   case CXCursor_InclusionDirective:
4765*67e74705SXin Li     return cxstring::createRef("inclusion directive");
4766*67e74705SXin Li   case CXCursor_Namespace:
4767*67e74705SXin Li     return cxstring::createRef("Namespace");
4768*67e74705SXin Li   case CXCursor_LinkageSpec:
4769*67e74705SXin Li     return cxstring::createRef("LinkageSpec");
4770*67e74705SXin Li   case CXCursor_CXXBaseSpecifier:
4771*67e74705SXin Li     return cxstring::createRef("C++ base class specifier");
4772*67e74705SXin Li   case CXCursor_Constructor:
4773*67e74705SXin Li     return cxstring::createRef("CXXConstructor");
4774*67e74705SXin Li   case CXCursor_Destructor:
4775*67e74705SXin Li     return cxstring::createRef("CXXDestructor");
4776*67e74705SXin Li   case CXCursor_ConversionFunction:
4777*67e74705SXin Li     return cxstring::createRef("CXXConversion");
4778*67e74705SXin Li   case CXCursor_TemplateTypeParameter:
4779*67e74705SXin Li     return cxstring::createRef("TemplateTypeParameter");
4780*67e74705SXin Li   case CXCursor_NonTypeTemplateParameter:
4781*67e74705SXin Li     return cxstring::createRef("NonTypeTemplateParameter");
4782*67e74705SXin Li   case CXCursor_TemplateTemplateParameter:
4783*67e74705SXin Li     return cxstring::createRef("TemplateTemplateParameter");
4784*67e74705SXin Li   case CXCursor_FunctionTemplate:
4785*67e74705SXin Li     return cxstring::createRef("FunctionTemplate");
4786*67e74705SXin Li   case CXCursor_ClassTemplate:
4787*67e74705SXin Li     return cxstring::createRef("ClassTemplate");
4788*67e74705SXin Li   case CXCursor_ClassTemplatePartialSpecialization:
4789*67e74705SXin Li     return cxstring::createRef("ClassTemplatePartialSpecialization");
4790*67e74705SXin Li   case CXCursor_NamespaceAlias:
4791*67e74705SXin Li     return cxstring::createRef("NamespaceAlias");
4792*67e74705SXin Li   case CXCursor_UsingDirective:
4793*67e74705SXin Li     return cxstring::createRef("UsingDirective");
4794*67e74705SXin Li   case CXCursor_UsingDeclaration:
4795*67e74705SXin Li     return cxstring::createRef("UsingDeclaration");
4796*67e74705SXin Li   case CXCursor_TypeAliasDecl:
4797*67e74705SXin Li     return cxstring::createRef("TypeAliasDecl");
4798*67e74705SXin Li   case CXCursor_ObjCSynthesizeDecl:
4799*67e74705SXin Li     return cxstring::createRef("ObjCSynthesizeDecl");
4800*67e74705SXin Li   case CXCursor_ObjCDynamicDecl:
4801*67e74705SXin Li     return cxstring::createRef("ObjCDynamicDecl");
4802*67e74705SXin Li   case CXCursor_CXXAccessSpecifier:
4803*67e74705SXin Li     return cxstring::createRef("CXXAccessSpecifier");
4804*67e74705SXin Li   case CXCursor_ModuleImportDecl:
4805*67e74705SXin Li     return cxstring::createRef("ModuleImport");
4806*67e74705SXin Li   case CXCursor_OMPParallelDirective:
4807*67e74705SXin Li     return cxstring::createRef("OMPParallelDirective");
4808*67e74705SXin Li   case CXCursor_OMPSimdDirective:
4809*67e74705SXin Li     return cxstring::createRef("OMPSimdDirective");
4810*67e74705SXin Li   case CXCursor_OMPForDirective:
4811*67e74705SXin Li     return cxstring::createRef("OMPForDirective");
4812*67e74705SXin Li   case CXCursor_OMPForSimdDirective:
4813*67e74705SXin Li     return cxstring::createRef("OMPForSimdDirective");
4814*67e74705SXin Li   case CXCursor_OMPSectionsDirective:
4815*67e74705SXin Li     return cxstring::createRef("OMPSectionsDirective");
4816*67e74705SXin Li   case CXCursor_OMPSectionDirective:
4817*67e74705SXin Li     return cxstring::createRef("OMPSectionDirective");
4818*67e74705SXin Li   case CXCursor_OMPSingleDirective:
4819*67e74705SXin Li     return cxstring::createRef("OMPSingleDirective");
4820*67e74705SXin Li   case CXCursor_OMPMasterDirective:
4821*67e74705SXin Li     return cxstring::createRef("OMPMasterDirective");
4822*67e74705SXin Li   case CXCursor_OMPCriticalDirective:
4823*67e74705SXin Li     return cxstring::createRef("OMPCriticalDirective");
4824*67e74705SXin Li   case CXCursor_OMPParallelForDirective:
4825*67e74705SXin Li     return cxstring::createRef("OMPParallelForDirective");
4826*67e74705SXin Li   case CXCursor_OMPParallelForSimdDirective:
4827*67e74705SXin Li     return cxstring::createRef("OMPParallelForSimdDirective");
4828*67e74705SXin Li   case CXCursor_OMPParallelSectionsDirective:
4829*67e74705SXin Li     return cxstring::createRef("OMPParallelSectionsDirective");
4830*67e74705SXin Li   case CXCursor_OMPTaskDirective:
4831*67e74705SXin Li     return cxstring::createRef("OMPTaskDirective");
4832*67e74705SXin Li   case CXCursor_OMPTaskyieldDirective:
4833*67e74705SXin Li     return cxstring::createRef("OMPTaskyieldDirective");
4834*67e74705SXin Li   case CXCursor_OMPBarrierDirective:
4835*67e74705SXin Li     return cxstring::createRef("OMPBarrierDirective");
4836*67e74705SXin Li   case CXCursor_OMPTaskwaitDirective:
4837*67e74705SXin Li     return cxstring::createRef("OMPTaskwaitDirective");
4838*67e74705SXin Li   case CXCursor_OMPTaskgroupDirective:
4839*67e74705SXin Li     return cxstring::createRef("OMPTaskgroupDirective");
4840*67e74705SXin Li   case CXCursor_OMPFlushDirective:
4841*67e74705SXin Li     return cxstring::createRef("OMPFlushDirective");
4842*67e74705SXin Li   case CXCursor_OMPOrderedDirective:
4843*67e74705SXin Li     return cxstring::createRef("OMPOrderedDirective");
4844*67e74705SXin Li   case CXCursor_OMPAtomicDirective:
4845*67e74705SXin Li     return cxstring::createRef("OMPAtomicDirective");
4846*67e74705SXin Li   case CXCursor_OMPTargetDirective:
4847*67e74705SXin Li     return cxstring::createRef("OMPTargetDirective");
4848*67e74705SXin Li   case CXCursor_OMPTargetDataDirective:
4849*67e74705SXin Li     return cxstring::createRef("OMPTargetDataDirective");
4850*67e74705SXin Li   case CXCursor_OMPTargetEnterDataDirective:
4851*67e74705SXin Li     return cxstring::createRef("OMPTargetEnterDataDirective");
4852*67e74705SXin Li   case CXCursor_OMPTargetExitDataDirective:
4853*67e74705SXin Li     return cxstring::createRef("OMPTargetExitDataDirective");
4854*67e74705SXin Li   case CXCursor_OMPTargetParallelDirective:
4855*67e74705SXin Li     return cxstring::createRef("OMPTargetParallelDirective");
4856*67e74705SXin Li   case CXCursor_OMPTargetParallelForDirective:
4857*67e74705SXin Li     return cxstring::createRef("OMPTargetParallelForDirective");
4858*67e74705SXin Li   case CXCursor_OMPTargetUpdateDirective:
4859*67e74705SXin Li     return cxstring::createRef("OMPTargetUpdateDirective");
4860*67e74705SXin Li   case CXCursor_OMPTeamsDirective:
4861*67e74705SXin Li     return cxstring::createRef("OMPTeamsDirective");
4862*67e74705SXin Li   case CXCursor_OMPCancellationPointDirective:
4863*67e74705SXin Li     return cxstring::createRef("OMPCancellationPointDirective");
4864*67e74705SXin Li   case CXCursor_OMPCancelDirective:
4865*67e74705SXin Li     return cxstring::createRef("OMPCancelDirective");
4866*67e74705SXin Li   case CXCursor_OMPTaskLoopDirective:
4867*67e74705SXin Li     return cxstring::createRef("OMPTaskLoopDirective");
4868*67e74705SXin Li   case CXCursor_OMPTaskLoopSimdDirective:
4869*67e74705SXin Li     return cxstring::createRef("OMPTaskLoopSimdDirective");
4870*67e74705SXin Li   case CXCursor_OMPDistributeDirective:
4871*67e74705SXin Li     return cxstring::createRef("OMPDistributeDirective");
4872*67e74705SXin Li   case CXCursor_OMPDistributeParallelForDirective:
4873*67e74705SXin Li     return cxstring::createRef("OMPDistributeParallelForDirective");
4874*67e74705SXin Li   case CXCursor_OMPDistributeParallelForSimdDirective:
4875*67e74705SXin Li     return cxstring::createRef("OMPDistributeParallelForSimdDirective");
4876*67e74705SXin Li   case CXCursor_OMPDistributeSimdDirective:
4877*67e74705SXin Li     return cxstring::createRef("OMPDistributeSimdDirective");
4878*67e74705SXin Li   case CXCursor_OMPTargetParallelForSimdDirective:
4879*67e74705SXin Li     return cxstring::createRef("OMPTargetParallelForSimdDirective");
4880*67e74705SXin Li   case CXCursor_OverloadCandidate:
4881*67e74705SXin Li       return cxstring::createRef("OverloadCandidate");
4882*67e74705SXin Li   case CXCursor_TypeAliasTemplateDecl:
4883*67e74705SXin Li       return cxstring::createRef("TypeAliasTemplateDecl");
4884*67e74705SXin Li   case CXCursor_StaticAssert:
4885*67e74705SXin Li       return cxstring::createRef("StaticAssert");
4886*67e74705SXin Li   }
4887*67e74705SXin Li 
4888*67e74705SXin Li   llvm_unreachable("Unhandled CXCursorKind");
4889*67e74705SXin Li }
4890*67e74705SXin Li 
4891*67e74705SXin Li struct GetCursorData {
4892*67e74705SXin Li   SourceLocation TokenBeginLoc;
4893*67e74705SXin Li   bool PointsAtMacroArgExpansion;
4894*67e74705SXin Li   bool VisitedObjCPropertyImplDecl;
4895*67e74705SXin Li   SourceLocation VisitedDeclaratorDeclStartLoc;
4896*67e74705SXin Li   CXCursor &BestCursor;
4897*67e74705SXin Li 
GetCursorDataGetCursorData4898*67e74705SXin Li   GetCursorData(SourceManager &SM,
4899*67e74705SXin Li                 SourceLocation tokenBegin, CXCursor &outputCursor)
4900*67e74705SXin Li     : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4901*67e74705SXin Li     PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4902*67e74705SXin Li     VisitedObjCPropertyImplDecl = false;
4903*67e74705SXin Li   }
4904*67e74705SXin Li };
4905*67e74705SXin Li 
GetCursorVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)4906*67e74705SXin Li static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4907*67e74705SXin Li                                                 CXCursor parent,
4908*67e74705SXin Li                                                 CXClientData client_data) {
4909*67e74705SXin Li   GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4910*67e74705SXin Li   CXCursor *BestCursor = &Data->BestCursor;
4911*67e74705SXin Li 
4912*67e74705SXin Li   // If we point inside a macro argument we should provide info of what the
4913*67e74705SXin Li   // token is so use the actual cursor, don't replace it with a macro expansion
4914*67e74705SXin Li   // cursor.
4915*67e74705SXin Li   if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4916*67e74705SXin Li     return CXChildVisit_Recurse;
4917*67e74705SXin Li 
4918*67e74705SXin Li   if (clang_isDeclaration(cursor.kind)) {
4919*67e74705SXin Li     // Avoid having the implicit methods override the property decls.
4920*67e74705SXin Li     if (const ObjCMethodDecl *MD
4921*67e74705SXin Li           = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4922*67e74705SXin Li       if (MD->isImplicit())
4923*67e74705SXin Li         return CXChildVisit_Break;
4924*67e74705SXin Li 
4925*67e74705SXin Li     } else if (const ObjCInterfaceDecl *ID
4926*67e74705SXin Li                  = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4927*67e74705SXin Li       // Check that when we have multiple @class references in the same line,
4928*67e74705SXin Li       // that later ones do not override the previous ones.
4929*67e74705SXin Li       // If we have:
4930*67e74705SXin Li       // @class Foo, Bar;
4931*67e74705SXin Li       // source ranges for both start at '@', so 'Bar' will end up overriding
4932*67e74705SXin Li       // 'Foo' even though the cursor location was at 'Foo'.
4933*67e74705SXin Li       if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4934*67e74705SXin Li           BestCursor->kind == CXCursor_ObjCClassRef)
4935*67e74705SXin Li         if (const ObjCInterfaceDecl *PrevID
4936*67e74705SXin Li              = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4937*67e74705SXin Li          if (PrevID != ID &&
4938*67e74705SXin Li              !PrevID->isThisDeclarationADefinition() &&
4939*67e74705SXin Li              !ID->isThisDeclarationADefinition())
4940*67e74705SXin Li            return CXChildVisit_Break;
4941*67e74705SXin Li         }
4942*67e74705SXin Li 
4943*67e74705SXin Li     } else if (const DeclaratorDecl *DD
4944*67e74705SXin Li                     = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4945*67e74705SXin Li       SourceLocation StartLoc = DD->getSourceRange().getBegin();
4946*67e74705SXin Li       // Check that when we have multiple declarators in the same line,
4947*67e74705SXin Li       // that later ones do not override the previous ones.
4948*67e74705SXin Li       // If we have:
4949*67e74705SXin Li       // int Foo, Bar;
4950*67e74705SXin Li       // source ranges for both start at 'int', so 'Bar' will end up overriding
4951*67e74705SXin Li       // 'Foo' even though the cursor location was at 'Foo'.
4952*67e74705SXin Li       if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4953*67e74705SXin Li         return CXChildVisit_Break;
4954*67e74705SXin Li       Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4955*67e74705SXin Li 
4956*67e74705SXin Li     } else if (const ObjCPropertyImplDecl *PropImp
4957*67e74705SXin Li               = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4958*67e74705SXin Li       (void)PropImp;
4959*67e74705SXin Li       // Check that when we have multiple @synthesize in the same line,
4960*67e74705SXin Li       // that later ones do not override the previous ones.
4961*67e74705SXin Li       // If we have:
4962*67e74705SXin Li       // @synthesize Foo, Bar;
4963*67e74705SXin Li       // source ranges for both start at '@', so 'Bar' will end up overriding
4964*67e74705SXin Li       // 'Foo' even though the cursor location was at 'Foo'.
4965*67e74705SXin Li       if (Data->VisitedObjCPropertyImplDecl)
4966*67e74705SXin Li         return CXChildVisit_Break;
4967*67e74705SXin Li       Data->VisitedObjCPropertyImplDecl = true;
4968*67e74705SXin Li     }
4969*67e74705SXin Li   }
4970*67e74705SXin Li 
4971*67e74705SXin Li   if (clang_isExpression(cursor.kind) &&
4972*67e74705SXin Li       clang_isDeclaration(BestCursor->kind)) {
4973*67e74705SXin Li     if (const Decl *D = getCursorDecl(*BestCursor)) {
4974*67e74705SXin Li       // Avoid having the cursor of an expression replace the declaration cursor
4975*67e74705SXin Li       // when the expression source range overlaps the declaration range.
4976*67e74705SXin Li       // This can happen for C++ constructor expressions whose range generally
4977*67e74705SXin Li       // include the variable declaration, e.g.:
4978*67e74705SXin Li       //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4979*67e74705SXin Li       if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4980*67e74705SXin Li           D->getLocation() == Data->TokenBeginLoc)
4981*67e74705SXin Li         return CXChildVisit_Break;
4982*67e74705SXin Li     }
4983*67e74705SXin Li   }
4984*67e74705SXin Li 
4985*67e74705SXin Li   // If our current best cursor is the construction of a temporary object,
4986*67e74705SXin Li   // don't replace that cursor with a type reference, because we want
4987*67e74705SXin Li   // clang_getCursor() to point at the constructor.
4988*67e74705SXin Li   if (clang_isExpression(BestCursor->kind) &&
4989*67e74705SXin Li       isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4990*67e74705SXin Li       cursor.kind == CXCursor_TypeRef) {
4991*67e74705SXin Li     // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4992*67e74705SXin Li     // as having the actual point on the type reference.
4993*67e74705SXin Li     *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4994*67e74705SXin Li     return CXChildVisit_Recurse;
4995*67e74705SXin Li   }
4996*67e74705SXin Li 
4997*67e74705SXin Li   // If we already have an Objective-C superclass reference, don't
4998*67e74705SXin Li   // update it further.
4999*67e74705SXin Li   if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5000*67e74705SXin Li     return CXChildVisit_Break;
5001*67e74705SXin Li 
5002*67e74705SXin Li   *BestCursor = cursor;
5003*67e74705SXin Li   return CXChildVisit_Recurse;
5004*67e74705SXin Li }
5005*67e74705SXin Li 
clang_getCursor(CXTranslationUnit TU,CXSourceLocation Loc)5006*67e74705SXin Li CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
5007*67e74705SXin Li   if (isNotUsableTU(TU)) {
5008*67e74705SXin Li     LOG_BAD_TU(TU);
5009*67e74705SXin Li     return clang_getNullCursor();
5010*67e74705SXin Li   }
5011*67e74705SXin Li 
5012*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5013*67e74705SXin Li   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5014*67e74705SXin Li 
5015*67e74705SXin Li   SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5016*67e74705SXin Li   CXCursor Result = cxcursor::getCursor(TU, SLoc);
5017*67e74705SXin Li 
5018*67e74705SXin Li   LOG_FUNC_SECTION {
5019*67e74705SXin Li     CXFile SearchFile;
5020*67e74705SXin Li     unsigned SearchLine, SearchColumn;
5021*67e74705SXin Li     CXFile ResultFile;
5022*67e74705SXin Li     unsigned ResultLine, ResultColumn;
5023*67e74705SXin Li     CXString SearchFileName, ResultFileName, KindSpelling, USR;
5024*67e74705SXin Li     const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
5025*67e74705SXin Li     CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
5026*67e74705SXin Li 
5027*67e74705SXin Li     clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5028*67e74705SXin Li                           nullptr);
5029*67e74705SXin Li     clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
5030*67e74705SXin Li                           &ResultColumn, nullptr);
5031*67e74705SXin Li     SearchFileName = clang_getFileName(SearchFile);
5032*67e74705SXin Li     ResultFileName = clang_getFileName(ResultFile);
5033*67e74705SXin Li     KindSpelling = clang_getCursorKindSpelling(Result.kind);
5034*67e74705SXin Li     USR = clang_getCursorUSR(Result);
5035*67e74705SXin Li     *Log << llvm::format("(%s:%d:%d) = %s",
5036*67e74705SXin Li                    clang_getCString(SearchFileName), SearchLine, SearchColumn,
5037*67e74705SXin Li                    clang_getCString(KindSpelling))
5038*67e74705SXin Li         << llvm::format("(%s:%d:%d):%s%s",
5039*67e74705SXin Li                      clang_getCString(ResultFileName), ResultLine, ResultColumn,
5040*67e74705SXin Li                      clang_getCString(USR), IsDef);
5041*67e74705SXin Li     clang_disposeString(SearchFileName);
5042*67e74705SXin Li     clang_disposeString(ResultFileName);
5043*67e74705SXin Li     clang_disposeString(KindSpelling);
5044*67e74705SXin Li     clang_disposeString(USR);
5045*67e74705SXin Li 
5046*67e74705SXin Li     CXCursor Definition = clang_getCursorDefinition(Result);
5047*67e74705SXin Li     if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5048*67e74705SXin Li       CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5049*67e74705SXin Li       CXString DefinitionKindSpelling
5050*67e74705SXin Li                                 = clang_getCursorKindSpelling(Definition.kind);
5051*67e74705SXin Li       CXFile DefinitionFile;
5052*67e74705SXin Li       unsigned DefinitionLine, DefinitionColumn;
5053*67e74705SXin Li       clang_getFileLocation(DefinitionLoc, &DefinitionFile,
5054*67e74705SXin Li                             &DefinitionLine, &DefinitionColumn, nullptr);
5055*67e74705SXin Li       CXString DefinitionFileName = clang_getFileName(DefinitionFile);
5056*67e74705SXin Li       *Log << llvm::format("  -> %s(%s:%d:%d)",
5057*67e74705SXin Li                      clang_getCString(DefinitionKindSpelling),
5058*67e74705SXin Li                      clang_getCString(DefinitionFileName),
5059*67e74705SXin Li                      DefinitionLine, DefinitionColumn);
5060*67e74705SXin Li       clang_disposeString(DefinitionFileName);
5061*67e74705SXin Li       clang_disposeString(DefinitionKindSpelling);
5062*67e74705SXin Li     }
5063*67e74705SXin Li   }
5064*67e74705SXin Li 
5065*67e74705SXin Li   return Result;
5066*67e74705SXin Li }
5067*67e74705SXin Li 
clang_getNullCursor(void)5068*67e74705SXin Li CXCursor clang_getNullCursor(void) {
5069*67e74705SXin Li   return MakeCXCursorInvalid(CXCursor_InvalidFile);
5070*67e74705SXin Li }
5071*67e74705SXin Li 
clang_equalCursors(CXCursor X,CXCursor Y)5072*67e74705SXin Li unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
5073*67e74705SXin Li   // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5074*67e74705SXin Li   // can't set consistently. For example, when visiting a DeclStmt we will set
5075*67e74705SXin Li   // it but we don't set it on the result of clang_getCursorDefinition for
5076*67e74705SXin Li   // a reference of the same declaration.
5077*67e74705SXin Li   // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5078*67e74705SXin Li   // when visiting a DeclStmt currently, the AST should be enhanced to be able
5079*67e74705SXin Li   // to provide that kind of info.
5080*67e74705SXin Li   if (clang_isDeclaration(X.kind))
5081*67e74705SXin Li     X.data[1] = nullptr;
5082*67e74705SXin Li   if (clang_isDeclaration(Y.kind))
5083*67e74705SXin Li     Y.data[1] = nullptr;
5084*67e74705SXin Li 
5085*67e74705SXin Li   return X == Y;
5086*67e74705SXin Li }
5087*67e74705SXin Li 
clang_hashCursor(CXCursor C)5088*67e74705SXin Li unsigned clang_hashCursor(CXCursor C) {
5089*67e74705SXin Li   unsigned Index = 0;
5090*67e74705SXin Li   if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5091*67e74705SXin Li     Index = 1;
5092*67e74705SXin Li 
5093*67e74705SXin Li   return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
5094*67e74705SXin Li                                         std::make_pair(C.kind, C.data[Index]));
5095*67e74705SXin Li }
5096*67e74705SXin Li 
clang_isInvalid(enum CXCursorKind K)5097*67e74705SXin Li unsigned clang_isInvalid(enum CXCursorKind K) {
5098*67e74705SXin Li   return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5099*67e74705SXin Li }
5100*67e74705SXin Li 
clang_isDeclaration(enum CXCursorKind K)5101*67e74705SXin Li unsigned clang_isDeclaration(enum CXCursorKind K) {
5102*67e74705SXin Li   return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
5103*67e74705SXin Li          (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5104*67e74705SXin Li }
5105*67e74705SXin Li 
clang_isReference(enum CXCursorKind K)5106*67e74705SXin Li unsigned clang_isReference(enum CXCursorKind K) {
5107*67e74705SXin Li   return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5108*67e74705SXin Li }
5109*67e74705SXin Li 
clang_isExpression(enum CXCursorKind K)5110*67e74705SXin Li unsigned clang_isExpression(enum CXCursorKind K) {
5111*67e74705SXin Li   return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5112*67e74705SXin Li }
5113*67e74705SXin Li 
clang_isStatement(enum CXCursorKind K)5114*67e74705SXin Li unsigned clang_isStatement(enum CXCursorKind K) {
5115*67e74705SXin Li   return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5116*67e74705SXin Li }
5117*67e74705SXin Li 
clang_isAttribute(enum CXCursorKind K)5118*67e74705SXin Li unsigned clang_isAttribute(enum CXCursorKind K) {
5119*67e74705SXin Li     return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
5120*67e74705SXin Li }
5121*67e74705SXin Li 
clang_isTranslationUnit(enum CXCursorKind K)5122*67e74705SXin Li unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5123*67e74705SXin Li   return K == CXCursor_TranslationUnit;
5124*67e74705SXin Li }
5125*67e74705SXin Li 
clang_isPreprocessing(enum CXCursorKind K)5126*67e74705SXin Li unsigned clang_isPreprocessing(enum CXCursorKind K) {
5127*67e74705SXin Li   return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5128*67e74705SXin Li }
5129*67e74705SXin Li 
clang_isUnexposed(enum CXCursorKind K)5130*67e74705SXin Li unsigned clang_isUnexposed(enum CXCursorKind K) {
5131*67e74705SXin Li   switch (K) {
5132*67e74705SXin Li     case CXCursor_UnexposedDecl:
5133*67e74705SXin Li     case CXCursor_UnexposedExpr:
5134*67e74705SXin Li     case CXCursor_UnexposedStmt:
5135*67e74705SXin Li     case CXCursor_UnexposedAttr:
5136*67e74705SXin Li       return true;
5137*67e74705SXin Li     default:
5138*67e74705SXin Li       return false;
5139*67e74705SXin Li   }
5140*67e74705SXin Li }
5141*67e74705SXin Li 
clang_getCursorKind(CXCursor C)5142*67e74705SXin Li CXCursorKind clang_getCursorKind(CXCursor C) {
5143*67e74705SXin Li   return C.kind;
5144*67e74705SXin Li }
5145*67e74705SXin Li 
clang_getCursorLocation(CXCursor C)5146*67e74705SXin Li CXSourceLocation clang_getCursorLocation(CXCursor C) {
5147*67e74705SXin Li   if (clang_isReference(C.kind)) {
5148*67e74705SXin Li     switch (C.kind) {
5149*67e74705SXin Li     case CXCursor_ObjCSuperClassRef: {
5150*67e74705SXin Li       std::pair<const ObjCInterfaceDecl *, SourceLocation> P
5151*67e74705SXin Li         = getCursorObjCSuperClassRef(C);
5152*67e74705SXin Li       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5153*67e74705SXin Li     }
5154*67e74705SXin Li 
5155*67e74705SXin Li     case CXCursor_ObjCProtocolRef: {
5156*67e74705SXin Li       std::pair<const ObjCProtocolDecl *, SourceLocation> P
5157*67e74705SXin Li         = getCursorObjCProtocolRef(C);
5158*67e74705SXin Li       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5159*67e74705SXin Li     }
5160*67e74705SXin Li 
5161*67e74705SXin Li     case CXCursor_ObjCClassRef: {
5162*67e74705SXin Li       std::pair<const ObjCInterfaceDecl *, SourceLocation> P
5163*67e74705SXin Li         = getCursorObjCClassRef(C);
5164*67e74705SXin Li       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5165*67e74705SXin Li     }
5166*67e74705SXin Li 
5167*67e74705SXin Li     case CXCursor_TypeRef: {
5168*67e74705SXin Li       std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
5169*67e74705SXin Li       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5170*67e74705SXin Li     }
5171*67e74705SXin Li 
5172*67e74705SXin Li     case CXCursor_TemplateRef: {
5173*67e74705SXin Li       std::pair<const TemplateDecl *, SourceLocation> P =
5174*67e74705SXin Li           getCursorTemplateRef(C);
5175*67e74705SXin Li       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5176*67e74705SXin Li     }
5177*67e74705SXin Li 
5178*67e74705SXin Li     case CXCursor_NamespaceRef: {
5179*67e74705SXin Li       std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
5180*67e74705SXin Li       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5181*67e74705SXin Li     }
5182*67e74705SXin Li 
5183*67e74705SXin Li     case CXCursor_MemberRef: {
5184*67e74705SXin Li       std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
5185*67e74705SXin Li       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5186*67e74705SXin Li     }
5187*67e74705SXin Li 
5188*67e74705SXin Li     case CXCursor_VariableRef: {
5189*67e74705SXin Li       std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
5190*67e74705SXin Li       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5191*67e74705SXin Li     }
5192*67e74705SXin Li 
5193*67e74705SXin Li     case CXCursor_CXXBaseSpecifier: {
5194*67e74705SXin Li       const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
5195*67e74705SXin Li       if (!BaseSpec)
5196*67e74705SXin Li         return clang_getNullLocation();
5197*67e74705SXin Li 
5198*67e74705SXin Li       if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
5199*67e74705SXin Li         return cxloc::translateSourceLocation(getCursorContext(C),
5200*67e74705SXin Li                                             TSInfo->getTypeLoc().getBeginLoc());
5201*67e74705SXin Li 
5202*67e74705SXin Li       return cxloc::translateSourceLocation(getCursorContext(C),
5203*67e74705SXin Li                                         BaseSpec->getLocStart());
5204*67e74705SXin Li     }
5205*67e74705SXin Li 
5206*67e74705SXin Li     case CXCursor_LabelRef: {
5207*67e74705SXin Li       std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
5208*67e74705SXin Li       return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5209*67e74705SXin Li     }
5210*67e74705SXin Li 
5211*67e74705SXin Li     case CXCursor_OverloadedDeclRef:
5212*67e74705SXin Li       return cxloc::translateSourceLocation(getCursorContext(C),
5213*67e74705SXin Li                                           getCursorOverloadedDeclRef(C).second);
5214*67e74705SXin Li 
5215*67e74705SXin Li     default:
5216*67e74705SXin Li       // FIXME: Need a way to enumerate all non-reference cases.
5217*67e74705SXin Li       llvm_unreachable("Missed a reference kind");
5218*67e74705SXin Li     }
5219*67e74705SXin Li   }
5220*67e74705SXin Li 
5221*67e74705SXin Li   if (clang_isExpression(C.kind))
5222*67e74705SXin Li     return cxloc::translateSourceLocation(getCursorContext(C),
5223*67e74705SXin Li                                    getLocationFromExpr(getCursorExpr(C)));
5224*67e74705SXin Li 
5225*67e74705SXin Li   if (clang_isStatement(C.kind))
5226*67e74705SXin Li     return cxloc::translateSourceLocation(getCursorContext(C),
5227*67e74705SXin Li                                           getCursorStmt(C)->getLocStart());
5228*67e74705SXin Li 
5229*67e74705SXin Li   if (C.kind == CXCursor_PreprocessingDirective) {
5230*67e74705SXin Li     SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5231*67e74705SXin Li     return cxloc::translateSourceLocation(getCursorContext(C), L);
5232*67e74705SXin Li   }
5233*67e74705SXin Li 
5234*67e74705SXin Li   if (C.kind == CXCursor_MacroExpansion) {
5235*67e74705SXin Li     SourceLocation L
5236*67e74705SXin Li       = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
5237*67e74705SXin Li     return cxloc::translateSourceLocation(getCursorContext(C), L);
5238*67e74705SXin Li   }
5239*67e74705SXin Li 
5240*67e74705SXin Li   if (C.kind == CXCursor_MacroDefinition) {
5241*67e74705SXin Li     SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5242*67e74705SXin Li     return cxloc::translateSourceLocation(getCursorContext(C), L);
5243*67e74705SXin Li   }
5244*67e74705SXin Li 
5245*67e74705SXin Li   if (C.kind == CXCursor_InclusionDirective) {
5246*67e74705SXin Li     SourceLocation L
5247*67e74705SXin Li       = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
5248*67e74705SXin Li     return cxloc::translateSourceLocation(getCursorContext(C), L);
5249*67e74705SXin Li   }
5250*67e74705SXin Li 
5251*67e74705SXin Li   if (clang_isAttribute(C.kind)) {
5252*67e74705SXin Li     SourceLocation L
5253*67e74705SXin Li       = cxcursor::getCursorAttr(C)->getLocation();
5254*67e74705SXin Li     return cxloc::translateSourceLocation(getCursorContext(C), L);
5255*67e74705SXin Li   }
5256*67e74705SXin Li 
5257*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
5258*67e74705SXin Li     return clang_getNullLocation();
5259*67e74705SXin Li 
5260*67e74705SXin Li   const Decl *D = getCursorDecl(C);
5261*67e74705SXin Li   if (!D)
5262*67e74705SXin Li     return clang_getNullLocation();
5263*67e74705SXin Li 
5264*67e74705SXin Li   SourceLocation Loc = D->getLocation();
5265*67e74705SXin Li   // FIXME: Multiple variables declared in a single declaration
5266*67e74705SXin Li   // currently lack the information needed to correctly determine their
5267*67e74705SXin Li   // ranges when accounting for the type-specifier.  We use context
5268*67e74705SXin Li   // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5269*67e74705SXin Li   // and if so, whether it is the first decl.
5270*67e74705SXin Li   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
5271*67e74705SXin Li     if (!cxcursor::isFirstInDeclGroup(C))
5272*67e74705SXin Li       Loc = VD->getLocation();
5273*67e74705SXin Li   }
5274*67e74705SXin Li 
5275*67e74705SXin Li   // For ObjC methods, give the start location of the method name.
5276*67e74705SXin Li   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5277*67e74705SXin Li     Loc = MD->getSelectorStartLoc();
5278*67e74705SXin Li 
5279*67e74705SXin Li   return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5280*67e74705SXin Li }
5281*67e74705SXin Li 
5282*67e74705SXin Li } // end extern "C"
5283*67e74705SXin Li 
getCursor(CXTranslationUnit TU,SourceLocation SLoc)5284*67e74705SXin Li CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
5285*67e74705SXin Li   assert(TU);
5286*67e74705SXin Li 
5287*67e74705SXin Li   // Guard against an invalid SourceLocation, or we may assert in one
5288*67e74705SXin Li   // of the following calls.
5289*67e74705SXin Li   if (SLoc.isInvalid())
5290*67e74705SXin Li     return clang_getNullCursor();
5291*67e74705SXin Li 
5292*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5293*67e74705SXin Li 
5294*67e74705SXin Li   // Translate the given source location to make it point at the beginning of
5295*67e74705SXin Li   // the token under the cursor.
5296*67e74705SXin Li   SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
5297*67e74705SXin Li                                     CXXUnit->getASTContext().getLangOpts());
5298*67e74705SXin Li 
5299*67e74705SXin Li   CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
5300*67e74705SXin Li   if (SLoc.isValid()) {
5301*67e74705SXin Li     GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
5302*67e74705SXin Li     CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
5303*67e74705SXin Li                             /*VisitPreprocessorLast=*/true,
5304*67e74705SXin Li                             /*VisitIncludedEntities=*/false,
5305*67e74705SXin Li                             SourceLocation(SLoc));
5306*67e74705SXin Li     CursorVis.visitFileRegion();
5307*67e74705SXin Li   }
5308*67e74705SXin Li 
5309*67e74705SXin Li   return Result;
5310*67e74705SXin Li }
5311*67e74705SXin Li 
getRawCursorExtent(CXCursor C)5312*67e74705SXin Li static SourceRange getRawCursorExtent(CXCursor C) {
5313*67e74705SXin Li   if (clang_isReference(C.kind)) {
5314*67e74705SXin Li     switch (C.kind) {
5315*67e74705SXin Li     case CXCursor_ObjCSuperClassRef:
5316*67e74705SXin Li       return  getCursorObjCSuperClassRef(C).second;
5317*67e74705SXin Li 
5318*67e74705SXin Li     case CXCursor_ObjCProtocolRef:
5319*67e74705SXin Li       return getCursorObjCProtocolRef(C).second;
5320*67e74705SXin Li 
5321*67e74705SXin Li     case CXCursor_ObjCClassRef:
5322*67e74705SXin Li       return getCursorObjCClassRef(C).second;
5323*67e74705SXin Li 
5324*67e74705SXin Li     case CXCursor_TypeRef:
5325*67e74705SXin Li       return getCursorTypeRef(C).second;
5326*67e74705SXin Li 
5327*67e74705SXin Li     case CXCursor_TemplateRef:
5328*67e74705SXin Li       return getCursorTemplateRef(C).second;
5329*67e74705SXin Li 
5330*67e74705SXin Li     case CXCursor_NamespaceRef:
5331*67e74705SXin Li       return getCursorNamespaceRef(C).second;
5332*67e74705SXin Li 
5333*67e74705SXin Li     case CXCursor_MemberRef:
5334*67e74705SXin Li       return getCursorMemberRef(C).second;
5335*67e74705SXin Li 
5336*67e74705SXin Li     case CXCursor_CXXBaseSpecifier:
5337*67e74705SXin Li       return getCursorCXXBaseSpecifier(C)->getSourceRange();
5338*67e74705SXin Li 
5339*67e74705SXin Li     case CXCursor_LabelRef:
5340*67e74705SXin Li       return getCursorLabelRef(C).second;
5341*67e74705SXin Li 
5342*67e74705SXin Li     case CXCursor_OverloadedDeclRef:
5343*67e74705SXin Li       return getCursorOverloadedDeclRef(C).second;
5344*67e74705SXin Li 
5345*67e74705SXin Li     case CXCursor_VariableRef:
5346*67e74705SXin Li       return getCursorVariableRef(C).second;
5347*67e74705SXin Li 
5348*67e74705SXin Li     default:
5349*67e74705SXin Li       // FIXME: Need a way to enumerate all non-reference cases.
5350*67e74705SXin Li       llvm_unreachable("Missed a reference kind");
5351*67e74705SXin Li     }
5352*67e74705SXin Li   }
5353*67e74705SXin Li 
5354*67e74705SXin Li   if (clang_isExpression(C.kind))
5355*67e74705SXin Li     return getCursorExpr(C)->getSourceRange();
5356*67e74705SXin Li 
5357*67e74705SXin Li   if (clang_isStatement(C.kind))
5358*67e74705SXin Li     return getCursorStmt(C)->getSourceRange();
5359*67e74705SXin Li 
5360*67e74705SXin Li   if (clang_isAttribute(C.kind))
5361*67e74705SXin Li     return getCursorAttr(C)->getRange();
5362*67e74705SXin Li 
5363*67e74705SXin Li   if (C.kind == CXCursor_PreprocessingDirective)
5364*67e74705SXin Li     return cxcursor::getCursorPreprocessingDirective(C);
5365*67e74705SXin Li 
5366*67e74705SXin Li   if (C.kind == CXCursor_MacroExpansion) {
5367*67e74705SXin Li     ASTUnit *TU = getCursorASTUnit(C);
5368*67e74705SXin Li     SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
5369*67e74705SXin Li     return TU->mapRangeFromPreamble(Range);
5370*67e74705SXin Li   }
5371*67e74705SXin Li 
5372*67e74705SXin Li   if (C.kind == CXCursor_MacroDefinition) {
5373*67e74705SXin Li     ASTUnit *TU = getCursorASTUnit(C);
5374*67e74705SXin Li     SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
5375*67e74705SXin Li     return TU->mapRangeFromPreamble(Range);
5376*67e74705SXin Li   }
5377*67e74705SXin Li 
5378*67e74705SXin Li   if (C.kind == CXCursor_InclusionDirective) {
5379*67e74705SXin Li     ASTUnit *TU = getCursorASTUnit(C);
5380*67e74705SXin Li     SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
5381*67e74705SXin Li     return TU->mapRangeFromPreamble(Range);
5382*67e74705SXin Li   }
5383*67e74705SXin Li 
5384*67e74705SXin Li   if (C.kind == CXCursor_TranslationUnit) {
5385*67e74705SXin Li     ASTUnit *TU = getCursorASTUnit(C);
5386*67e74705SXin Li     FileID MainID = TU->getSourceManager().getMainFileID();
5387*67e74705SXin Li     SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
5388*67e74705SXin Li     SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
5389*67e74705SXin Li     return SourceRange(Start, End);
5390*67e74705SXin Li   }
5391*67e74705SXin Li 
5392*67e74705SXin Li   if (clang_isDeclaration(C.kind)) {
5393*67e74705SXin Li     const Decl *D = cxcursor::getCursorDecl(C);
5394*67e74705SXin Li     if (!D)
5395*67e74705SXin Li       return SourceRange();
5396*67e74705SXin Li 
5397*67e74705SXin Li     SourceRange R = D->getSourceRange();
5398*67e74705SXin Li     // FIXME: Multiple variables declared in a single declaration
5399*67e74705SXin Li     // currently lack the information needed to correctly determine their
5400*67e74705SXin Li     // ranges when accounting for the type-specifier.  We use context
5401*67e74705SXin Li     // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5402*67e74705SXin Li     // and if so, whether it is the first decl.
5403*67e74705SXin Li     if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
5404*67e74705SXin Li       if (!cxcursor::isFirstInDeclGroup(C))
5405*67e74705SXin Li         R.setBegin(VD->getLocation());
5406*67e74705SXin Li     }
5407*67e74705SXin Li     return R;
5408*67e74705SXin Li   }
5409*67e74705SXin Li   return SourceRange();
5410*67e74705SXin Li }
5411*67e74705SXin Li 
5412*67e74705SXin Li /// \brief Retrieves the "raw" cursor extent, which is then extended to include
5413*67e74705SXin Li /// the decl-specifier-seq for declarations.
getFullCursorExtent(CXCursor C,SourceManager & SrcMgr)5414*67e74705SXin Li static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
5415*67e74705SXin Li   if (clang_isDeclaration(C.kind)) {
5416*67e74705SXin Li     const Decl *D = cxcursor::getCursorDecl(C);
5417*67e74705SXin Li     if (!D)
5418*67e74705SXin Li       return SourceRange();
5419*67e74705SXin Li 
5420*67e74705SXin Li     SourceRange R = D->getSourceRange();
5421*67e74705SXin Li 
5422*67e74705SXin Li     // Adjust the start of the location for declarations preceded by
5423*67e74705SXin Li     // declaration specifiers.
5424*67e74705SXin Li     SourceLocation StartLoc;
5425*67e74705SXin Li     if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
5426*67e74705SXin Li       if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
5427*67e74705SXin Li         StartLoc = TI->getTypeLoc().getLocStart();
5428*67e74705SXin Li     } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
5429*67e74705SXin Li       if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
5430*67e74705SXin Li         StartLoc = TI->getTypeLoc().getLocStart();
5431*67e74705SXin Li     }
5432*67e74705SXin Li 
5433*67e74705SXin Li     if (StartLoc.isValid() && R.getBegin().isValid() &&
5434*67e74705SXin Li         SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
5435*67e74705SXin Li       R.setBegin(StartLoc);
5436*67e74705SXin Li 
5437*67e74705SXin Li     // FIXME: Multiple variables declared in a single declaration
5438*67e74705SXin Li     // currently lack the information needed to correctly determine their
5439*67e74705SXin Li     // ranges when accounting for the type-specifier.  We use context
5440*67e74705SXin Li     // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5441*67e74705SXin Li     // and if so, whether it is the first decl.
5442*67e74705SXin Li     if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
5443*67e74705SXin Li       if (!cxcursor::isFirstInDeclGroup(C))
5444*67e74705SXin Li         R.setBegin(VD->getLocation());
5445*67e74705SXin Li     }
5446*67e74705SXin Li 
5447*67e74705SXin Li     return R;
5448*67e74705SXin Li   }
5449*67e74705SXin Li 
5450*67e74705SXin Li   return getRawCursorExtent(C);
5451*67e74705SXin Li }
5452*67e74705SXin Li 
5453*67e74705SXin Li extern "C" {
5454*67e74705SXin Li 
clang_getCursorExtent(CXCursor C)5455*67e74705SXin Li CXSourceRange clang_getCursorExtent(CXCursor C) {
5456*67e74705SXin Li   SourceRange R = getRawCursorExtent(C);
5457*67e74705SXin Li   if (R.isInvalid())
5458*67e74705SXin Li     return clang_getNullRange();
5459*67e74705SXin Li 
5460*67e74705SXin Li   return cxloc::translateSourceRange(getCursorContext(C), R);
5461*67e74705SXin Li }
5462*67e74705SXin Li 
clang_getCursorReferenced(CXCursor C)5463*67e74705SXin Li CXCursor clang_getCursorReferenced(CXCursor C) {
5464*67e74705SXin Li   if (clang_isInvalid(C.kind))
5465*67e74705SXin Li     return clang_getNullCursor();
5466*67e74705SXin Li 
5467*67e74705SXin Li   CXTranslationUnit tu = getCursorTU(C);
5468*67e74705SXin Li   if (clang_isDeclaration(C.kind)) {
5469*67e74705SXin Li     const Decl *D = getCursorDecl(C);
5470*67e74705SXin Li     if (!D)
5471*67e74705SXin Li       return clang_getNullCursor();
5472*67e74705SXin Li     if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
5473*67e74705SXin Li       return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
5474*67e74705SXin Li     if (const ObjCPropertyImplDecl *PropImpl =
5475*67e74705SXin Li             dyn_cast<ObjCPropertyImplDecl>(D))
5476*67e74705SXin Li       if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5477*67e74705SXin Li         return MakeCXCursor(Property, tu);
5478*67e74705SXin Li 
5479*67e74705SXin Li     return C;
5480*67e74705SXin Li   }
5481*67e74705SXin Li 
5482*67e74705SXin Li   if (clang_isExpression(C.kind)) {
5483*67e74705SXin Li     const Expr *E = getCursorExpr(C);
5484*67e74705SXin Li     const Decl *D = getDeclFromExpr(E);
5485*67e74705SXin Li     if (D) {
5486*67e74705SXin Li       CXCursor declCursor = MakeCXCursor(D, tu);
5487*67e74705SXin Li       declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
5488*67e74705SXin Li                                                declCursor);
5489*67e74705SXin Li       return declCursor;
5490*67e74705SXin Li     }
5491*67e74705SXin Li 
5492*67e74705SXin Li     if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
5493*67e74705SXin Li       return MakeCursorOverloadedDeclRef(Ovl, tu);
5494*67e74705SXin Li 
5495*67e74705SXin Li     return clang_getNullCursor();
5496*67e74705SXin Li   }
5497*67e74705SXin Li 
5498*67e74705SXin Li   if (clang_isStatement(C.kind)) {
5499*67e74705SXin Li     const Stmt *S = getCursorStmt(C);
5500*67e74705SXin Li     if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
5501*67e74705SXin Li       if (LabelDecl *label = Goto->getLabel())
5502*67e74705SXin Li         if (LabelStmt *labelS = label->getStmt())
5503*67e74705SXin Li         return MakeCXCursor(labelS, getCursorDecl(C), tu);
5504*67e74705SXin Li 
5505*67e74705SXin Li     return clang_getNullCursor();
5506*67e74705SXin Li   }
5507*67e74705SXin Li 
5508*67e74705SXin Li   if (C.kind == CXCursor_MacroExpansion) {
5509*67e74705SXin Li     if (const MacroDefinitionRecord *Def =
5510*67e74705SXin Li             getCursorMacroExpansion(C).getDefinition())
5511*67e74705SXin Li       return MakeMacroDefinitionCursor(Def, tu);
5512*67e74705SXin Li   }
5513*67e74705SXin Li 
5514*67e74705SXin Li   if (!clang_isReference(C.kind))
5515*67e74705SXin Li     return clang_getNullCursor();
5516*67e74705SXin Li 
5517*67e74705SXin Li   switch (C.kind) {
5518*67e74705SXin Li     case CXCursor_ObjCSuperClassRef:
5519*67e74705SXin Li       return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5520*67e74705SXin Li 
5521*67e74705SXin Li     case CXCursor_ObjCProtocolRef: {
5522*67e74705SXin Li       const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5523*67e74705SXin Li       if (const ObjCProtocolDecl *Def = Prot->getDefinition())
5524*67e74705SXin Li         return MakeCXCursor(Def, tu);
5525*67e74705SXin Li 
5526*67e74705SXin Li       return MakeCXCursor(Prot, tu);
5527*67e74705SXin Li     }
5528*67e74705SXin Li 
5529*67e74705SXin Li     case CXCursor_ObjCClassRef: {
5530*67e74705SXin Li       const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5531*67e74705SXin Li       if (const ObjCInterfaceDecl *Def = Class->getDefinition())
5532*67e74705SXin Li         return MakeCXCursor(Def, tu);
5533*67e74705SXin Li 
5534*67e74705SXin Li       return MakeCXCursor(Class, tu);
5535*67e74705SXin Li     }
5536*67e74705SXin Li 
5537*67e74705SXin Li     case CXCursor_TypeRef:
5538*67e74705SXin Li       return MakeCXCursor(getCursorTypeRef(C).first, tu );
5539*67e74705SXin Li 
5540*67e74705SXin Li     case CXCursor_TemplateRef:
5541*67e74705SXin Li       return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5542*67e74705SXin Li 
5543*67e74705SXin Li     case CXCursor_NamespaceRef:
5544*67e74705SXin Li       return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5545*67e74705SXin Li 
5546*67e74705SXin Li     case CXCursor_MemberRef:
5547*67e74705SXin Li       return MakeCXCursor(getCursorMemberRef(C).first, tu );
5548*67e74705SXin Li 
5549*67e74705SXin Li     case CXCursor_CXXBaseSpecifier: {
5550*67e74705SXin Li       const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
5551*67e74705SXin Li       return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5552*67e74705SXin Li                                                          tu ));
5553*67e74705SXin Li     }
5554*67e74705SXin Li 
5555*67e74705SXin Li     case CXCursor_LabelRef:
5556*67e74705SXin Li       // FIXME: We end up faking the "parent" declaration here because we
5557*67e74705SXin Li       // don't want to make CXCursor larger.
5558*67e74705SXin Li       return MakeCXCursor(getCursorLabelRef(C).first,
5559*67e74705SXin Li                           cxtu::getASTUnit(tu)->getASTContext()
5560*67e74705SXin Li                               .getTranslationUnitDecl(),
5561*67e74705SXin Li                           tu);
5562*67e74705SXin Li 
5563*67e74705SXin Li     case CXCursor_OverloadedDeclRef:
5564*67e74705SXin Li       return C;
5565*67e74705SXin Li 
5566*67e74705SXin Li     case CXCursor_VariableRef:
5567*67e74705SXin Li       return MakeCXCursor(getCursorVariableRef(C).first, tu);
5568*67e74705SXin Li 
5569*67e74705SXin Li     default:
5570*67e74705SXin Li       // We would prefer to enumerate all non-reference cursor kinds here.
5571*67e74705SXin Li       llvm_unreachable("Unhandled reference cursor kind");
5572*67e74705SXin Li   }
5573*67e74705SXin Li }
5574*67e74705SXin Li 
clang_getCursorDefinition(CXCursor C)5575*67e74705SXin Li CXCursor clang_getCursorDefinition(CXCursor C) {
5576*67e74705SXin Li   if (clang_isInvalid(C.kind))
5577*67e74705SXin Li     return clang_getNullCursor();
5578*67e74705SXin Li 
5579*67e74705SXin Li   CXTranslationUnit TU = getCursorTU(C);
5580*67e74705SXin Li 
5581*67e74705SXin Li   bool WasReference = false;
5582*67e74705SXin Li   if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5583*67e74705SXin Li     C = clang_getCursorReferenced(C);
5584*67e74705SXin Li     WasReference = true;
5585*67e74705SXin Li   }
5586*67e74705SXin Li 
5587*67e74705SXin Li   if (C.kind == CXCursor_MacroExpansion)
5588*67e74705SXin Li     return clang_getCursorReferenced(C);
5589*67e74705SXin Li 
5590*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
5591*67e74705SXin Li     return clang_getNullCursor();
5592*67e74705SXin Li 
5593*67e74705SXin Li   const Decl *D = getCursorDecl(C);
5594*67e74705SXin Li   if (!D)
5595*67e74705SXin Li     return clang_getNullCursor();
5596*67e74705SXin Li 
5597*67e74705SXin Li   switch (D->getKind()) {
5598*67e74705SXin Li   // Declaration kinds that don't really separate the notions of
5599*67e74705SXin Li   // declaration and definition.
5600*67e74705SXin Li   case Decl::Namespace:
5601*67e74705SXin Li   case Decl::Typedef:
5602*67e74705SXin Li   case Decl::TypeAlias:
5603*67e74705SXin Li   case Decl::TypeAliasTemplate:
5604*67e74705SXin Li   case Decl::TemplateTypeParm:
5605*67e74705SXin Li   case Decl::EnumConstant:
5606*67e74705SXin Li   case Decl::Field:
5607*67e74705SXin Li   case Decl::MSProperty:
5608*67e74705SXin Li   case Decl::IndirectField:
5609*67e74705SXin Li   case Decl::ObjCIvar:
5610*67e74705SXin Li   case Decl::ObjCAtDefsField:
5611*67e74705SXin Li   case Decl::ImplicitParam:
5612*67e74705SXin Li   case Decl::ParmVar:
5613*67e74705SXin Li   case Decl::NonTypeTemplateParm:
5614*67e74705SXin Li   case Decl::TemplateTemplateParm:
5615*67e74705SXin Li   case Decl::ObjCCategoryImpl:
5616*67e74705SXin Li   case Decl::ObjCImplementation:
5617*67e74705SXin Li   case Decl::AccessSpec:
5618*67e74705SXin Li   case Decl::LinkageSpec:
5619*67e74705SXin Li   case Decl::ObjCPropertyImpl:
5620*67e74705SXin Li   case Decl::FileScopeAsm:
5621*67e74705SXin Li   case Decl::StaticAssert:
5622*67e74705SXin Li   case Decl::Block:
5623*67e74705SXin Li   case Decl::Captured:
5624*67e74705SXin Li   case Decl::OMPCapturedExpr:
5625*67e74705SXin Li   case Decl::Label:  // FIXME: Is this right??
5626*67e74705SXin Li   case Decl::ClassScopeFunctionSpecialization:
5627*67e74705SXin Li   case Decl::Import:
5628*67e74705SXin Li   case Decl::OMPThreadPrivate:
5629*67e74705SXin Li   case Decl::OMPDeclareReduction:
5630*67e74705SXin Li   case Decl::ObjCTypeParam:
5631*67e74705SXin Li   case Decl::BuiltinTemplate:
5632*67e74705SXin Li   case Decl::PragmaComment:
5633*67e74705SXin Li   case Decl::PragmaDetectMismatch:
5634*67e74705SXin Li     return C;
5635*67e74705SXin Li 
5636*67e74705SXin Li   // Declaration kinds that don't make any sense here, but are
5637*67e74705SXin Li   // nonetheless harmless.
5638*67e74705SXin Li   case Decl::Empty:
5639*67e74705SXin Li   case Decl::TranslationUnit:
5640*67e74705SXin Li   case Decl::ExternCContext:
5641*67e74705SXin Li     break;
5642*67e74705SXin Li 
5643*67e74705SXin Li   // Declaration kinds for which the definition is not resolvable.
5644*67e74705SXin Li   case Decl::UnresolvedUsingTypename:
5645*67e74705SXin Li   case Decl::UnresolvedUsingValue:
5646*67e74705SXin Li     break;
5647*67e74705SXin Li 
5648*67e74705SXin Li   case Decl::UsingDirective:
5649*67e74705SXin Li     return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5650*67e74705SXin Li                         TU);
5651*67e74705SXin Li 
5652*67e74705SXin Li   case Decl::NamespaceAlias:
5653*67e74705SXin Li     return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5654*67e74705SXin Li 
5655*67e74705SXin Li   case Decl::Enum:
5656*67e74705SXin Li   case Decl::Record:
5657*67e74705SXin Li   case Decl::CXXRecord:
5658*67e74705SXin Li   case Decl::ClassTemplateSpecialization:
5659*67e74705SXin Li   case Decl::ClassTemplatePartialSpecialization:
5660*67e74705SXin Li     if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5661*67e74705SXin Li       return MakeCXCursor(Def, TU);
5662*67e74705SXin Li     return clang_getNullCursor();
5663*67e74705SXin Li 
5664*67e74705SXin Li   case Decl::Function:
5665*67e74705SXin Li   case Decl::CXXMethod:
5666*67e74705SXin Li   case Decl::CXXConstructor:
5667*67e74705SXin Li   case Decl::CXXDestructor:
5668*67e74705SXin Li   case Decl::CXXConversion: {
5669*67e74705SXin Li     const FunctionDecl *Def = nullptr;
5670*67e74705SXin Li     if (cast<FunctionDecl>(D)->getBody(Def))
5671*67e74705SXin Li       return MakeCXCursor(Def, TU);
5672*67e74705SXin Li     return clang_getNullCursor();
5673*67e74705SXin Li   }
5674*67e74705SXin Li 
5675*67e74705SXin Li   case Decl::Var:
5676*67e74705SXin Li   case Decl::VarTemplateSpecialization:
5677*67e74705SXin Li   case Decl::VarTemplatePartialSpecialization: {
5678*67e74705SXin Li     // Ask the variable if it has a definition.
5679*67e74705SXin Li     if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
5680*67e74705SXin Li       return MakeCXCursor(Def, TU);
5681*67e74705SXin Li     return clang_getNullCursor();
5682*67e74705SXin Li   }
5683*67e74705SXin Li 
5684*67e74705SXin Li   case Decl::FunctionTemplate: {
5685*67e74705SXin Li     const FunctionDecl *Def = nullptr;
5686*67e74705SXin Li     if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5687*67e74705SXin Li       return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5688*67e74705SXin Li     return clang_getNullCursor();
5689*67e74705SXin Li   }
5690*67e74705SXin Li 
5691*67e74705SXin Li   case Decl::ClassTemplate: {
5692*67e74705SXin Li     if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5693*67e74705SXin Li                                                             ->getDefinition())
5694*67e74705SXin Li       return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5695*67e74705SXin Li                           TU);
5696*67e74705SXin Li     return clang_getNullCursor();
5697*67e74705SXin Li   }
5698*67e74705SXin Li 
5699*67e74705SXin Li   case Decl::VarTemplate: {
5700*67e74705SXin Li     if (VarDecl *Def =
5701*67e74705SXin Li             cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5702*67e74705SXin Li       return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5703*67e74705SXin Li     return clang_getNullCursor();
5704*67e74705SXin Li   }
5705*67e74705SXin Li 
5706*67e74705SXin Li   case Decl::Using:
5707*67e74705SXin Li     return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5708*67e74705SXin Li                                        D->getLocation(), TU);
5709*67e74705SXin Li 
5710*67e74705SXin Li   case Decl::UsingShadow:
5711*67e74705SXin Li   case Decl::ConstructorUsingShadow:
5712*67e74705SXin Li     return clang_getCursorDefinition(
5713*67e74705SXin Li                        MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5714*67e74705SXin Li                                     TU));
5715*67e74705SXin Li 
5716*67e74705SXin Li   case Decl::ObjCMethod: {
5717*67e74705SXin Li     const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
5718*67e74705SXin Li     if (Method->isThisDeclarationADefinition())
5719*67e74705SXin Li       return C;
5720*67e74705SXin Li 
5721*67e74705SXin Li     // Dig out the method definition in the associated
5722*67e74705SXin Li     // @implementation, if we have it.
5723*67e74705SXin Li     // FIXME: The ASTs should make finding the definition easier.
5724*67e74705SXin Li     if (const ObjCInterfaceDecl *Class
5725*67e74705SXin Li                        = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5726*67e74705SXin Li       if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5727*67e74705SXin Li         if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5728*67e74705SXin Li                                                   Method->isInstanceMethod()))
5729*67e74705SXin Li           if (Def->isThisDeclarationADefinition())
5730*67e74705SXin Li             return MakeCXCursor(Def, TU);
5731*67e74705SXin Li 
5732*67e74705SXin Li     return clang_getNullCursor();
5733*67e74705SXin Li   }
5734*67e74705SXin Li 
5735*67e74705SXin Li   case Decl::ObjCCategory:
5736*67e74705SXin Li     if (ObjCCategoryImplDecl *Impl
5737*67e74705SXin Li                                = cast<ObjCCategoryDecl>(D)->getImplementation())
5738*67e74705SXin Li       return MakeCXCursor(Impl, TU);
5739*67e74705SXin Li     return clang_getNullCursor();
5740*67e74705SXin Li 
5741*67e74705SXin Li   case Decl::ObjCProtocol:
5742*67e74705SXin Li     if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
5743*67e74705SXin Li       return MakeCXCursor(Def, TU);
5744*67e74705SXin Li     return clang_getNullCursor();
5745*67e74705SXin Li 
5746*67e74705SXin Li   case Decl::ObjCInterface: {
5747*67e74705SXin Li     // There are two notions of a "definition" for an Objective-C
5748*67e74705SXin Li     // class: the interface and its implementation. When we resolved a
5749*67e74705SXin Li     // reference to an Objective-C class, produce the @interface as
5750*67e74705SXin Li     // the definition; when we were provided with the interface,
5751*67e74705SXin Li     // produce the @implementation as the definition.
5752*67e74705SXin Li     const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
5753*67e74705SXin Li     if (WasReference) {
5754*67e74705SXin Li       if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
5755*67e74705SXin Li         return MakeCXCursor(Def, TU);
5756*67e74705SXin Li     } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5757*67e74705SXin Li       return MakeCXCursor(Impl, TU);
5758*67e74705SXin Li     return clang_getNullCursor();
5759*67e74705SXin Li   }
5760*67e74705SXin Li 
5761*67e74705SXin Li   case Decl::ObjCProperty:
5762*67e74705SXin Li     // FIXME: We don't really know where to find the
5763*67e74705SXin Li     // ObjCPropertyImplDecls that implement this property.
5764*67e74705SXin Li     return clang_getNullCursor();
5765*67e74705SXin Li 
5766*67e74705SXin Li   case Decl::ObjCCompatibleAlias:
5767*67e74705SXin Li     if (const ObjCInterfaceDecl *Class
5768*67e74705SXin Li           = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
5769*67e74705SXin Li       if (const ObjCInterfaceDecl *Def = Class->getDefinition())
5770*67e74705SXin Li         return MakeCXCursor(Def, TU);
5771*67e74705SXin Li 
5772*67e74705SXin Li     return clang_getNullCursor();
5773*67e74705SXin Li 
5774*67e74705SXin Li   case Decl::Friend:
5775*67e74705SXin Li     if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5776*67e74705SXin Li       return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5777*67e74705SXin Li     return clang_getNullCursor();
5778*67e74705SXin Li 
5779*67e74705SXin Li   case Decl::FriendTemplate:
5780*67e74705SXin Li     if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5781*67e74705SXin Li       return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5782*67e74705SXin Li     return clang_getNullCursor();
5783*67e74705SXin Li   }
5784*67e74705SXin Li 
5785*67e74705SXin Li   return clang_getNullCursor();
5786*67e74705SXin Li }
5787*67e74705SXin Li 
clang_isCursorDefinition(CXCursor C)5788*67e74705SXin Li unsigned clang_isCursorDefinition(CXCursor C) {
5789*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
5790*67e74705SXin Li     return 0;
5791*67e74705SXin Li 
5792*67e74705SXin Li   return clang_getCursorDefinition(C) == C;
5793*67e74705SXin Li }
5794*67e74705SXin Li 
clang_getCanonicalCursor(CXCursor C)5795*67e74705SXin Li CXCursor clang_getCanonicalCursor(CXCursor C) {
5796*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
5797*67e74705SXin Li     return C;
5798*67e74705SXin Li 
5799*67e74705SXin Li   if (const Decl *D = getCursorDecl(C)) {
5800*67e74705SXin Li     if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
5801*67e74705SXin Li       if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5802*67e74705SXin Li         return MakeCXCursor(CatD, getCursorTU(C));
5803*67e74705SXin Li 
5804*67e74705SXin Li     if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5805*67e74705SXin Li       if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
5806*67e74705SXin Li         return MakeCXCursor(IFD, getCursorTU(C));
5807*67e74705SXin Li 
5808*67e74705SXin Li     return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5809*67e74705SXin Li   }
5810*67e74705SXin Li 
5811*67e74705SXin Li   return C;
5812*67e74705SXin Li }
5813*67e74705SXin Li 
clang_Cursor_getObjCSelectorIndex(CXCursor cursor)5814*67e74705SXin Li int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5815*67e74705SXin Li   return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5816*67e74705SXin Li }
5817*67e74705SXin Li 
clang_getNumOverloadedDecls(CXCursor C)5818*67e74705SXin Li unsigned clang_getNumOverloadedDecls(CXCursor C) {
5819*67e74705SXin Li   if (C.kind != CXCursor_OverloadedDeclRef)
5820*67e74705SXin Li     return 0;
5821*67e74705SXin Li 
5822*67e74705SXin Li   OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
5823*67e74705SXin Li   if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
5824*67e74705SXin Li     return E->getNumDecls();
5825*67e74705SXin Li 
5826*67e74705SXin Li   if (OverloadedTemplateStorage *S
5827*67e74705SXin Li                               = Storage.dyn_cast<OverloadedTemplateStorage*>())
5828*67e74705SXin Li     return S->size();
5829*67e74705SXin Li 
5830*67e74705SXin Li   const Decl *D = Storage.get<const Decl *>();
5831*67e74705SXin Li   if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
5832*67e74705SXin Li     return Using->shadow_size();
5833*67e74705SXin Li 
5834*67e74705SXin Li   return 0;
5835*67e74705SXin Li }
5836*67e74705SXin Li 
clang_getOverloadedDecl(CXCursor cursor,unsigned index)5837*67e74705SXin Li CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5838*67e74705SXin Li   if (cursor.kind != CXCursor_OverloadedDeclRef)
5839*67e74705SXin Li     return clang_getNullCursor();
5840*67e74705SXin Li 
5841*67e74705SXin Li   if (index >= clang_getNumOverloadedDecls(cursor))
5842*67e74705SXin Li     return clang_getNullCursor();
5843*67e74705SXin Li 
5844*67e74705SXin Li   CXTranslationUnit TU = getCursorTU(cursor);
5845*67e74705SXin Li   OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
5846*67e74705SXin Li   if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
5847*67e74705SXin Li     return MakeCXCursor(E->decls_begin()[index], TU);
5848*67e74705SXin Li 
5849*67e74705SXin Li   if (OverloadedTemplateStorage *S
5850*67e74705SXin Li                               = Storage.dyn_cast<OverloadedTemplateStorage*>())
5851*67e74705SXin Li     return MakeCXCursor(S->begin()[index], TU);
5852*67e74705SXin Li 
5853*67e74705SXin Li   const Decl *D = Storage.get<const Decl *>();
5854*67e74705SXin Li   if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
5855*67e74705SXin Li     // FIXME: This is, unfortunately, linear time.
5856*67e74705SXin Li     UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5857*67e74705SXin Li     std::advance(Pos, index);
5858*67e74705SXin Li     return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5859*67e74705SXin Li   }
5860*67e74705SXin Li 
5861*67e74705SXin Li   return clang_getNullCursor();
5862*67e74705SXin Li }
5863*67e74705SXin Li 
clang_getDefinitionSpellingAndExtent(CXCursor C,const char ** startBuf,const char ** endBuf,unsigned * startLine,unsigned * startColumn,unsigned * endLine,unsigned * endColumn)5864*67e74705SXin Li void clang_getDefinitionSpellingAndExtent(CXCursor C,
5865*67e74705SXin Li                                           const char **startBuf,
5866*67e74705SXin Li                                           const char **endBuf,
5867*67e74705SXin Li                                           unsigned *startLine,
5868*67e74705SXin Li                                           unsigned *startColumn,
5869*67e74705SXin Li                                           unsigned *endLine,
5870*67e74705SXin Li                                           unsigned *endColumn) {
5871*67e74705SXin Li   assert(getCursorDecl(C) && "CXCursor has null decl");
5872*67e74705SXin Li   const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
5873*67e74705SXin Li   CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5874*67e74705SXin Li 
5875*67e74705SXin Li   SourceManager &SM = FD->getASTContext().getSourceManager();
5876*67e74705SXin Li   *startBuf = SM.getCharacterData(Body->getLBracLoc());
5877*67e74705SXin Li   *endBuf = SM.getCharacterData(Body->getRBracLoc());
5878*67e74705SXin Li   *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5879*67e74705SXin Li   *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5880*67e74705SXin Li   *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5881*67e74705SXin Li   *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5882*67e74705SXin Li }
5883*67e74705SXin Li 
5884*67e74705SXin Li 
clang_getCursorReferenceNameRange(CXCursor C,unsigned NameFlags,unsigned PieceIndex)5885*67e74705SXin Li CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5886*67e74705SXin Li                                                 unsigned PieceIndex) {
5887*67e74705SXin Li   RefNamePieces Pieces;
5888*67e74705SXin Li 
5889*67e74705SXin Li   switch (C.kind) {
5890*67e74705SXin Li   case CXCursor_MemberRefExpr:
5891*67e74705SXin Li     if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
5892*67e74705SXin Li       Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5893*67e74705SXin Li                            E->getQualifierLoc().getSourceRange());
5894*67e74705SXin Li     break;
5895*67e74705SXin Li 
5896*67e74705SXin Li   case CXCursor_DeclRefExpr:
5897*67e74705SXin Li     if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
5898*67e74705SXin Li       SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
5899*67e74705SXin Li       Pieces =
5900*67e74705SXin Li           buildPieces(NameFlags, false, E->getNameInfo(),
5901*67e74705SXin Li                       E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
5902*67e74705SXin Li     }
5903*67e74705SXin Li     break;
5904*67e74705SXin Li 
5905*67e74705SXin Li   case CXCursor_CallExpr:
5906*67e74705SXin Li     if (const CXXOperatorCallExpr *OCE =
5907*67e74705SXin Li         dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
5908*67e74705SXin Li       const Expr *Callee = OCE->getCallee();
5909*67e74705SXin Li       if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
5910*67e74705SXin Li         Callee = ICE->getSubExpr();
5911*67e74705SXin Li 
5912*67e74705SXin Li       if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
5913*67e74705SXin Li         Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5914*67e74705SXin Li                              DRE->getQualifierLoc().getSourceRange());
5915*67e74705SXin Li     }
5916*67e74705SXin Li     break;
5917*67e74705SXin Li 
5918*67e74705SXin Li   default:
5919*67e74705SXin Li     break;
5920*67e74705SXin Li   }
5921*67e74705SXin Li 
5922*67e74705SXin Li   if (Pieces.empty()) {
5923*67e74705SXin Li     if (PieceIndex == 0)
5924*67e74705SXin Li       return clang_getCursorExtent(C);
5925*67e74705SXin Li   } else if (PieceIndex < Pieces.size()) {
5926*67e74705SXin Li       SourceRange R = Pieces[PieceIndex];
5927*67e74705SXin Li       if (R.isValid())
5928*67e74705SXin Li         return cxloc::translateSourceRange(getCursorContext(C), R);
5929*67e74705SXin Li   }
5930*67e74705SXin Li 
5931*67e74705SXin Li   return clang_getNullRange();
5932*67e74705SXin Li }
5933*67e74705SXin Li 
clang_enableStackTraces(void)5934*67e74705SXin Li void clang_enableStackTraces(void) {
5935*67e74705SXin Li   // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
5936*67e74705SXin Li   llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
5937*67e74705SXin Li }
5938*67e74705SXin Li 
clang_executeOnThread(void (* fn)(void *),void * user_data,unsigned stack_size)5939*67e74705SXin Li void clang_executeOnThread(void (*fn)(void*), void *user_data,
5940*67e74705SXin Li                            unsigned stack_size) {
5941*67e74705SXin Li   llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5942*67e74705SXin Li }
5943*67e74705SXin Li 
5944*67e74705SXin Li } // end: extern "C"
5945*67e74705SXin Li 
5946*67e74705SXin Li //===----------------------------------------------------------------------===//
5947*67e74705SXin Li // Token-based Operations.
5948*67e74705SXin Li //===----------------------------------------------------------------------===//
5949*67e74705SXin Li 
5950*67e74705SXin Li /* CXToken layout:
5951*67e74705SXin Li  *   int_data[0]: a CXTokenKind
5952*67e74705SXin Li  *   int_data[1]: starting token location
5953*67e74705SXin Li  *   int_data[2]: token length
5954*67e74705SXin Li  *   int_data[3]: reserved
5955*67e74705SXin Li  *   ptr_data: for identifiers and keywords, an IdentifierInfo*.
5956*67e74705SXin Li  *   otherwise unused.
5957*67e74705SXin Li  */
5958*67e74705SXin Li extern "C" {
5959*67e74705SXin Li 
clang_getTokenKind(CXToken CXTok)5960*67e74705SXin Li CXTokenKind clang_getTokenKind(CXToken CXTok) {
5961*67e74705SXin Li   return static_cast<CXTokenKind>(CXTok.int_data[0]);
5962*67e74705SXin Li }
5963*67e74705SXin Li 
clang_getTokenSpelling(CXTranslationUnit TU,CXToken CXTok)5964*67e74705SXin Li CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5965*67e74705SXin Li   switch (clang_getTokenKind(CXTok)) {
5966*67e74705SXin Li   case CXToken_Identifier:
5967*67e74705SXin Li   case CXToken_Keyword:
5968*67e74705SXin Li     // We know we have an IdentifierInfo*, so use that.
5969*67e74705SXin Li     return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
5970*67e74705SXin Li                             ->getNameStart());
5971*67e74705SXin Li 
5972*67e74705SXin Li   case CXToken_Literal: {
5973*67e74705SXin Li     // We have stashed the starting pointer in the ptr_data field. Use it.
5974*67e74705SXin Li     const char *Text = static_cast<const char *>(CXTok.ptr_data);
5975*67e74705SXin Li     return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
5976*67e74705SXin Li   }
5977*67e74705SXin Li 
5978*67e74705SXin Li   case CXToken_Punctuation:
5979*67e74705SXin Li   case CXToken_Comment:
5980*67e74705SXin Li     break;
5981*67e74705SXin Li   }
5982*67e74705SXin Li 
5983*67e74705SXin Li   if (isNotUsableTU(TU)) {
5984*67e74705SXin Li     LOG_BAD_TU(TU);
5985*67e74705SXin Li     return cxstring::createEmpty();
5986*67e74705SXin Li   }
5987*67e74705SXin Li 
5988*67e74705SXin Li   // We have to find the starting buffer pointer the hard way, by
5989*67e74705SXin Li   // deconstructing the source location.
5990*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5991*67e74705SXin Li   if (!CXXUnit)
5992*67e74705SXin Li     return cxstring::createEmpty();
5993*67e74705SXin Li 
5994*67e74705SXin Li   SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5995*67e74705SXin Li   std::pair<FileID, unsigned> LocInfo
5996*67e74705SXin Li     = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5997*67e74705SXin Li   bool Invalid = false;
5998*67e74705SXin Li   StringRef Buffer
5999*67e74705SXin Li     = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
6000*67e74705SXin Li   if (Invalid)
6001*67e74705SXin Li     return cxstring::createEmpty();
6002*67e74705SXin Li 
6003*67e74705SXin Li   return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
6004*67e74705SXin Li }
6005*67e74705SXin Li 
clang_getTokenLocation(CXTranslationUnit TU,CXToken CXTok)6006*67e74705SXin Li CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
6007*67e74705SXin Li   if (isNotUsableTU(TU)) {
6008*67e74705SXin Li     LOG_BAD_TU(TU);
6009*67e74705SXin Li     return clang_getNullLocation();
6010*67e74705SXin Li   }
6011*67e74705SXin Li 
6012*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6013*67e74705SXin Li   if (!CXXUnit)
6014*67e74705SXin Li     return clang_getNullLocation();
6015*67e74705SXin Li 
6016*67e74705SXin Li   return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
6017*67e74705SXin Li                         SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6018*67e74705SXin Li }
6019*67e74705SXin Li 
clang_getTokenExtent(CXTranslationUnit TU,CXToken CXTok)6020*67e74705SXin Li CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
6021*67e74705SXin Li   if (isNotUsableTU(TU)) {
6022*67e74705SXin Li     LOG_BAD_TU(TU);
6023*67e74705SXin Li     return clang_getNullRange();
6024*67e74705SXin Li   }
6025*67e74705SXin Li 
6026*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6027*67e74705SXin Li   if (!CXXUnit)
6028*67e74705SXin Li     return clang_getNullRange();
6029*67e74705SXin Li 
6030*67e74705SXin Li   return cxloc::translateSourceRange(CXXUnit->getASTContext(),
6031*67e74705SXin Li                         SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
6032*67e74705SXin Li }
6033*67e74705SXin Li 
getTokens(ASTUnit * CXXUnit,SourceRange Range,SmallVectorImpl<CXToken> & CXTokens)6034*67e74705SXin Li static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6035*67e74705SXin Li                       SmallVectorImpl<CXToken> &CXTokens) {
6036*67e74705SXin Li   SourceManager &SourceMgr = CXXUnit->getSourceManager();
6037*67e74705SXin Li   std::pair<FileID, unsigned> BeginLocInfo
6038*67e74705SXin Li     = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6039*67e74705SXin Li   std::pair<FileID, unsigned> EndLocInfo
6040*67e74705SXin Li     = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
6041*67e74705SXin Li 
6042*67e74705SXin Li   // Cannot tokenize across files.
6043*67e74705SXin Li   if (BeginLocInfo.first != EndLocInfo.first)
6044*67e74705SXin Li     return;
6045*67e74705SXin Li 
6046*67e74705SXin Li   // Create a lexer
6047*67e74705SXin Li   bool Invalid = false;
6048*67e74705SXin Li   StringRef Buffer
6049*67e74705SXin Li     = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6050*67e74705SXin Li   if (Invalid)
6051*67e74705SXin Li     return;
6052*67e74705SXin Li 
6053*67e74705SXin Li   Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6054*67e74705SXin Li             CXXUnit->getASTContext().getLangOpts(),
6055*67e74705SXin Li             Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
6056*67e74705SXin Li   Lex.SetCommentRetentionState(true);
6057*67e74705SXin Li 
6058*67e74705SXin Li   // Lex tokens until we hit the end of the range.
6059*67e74705SXin Li   const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6060*67e74705SXin Li   Token Tok;
6061*67e74705SXin Li   bool previousWasAt = false;
6062*67e74705SXin Li   do {
6063*67e74705SXin Li     // Lex the next token
6064*67e74705SXin Li     Lex.LexFromRawLexer(Tok);
6065*67e74705SXin Li     if (Tok.is(tok::eof))
6066*67e74705SXin Li       break;
6067*67e74705SXin Li 
6068*67e74705SXin Li     // Initialize the CXToken.
6069*67e74705SXin Li     CXToken CXTok;
6070*67e74705SXin Li 
6071*67e74705SXin Li     //   - Common fields
6072*67e74705SXin Li     CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6073*67e74705SXin Li     CXTok.int_data[2] = Tok.getLength();
6074*67e74705SXin Li     CXTok.int_data[3] = 0;
6075*67e74705SXin Li 
6076*67e74705SXin Li     //   - Kind-specific fields
6077*67e74705SXin Li     if (Tok.isLiteral()) {
6078*67e74705SXin Li       CXTok.int_data[0] = CXToken_Literal;
6079*67e74705SXin Li       CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
6080*67e74705SXin Li     } else if (Tok.is(tok::raw_identifier)) {
6081*67e74705SXin Li       // Lookup the identifier to determine whether we have a keyword.
6082*67e74705SXin Li       IdentifierInfo *II
6083*67e74705SXin Li         = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
6084*67e74705SXin Li 
6085*67e74705SXin Li       if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6086*67e74705SXin Li         CXTok.int_data[0] = CXToken_Keyword;
6087*67e74705SXin Li       }
6088*67e74705SXin Li       else {
6089*67e74705SXin Li         CXTok.int_data[0] = Tok.is(tok::identifier)
6090*67e74705SXin Li           ? CXToken_Identifier
6091*67e74705SXin Li           : CXToken_Keyword;
6092*67e74705SXin Li       }
6093*67e74705SXin Li       CXTok.ptr_data = II;
6094*67e74705SXin Li     } else if (Tok.is(tok::comment)) {
6095*67e74705SXin Li       CXTok.int_data[0] = CXToken_Comment;
6096*67e74705SXin Li       CXTok.ptr_data = nullptr;
6097*67e74705SXin Li     } else {
6098*67e74705SXin Li       CXTok.int_data[0] = CXToken_Punctuation;
6099*67e74705SXin Li       CXTok.ptr_data = nullptr;
6100*67e74705SXin Li     }
6101*67e74705SXin Li     CXTokens.push_back(CXTok);
6102*67e74705SXin Li     previousWasAt = Tok.is(tok::at);
6103*67e74705SXin Li   } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
6104*67e74705SXin Li }
6105*67e74705SXin Li 
clang_tokenize(CXTranslationUnit TU,CXSourceRange Range,CXToken ** Tokens,unsigned * NumTokens)6106*67e74705SXin Li void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
6107*67e74705SXin Li                     CXToken **Tokens, unsigned *NumTokens) {
6108*67e74705SXin Li   LOG_FUNC_SECTION {
6109*67e74705SXin Li     *Log << TU << ' ' << Range;
6110*67e74705SXin Li   }
6111*67e74705SXin Li 
6112*67e74705SXin Li   if (Tokens)
6113*67e74705SXin Li     *Tokens = nullptr;
6114*67e74705SXin Li   if (NumTokens)
6115*67e74705SXin Li     *NumTokens = 0;
6116*67e74705SXin Li 
6117*67e74705SXin Li   if (isNotUsableTU(TU)) {
6118*67e74705SXin Li     LOG_BAD_TU(TU);
6119*67e74705SXin Li     return;
6120*67e74705SXin Li   }
6121*67e74705SXin Li 
6122*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6123*67e74705SXin Li   if (!CXXUnit || !Tokens || !NumTokens)
6124*67e74705SXin Li     return;
6125*67e74705SXin Li 
6126*67e74705SXin Li   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6127*67e74705SXin Li 
6128*67e74705SXin Li   SourceRange R = cxloc::translateCXSourceRange(Range);
6129*67e74705SXin Li   if (R.isInvalid())
6130*67e74705SXin Li     return;
6131*67e74705SXin Li 
6132*67e74705SXin Li   SmallVector<CXToken, 32> CXTokens;
6133*67e74705SXin Li   getTokens(CXXUnit, R, CXTokens);
6134*67e74705SXin Li 
6135*67e74705SXin Li   if (CXTokens.empty())
6136*67e74705SXin Li     return;
6137*67e74705SXin Li 
6138*67e74705SXin Li   *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
6139*67e74705SXin Li   memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6140*67e74705SXin Li   *NumTokens = CXTokens.size();
6141*67e74705SXin Li }
6142*67e74705SXin Li 
clang_disposeTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens)6143*67e74705SXin Li void clang_disposeTokens(CXTranslationUnit TU,
6144*67e74705SXin Li                          CXToken *Tokens, unsigned NumTokens) {
6145*67e74705SXin Li   free(Tokens);
6146*67e74705SXin Li }
6147*67e74705SXin Li 
6148*67e74705SXin Li } // end: extern "C"
6149*67e74705SXin Li 
6150*67e74705SXin Li //===----------------------------------------------------------------------===//
6151*67e74705SXin Li // Token annotation APIs.
6152*67e74705SXin Li //===----------------------------------------------------------------------===//
6153*67e74705SXin Li 
6154*67e74705SXin Li static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6155*67e74705SXin Li                                                      CXCursor parent,
6156*67e74705SXin Li                                                      CXClientData client_data);
6157*67e74705SXin Li static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6158*67e74705SXin Li                                               CXClientData client_data);
6159*67e74705SXin Li 
6160*67e74705SXin Li namespace {
6161*67e74705SXin Li class AnnotateTokensWorker {
6162*67e74705SXin Li   CXToken *Tokens;
6163*67e74705SXin Li   CXCursor *Cursors;
6164*67e74705SXin Li   unsigned NumTokens;
6165*67e74705SXin Li   unsigned TokIdx;
6166*67e74705SXin Li   unsigned PreprocessingTokIdx;
6167*67e74705SXin Li   CursorVisitor AnnotateVis;
6168*67e74705SXin Li   SourceManager &SrcMgr;
6169*67e74705SXin Li   bool HasContextSensitiveKeywords;
6170*67e74705SXin Li 
6171*67e74705SXin Li   struct PostChildrenInfo {
6172*67e74705SXin Li     CXCursor Cursor;
6173*67e74705SXin Li     SourceRange CursorRange;
6174*67e74705SXin Li     unsigned BeforeReachingCursorIdx;
6175*67e74705SXin Li     unsigned BeforeChildrenTokenIdx;
6176*67e74705SXin Li   };
6177*67e74705SXin Li   SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
6178*67e74705SXin Li 
getTok(unsigned Idx)6179*67e74705SXin Li   CXToken &getTok(unsigned Idx) {
6180*67e74705SXin Li     assert(Idx < NumTokens);
6181*67e74705SXin Li     return Tokens[Idx];
6182*67e74705SXin Li   }
getTok(unsigned Idx) const6183*67e74705SXin Li   const CXToken &getTok(unsigned Idx) const {
6184*67e74705SXin Li     assert(Idx < NumTokens);
6185*67e74705SXin Li     return Tokens[Idx];
6186*67e74705SXin Li   }
MoreTokens() const6187*67e74705SXin Li   bool MoreTokens() const { return TokIdx < NumTokens; }
NextToken() const6188*67e74705SXin Li   unsigned NextToken() const { return TokIdx; }
AdvanceToken()6189*67e74705SXin Li   void AdvanceToken() { ++TokIdx; }
GetTokenLoc(unsigned tokI)6190*67e74705SXin Li   SourceLocation GetTokenLoc(unsigned tokI) {
6191*67e74705SXin Li     return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
6192*67e74705SXin Li   }
isFunctionMacroToken(unsigned tokI) const6193*67e74705SXin Li   bool isFunctionMacroToken(unsigned tokI) const {
6194*67e74705SXin Li     return getTok(tokI).int_data[3] != 0;
6195*67e74705SXin Li   }
getFunctionMacroTokenLoc(unsigned tokI) const6196*67e74705SXin Li   SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
6197*67e74705SXin Li     return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
6198*67e74705SXin Li   }
6199*67e74705SXin Li 
6200*67e74705SXin Li   void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
6201*67e74705SXin Li   bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
6202*67e74705SXin Li                                              SourceRange);
6203*67e74705SXin Li 
6204*67e74705SXin Li public:
AnnotateTokensWorker(CXToken * tokens,CXCursor * cursors,unsigned numTokens,CXTranslationUnit TU,SourceRange RegionOfInterest)6205*67e74705SXin Li   AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
6206*67e74705SXin Li                        CXTranslationUnit TU, SourceRange RegionOfInterest)
6207*67e74705SXin Li     : Tokens(tokens), Cursors(cursors),
6208*67e74705SXin Li       NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
6209*67e74705SXin Li       AnnotateVis(TU,
6210*67e74705SXin Li                   AnnotateTokensVisitor, this,
6211*67e74705SXin Li                   /*VisitPreprocessorLast=*/true,
6212*67e74705SXin Li                   /*VisitIncludedEntities=*/false,
6213*67e74705SXin Li                   RegionOfInterest,
6214*67e74705SXin Li                   /*VisitDeclsOnly=*/false,
6215*67e74705SXin Li                   AnnotateTokensPostChildrenVisitor),
6216*67e74705SXin Li       SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
6217*67e74705SXin Li       HasContextSensitiveKeywords(false) { }
6218*67e74705SXin Li 
VisitChildren(CXCursor C)6219*67e74705SXin Li   void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6220*67e74705SXin Li   enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
6221*67e74705SXin Li   bool postVisitChildren(CXCursor cursor);
6222*67e74705SXin Li   void AnnotateTokens();
6223*67e74705SXin Li 
6224*67e74705SXin Li   /// \brief Determine whether the annotator saw any cursors that have
6225*67e74705SXin Li   /// context-sensitive keywords.
hasContextSensitiveKeywords() const6226*67e74705SXin Li   bool hasContextSensitiveKeywords() const {
6227*67e74705SXin Li     return HasContextSensitiveKeywords;
6228*67e74705SXin Li   }
6229*67e74705SXin Li 
~AnnotateTokensWorker()6230*67e74705SXin Li   ~AnnotateTokensWorker() {
6231*67e74705SXin Li     assert(PostChildrenInfos.empty());
6232*67e74705SXin Li   }
6233*67e74705SXin Li };
6234*67e74705SXin Li }
6235*67e74705SXin Li 
AnnotateTokens()6236*67e74705SXin Li void AnnotateTokensWorker::AnnotateTokens() {
6237*67e74705SXin Li   // Walk the AST within the region of interest, annotating tokens
6238*67e74705SXin Li   // along the way.
6239*67e74705SXin Li   AnnotateVis.visitFileRegion();
6240*67e74705SXin Li }
6241*67e74705SXin Li 
updateCursorAnnotation(CXCursor & Cursor,const CXCursor & updateC)6242*67e74705SXin Li static inline void updateCursorAnnotation(CXCursor &Cursor,
6243*67e74705SXin Li                                           const CXCursor &updateC) {
6244*67e74705SXin Li   if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
6245*67e74705SXin Li     return;
6246*67e74705SXin Li   Cursor = updateC;
6247*67e74705SXin Li }
6248*67e74705SXin Li 
6249*67e74705SXin Li /// \brief It annotates and advances tokens with a cursor until the comparison
6250*67e74705SXin Li //// between the cursor location and the source range is the same as
6251*67e74705SXin Li /// \arg compResult.
6252*67e74705SXin Li ///
6253*67e74705SXin Li /// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
6254*67e74705SXin Li /// Pass RangeOverlap to annotate tokens inside a range.
annotateAndAdvanceTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)6255*67e74705SXin Li void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
6256*67e74705SXin Li                                                RangeComparisonResult compResult,
6257*67e74705SXin Li                                                SourceRange range) {
6258*67e74705SXin Li   while (MoreTokens()) {
6259*67e74705SXin Li     const unsigned I = NextToken();
6260*67e74705SXin Li     if (isFunctionMacroToken(I))
6261*67e74705SXin Li       if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
6262*67e74705SXin Li         return;
6263*67e74705SXin Li 
6264*67e74705SXin Li     SourceLocation TokLoc = GetTokenLoc(I);
6265*67e74705SXin Li     if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6266*67e74705SXin Li       updateCursorAnnotation(Cursors[I], updateC);
6267*67e74705SXin Li       AdvanceToken();
6268*67e74705SXin Li       continue;
6269*67e74705SXin Li     }
6270*67e74705SXin Li     break;
6271*67e74705SXin Li   }
6272*67e74705SXin Li }
6273*67e74705SXin Li 
6274*67e74705SXin Li /// \brief Special annotation handling for macro argument tokens.
6275*67e74705SXin Li /// \returns true if it advanced beyond all macro tokens, false otherwise.
annotateAndAdvanceFunctionMacroTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)6276*67e74705SXin Li bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
6277*67e74705SXin Li                                                CXCursor updateC,
6278*67e74705SXin Li                                                RangeComparisonResult compResult,
6279*67e74705SXin Li                                                SourceRange range) {
6280*67e74705SXin Li   assert(MoreTokens());
6281*67e74705SXin Li   assert(isFunctionMacroToken(NextToken()) &&
6282*67e74705SXin Li          "Should be called only for macro arg tokens");
6283*67e74705SXin Li 
6284*67e74705SXin Li   // This works differently than annotateAndAdvanceTokens; because expanded
6285*67e74705SXin Li   // macro arguments can have arbitrary translation-unit source order, we do not
6286*67e74705SXin Li   // advance the token index one by one until a token fails the range test.
6287*67e74705SXin Li   // We only advance once past all of the macro arg tokens if all of them
6288*67e74705SXin Li   // pass the range test. If one of them fails we keep the token index pointing
6289*67e74705SXin Li   // at the start of the macro arg tokens so that the failing token will be
6290*67e74705SXin Li   // annotated by a subsequent annotation try.
6291*67e74705SXin Li 
6292*67e74705SXin Li   bool atLeastOneCompFail = false;
6293*67e74705SXin Li 
6294*67e74705SXin Li   unsigned I = NextToken();
6295*67e74705SXin Li   for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
6296*67e74705SXin Li     SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
6297*67e74705SXin Li     if (TokLoc.isFileID())
6298*67e74705SXin Li       continue; // not macro arg token, it's parens or comma.
6299*67e74705SXin Li     if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
6300*67e74705SXin Li       if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
6301*67e74705SXin Li         Cursors[I] = updateC;
6302*67e74705SXin Li     } else
6303*67e74705SXin Li       atLeastOneCompFail = true;
6304*67e74705SXin Li   }
6305*67e74705SXin Li 
6306*67e74705SXin Li   if (atLeastOneCompFail)
6307*67e74705SXin Li     return false;
6308*67e74705SXin Li 
6309*67e74705SXin Li   TokIdx = I; // All of the tokens were handled, advance beyond all of them.
6310*67e74705SXin Li   return true;
6311*67e74705SXin Li }
6312*67e74705SXin Li 
6313*67e74705SXin Li enum CXChildVisitResult
Visit(CXCursor cursor,CXCursor parent)6314*67e74705SXin Li AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
6315*67e74705SXin Li   SourceRange cursorRange = getRawCursorExtent(cursor);
6316*67e74705SXin Li   if (cursorRange.isInvalid())
6317*67e74705SXin Li     return CXChildVisit_Recurse;
6318*67e74705SXin Li 
6319*67e74705SXin Li   if (!HasContextSensitiveKeywords) {
6320*67e74705SXin Li     // Objective-C properties can have context-sensitive keywords.
6321*67e74705SXin Li     if (cursor.kind == CXCursor_ObjCPropertyDecl) {
6322*67e74705SXin Li       if (const ObjCPropertyDecl *Property
6323*67e74705SXin Li                   = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
6324*67e74705SXin Li         HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
6325*67e74705SXin Li     }
6326*67e74705SXin Li     // Objective-C methods can have context-sensitive keywords.
6327*67e74705SXin Li     else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
6328*67e74705SXin Li              cursor.kind == CXCursor_ObjCClassMethodDecl) {
6329*67e74705SXin Li       if (const ObjCMethodDecl *Method
6330*67e74705SXin Li             = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6331*67e74705SXin Li         if (Method->getObjCDeclQualifier())
6332*67e74705SXin Li           HasContextSensitiveKeywords = true;
6333*67e74705SXin Li         else {
6334*67e74705SXin Li           for (const auto *P : Method->parameters()) {
6335*67e74705SXin Li             if (P->getObjCDeclQualifier()) {
6336*67e74705SXin Li               HasContextSensitiveKeywords = true;
6337*67e74705SXin Li               break;
6338*67e74705SXin Li             }
6339*67e74705SXin Li           }
6340*67e74705SXin Li         }
6341*67e74705SXin Li       }
6342*67e74705SXin Li     }
6343*67e74705SXin Li     // C++ methods can have context-sensitive keywords.
6344*67e74705SXin Li     else if (cursor.kind == CXCursor_CXXMethod) {
6345*67e74705SXin Li       if (const CXXMethodDecl *Method
6346*67e74705SXin Li                   = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
6347*67e74705SXin Li         if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
6348*67e74705SXin Li           HasContextSensitiveKeywords = true;
6349*67e74705SXin Li       }
6350*67e74705SXin Li     }
6351*67e74705SXin Li     // C++ classes can have context-sensitive keywords.
6352*67e74705SXin Li     else if (cursor.kind == CXCursor_StructDecl ||
6353*67e74705SXin Li              cursor.kind == CXCursor_ClassDecl ||
6354*67e74705SXin Li              cursor.kind == CXCursor_ClassTemplate ||
6355*67e74705SXin Li              cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
6356*67e74705SXin Li       if (const Decl *D = getCursorDecl(cursor))
6357*67e74705SXin Li         if (D->hasAttr<FinalAttr>())
6358*67e74705SXin Li           HasContextSensitiveKeywords = true;
6359*67e74705SXin Li     }
6360*67e74705SXin Li   }
6361*67e74705SXin Li 
6362*67e74705SXin Li   // Don't override a property annotation with its getter/setter method.
6363*67e74705SXin Li   if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
6364*67e74705SXin Li       parent.kind == CXCursor_ObjCPropertyDecl)
6365*67e74705SXin Li     return CXChildVisit_Continue;
6366*67e74705SXin Li 
6367*67e74705SXin Li   if (clang_isPreprocessing(cursor.kind)) {
6368*67e74705SXin Li     // Items in the preprocessing record are kept separate from items in
6369*67e74705SXin Li     // declarations, so we keep a separate token index.
6370*67e74705SXin Li     unsigned SavedTokIdx = TokIdx;
6371*67e74705SXin Li     TokIdx = PreprocessingTokIdx;
6372*67e74705SXin Li 
6373*67e74705SXin Li     // Skip tokens up until we catch up to the beginning of the preprocessing
6374*67e74705SXin Li     // entry.
6375*67e74705SXin Li     while (MoreTokens()) {
6376*67e74705SXin Li       const unsigned I = NextToken();
6377*67e74705SXin Li       SourceLocation TokLoc = GetTokenLoc(I);
6378*67e74705SXin Li       switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6379*67e74705SXin Li       case RangeBefore:
6380*67e74705SXin Li         AdvanceToken();
6381*67e74705SXin Li         continue;
6382*67e74705SXin Li       case RangeAfter:
6383*67e74705SXin Li       case RangeOverlap:
6384*67e74705SXin Li         break;
6385*67e74705SXin Li       }
6386*67e74705SXin Li       break;
6387*67e74705SXin Li     }
6388*67e74705SXin Li 
6389*67e74705SXin Li     // Look at all of the tokens within this range.
6390*67e74705SXin Li     while (MoreTokens()) {
6391*67e74705SXin Li       const unsigned I = NextToken();
6392*67e74705SXin Li       SourceLocation TokLoc = GetTokenLoc(I);
6393*67e74705SXin Li       switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
6394*67e74705SXin Li       case RangeBefore:
6395*67e74705SXin Li         llvm_unreachable("Infeasible");
6396*67e74705SXin Li       case RangeAfter:
6397*67e74705SXin Li         break;
6398*67e74705SXin Li       case RangeOverlap:
6399*67e74705SXin Li         // For macro expansions, just note where the beginning of the macro
6400*67e74705SXin Li         // expansion occurs.
6401*67e74705SXin Li         if (cursor.kind == CXCursor_MacroExpansion) {
6402*67e74705SXin Li           if (TokLoc == cursorRange.getBegin())
6403*67e74705SXin Li             Cursors[I] = cursor;
6404*67e74705SXin Li           AdvanceToken();
6405*67e74705SXin Li           break;
6406*67e74705SXin Li         }
6407*67e74705SXin Li         // We may have already annotated macro names inside macro definitions.
6408*67e74705SXin Li         if (Cursors[I].kind != CXCursor_MacroExpansion)
6409*67e74705SXin Li           Cursors[I] = cursor;
6410*67e74705SXin Li         AdvanceToken();
6411*67e74705SXin Li         continue;
6412*67e74705SXin Li       }
6413*67e74705SXin Li       break;
6414*67e74705SXin Li     }
6415*67e74705SXin Li 
6416*67e74705SXin Li     // Save the preprocessing token index; restore the non-preprocessing
6417*67e74705SXin Li     // token index.
6418*67e74705SXin Li     PreprocessingTokIdx = TokIdx;
6419*67e74705SXin Li     TokIdx = SavedTokIdx;
6420*67e74705SXin Li     return CXChildVisit_Recurse;
6421*67e74705SXin Li   }
6422*67e74705SXin Li 
6423*67e74705SXin Li   if (cursorRange.isInvalid())
6424*67e74705SXin Li     return CXChildVisit_Continue;
6425*67e74705SXin Li 
6426*67e74705SXin Li   unsigned BeforeReachingCursorIdx = NextToken();
6427*67e74705SXin Li   const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
6428*67e74705SXin Li   const enum CXCursorKind K = clang_getCursorKind(parent);
6429*67e74705SXin Li   const CXCursor updateC =
6430*67e74705SXin Li     (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
6431*67e74705SXin Li      // Attributes are annotated out-of-order, skip tokens until we reach it.
6432*67e74705SXin Li      clang_isAttribute(cursor.kind))
6433*67e74705SXin Li      ? clang_getNullCursor() : parent;
6434*67e74705SXin Li 
6435*67e74705SXin Li   annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
6436*67e74705SXin Li 
6437*67e74705SXin Li   // Avoid having the cursor of an expression "overwrite" the annotation of the
6438*67e74705SXin Li   // variable declaration that it belongs to.
6439*67e74705SXin Li   // This can happen for C++ constructor expressions whose range generally
6440*67e74705SXin Li   // include the variable declaration, e.g.:
6441*67e74705SXin Li   //  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
6442*67e74705SXin Li   if (clang_isExpression(cursorK) && MoreTokens()) {
6443*67e74705SXin Li     const Expr *E = getCursorExpr(cursor);
6444*67e74705SXin Li     if (const Decl *D = getCursorParentDecl(cursor)) {
6445*67e74705SXin Li       const unsigned I = NextToken();
6446*67e74705SXin Li       if (E->getLocStart().isValid() && D->getLocation().isValid() &&
6447*67e74705SXin Li           E->getLocStart() == D->getLocation() &&
6448*67e74705SXin Li           E->getLocStart() == GetTokenLoc(I)) {
6449*67e74705SXin Li         updateCursorAnnotation(Cursors[I], updateC);
6450*67e74705SXin Li         AdvanceToken();
6451*67e74705SXin Li       }
6452*67e74705SXin Li     }
6453*67e74705SXin Li   }
6454*67e74705SXin Li 
6455*67e74705SXin Li   // Before recursing into the children keep some state that we are going
6456*67e74705SXin Li   // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
6457*67e74705SXin Li   // extra work after the child nodes are visited.
6458*67e74705SXin Li   // Note that we don't call VisitChildren here to avoid traversing statements
6459*67e74705SXin Li   // code-recursively which can blow the stack.
6460*67e74705SXin Li 
6461*67e74705SXin Li   PostChildrenInfo Info;
6462*67e74705SXin Li   Info.Cursor = cursor;
6463*67e74705SXin Li   Info.CursorRange = cursorRange;
6464*67e74705SXin Li   Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
6465*67e74705SXin Li   Info.BeforeChildrenTokenIdx = NextToken();
6466*67e74705SXin Li   PostChildrenInfos.push_back(Info);
6467*67e74705SXin Li 
6468*67e74705SXin Li   return CXChildVisit_Recurse;
6469*67e74705SXin Li }
6470*67e74705SXin Li 
postVisitChildren(CXCursor cursor)6471*67e74705SXin Li bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
6472*67e74705SXin Li   if (PostChildrenInfos.empty())
6473*67e74705SXin Li     return false;
6474*67e74705SXin Li   const PostChildrenInfo &Info = PostChildrenInfos.back();
6475*67e74705SXin Li   if (!clang_equalCursors(Info.Cursor, cursor))
6476*67e74705SXin Li     return false;
6477*67e74705SXin Li 
6478*67e74705SXin Li   const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
6479*67e74705SXin Li   const unsigned AfterChildren = NextToken();
6480*67e74705SXin Li   SourceRange cursorRange = Info.CursorRange;
6481*67e74705SXin Li 
6482*67e74705SXin Li   // Scan the tokens that are at the end of the cursor, but are not captured
6483*67e74705SXin Li   // but the child cursors.
6484*67e74705SXin Li   annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
6485*67e74705SXin Li 
6486*67e74705SXin Li   // Scan the tokens that are at the beginning of the cursor, but are not
6487*67e74705SXin Li   // capture by the child cursors.
6488*67e74705SXin Li   for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
6489*67e74705SXin Li     if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
6490*67e74705SXin Li       break;
6491*67e74705SXin Li 
6492*67e74705SXin Li     Cursors[I] = cursor;
6493*67e74705SXin Li   }
6494*67e74705SXin Li 
6495*67e74705SXin Li   // Attributes are annotated out-of-order, rewind TokIdx to when we first
6496*67e74705SXin Li   // encountered the attribute cursor.
6497*67e74705SXin Li   if (clang_isAttribute(cursor.kind))
6498*67e74705SXin Li     TokIdx = Info.BeforeReachingCursorIdx;
6499*67e74705SXin Li 
6500*67e74705SXin Li   PostChildrenInfos.pop_back();
6501*67e74705SXin Li   return false;
6502*67e74705SXin Li }
6503*67e74705SXin Li 
AnnotateTokensVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)6504*67e74705SXin Li static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6505*67e74705SXin Li                                                      CXCursor parent,
6506*67e74705SXin Li                                                      CXClientData client_data) {
6507*67e74705SXin Li   return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
6508*67e74705SXin Li }
6509*67e74705SXin Li 
AnnotateTokensPostChildrenVisitor(CXCursor cursor,CXClientData client_data)6510*67e74705SXin Li static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6511*67e74705SXin Li                                               CXClientData client_data) {
6512*67e74705SXin Li   return static_cast<AnnotateTokensWorker*>(client_data)->
6513*67e74705SXin Li                                                       postVisitChildren(cursor);
6514*67e74705SXin Li }
6515*67e74705SXin Li 
6516*67e74705SXin Li namespace {
6517*67e74705SXin Li 
6518*67e74705SXin Li /// \brief Uses the macro expansions in the preprocessing record to find
6519*67e74705SXin Li /// and mark tokens that are macro arguments. This info is used by the
6520*67e74705SXin Li /// AnnotateTokensWorker.
6521*67e74705SXin Li class MarkMacroArgTokensVisitor {
6522*67e74705SXin Li   SourceManager &SM;
6523*67e74705SXin Li   CXToken *Tokens;
6524*67e74705SXin Li   unsigned NumTokens;
6525*67e74705SXin Li   unsigned CurIdx;
6526*67e74705SXin Li 
6527*67e74705SXin Li public:
MarkMacroArgTokensVisitor(SourceManager & SM,CXToken * tokens,unsigned numTokens)6528*67e74705SXin Li   MarkMacroArgTokensVisitor(SourceManager &SM,
6529*67e74705SXin Li                             CXToken *tokens, unsigned numTokens)
6530*67e74705SXin Li     : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6531*67e74705SXin Li 
visit(CXCursor cursor,CXCursor parent)6532*67e74705SXin Li   CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6533*67e74705SXin Li     if (cursor.kind != CXCursor_MacroExpansion)
6534*67e74705SXin Li       return CXChildVisit_Continue;
6535*67e74705SXin Li 
6536*67e74705SXin Li     SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
6537*67e74705SXin Li     if (macroRange.getBegin() == macroRange.getEnd())
6538*67e74705SXin Li       return CXChildVisit_Continue; // it's not a function macro.
6539*67e74705SXin Li 
6540*67e74705SXin Li     for (; CurIdx < NumTokens; ++CurIdx) {
6541*67e74705SXin Li       if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6542*67e74705SXin Li                                         macroRange.getBegin()))
6543*67e74705SXin Li         break;
6544*67e74705SXin Li     }
6545*67e74705SXin Li 
6546*67e74705SXin Li     if (CurIdx == NumTokens)
6547*67e74705SXin Li       return CXChildVisit_Break;
6548*67e74705SXin Li 
6549*67e74705SXin Li     for (; CurIdx < NumTokens; ++CurIdx) {
6550*67e74705SXin Li       SourceLocation tokLoc = getTokenLoc(CurIdx);
6551*67e74705SXin Li       if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6552*67e74705SXin Li         break;
6553*67e74705SXin Li 
6554*67e74705SXin Li       setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6555*67e74705SXin Li     }
6556*67e74705SXin Li 
6557*67e74705SXin Li     if (CurIdx == NumTokens)
6558*67e74705SXin Li       return CXChildVisit_Break;
6559*67e74705SXin Li 
6560*67e74705SXin Li     return CXChildVisit_Continue;
6561*67e74705SXin Li   }
6562*67e74705SXin Li 
6563*67e74705SXin Li private:
getTok(unsigned Idx)6564*67e74705SXin Li   CXToken &getTok(unsigned Idx) {
6565*67e74705SXin Li     assert(Idx < NumTokens);
6566*67e74705SXin Li     return Tokens[Idx];
6567*67e74705SXin Li   }
getTok(unsigned Idx) const6568*67e74705SXin Li   const CXToken &getTok(unsigned Idx) const {
6569*67e74705SXin Li     assert(Idx < NumTokens);
6570*67e74705SXin Li     return Tokens[Idx];
6571*67e74705SXin Li   }
6572*67e74705SXin Li 
getTokenLoc(unsigned tokI)6573*67e74705SXin Li   SourceLocation getTokenLoc(unsigned tokI) {
6574*67e74705SXin Li     return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
6575*67e74705SXin Li   }
6576*67e74705SXin Li 
setFunctionMacroTokenLoc(unsigned tokI,SourceLocation loc)6577*67e74705SXin Li   void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6578*67e74705SXin Li     // The third field is reserved and currently not used. Use it here
6579*67e74705SXin Li     // to mark macro arg expanded tokens with their expanded locations.
6580*67e74705SXin Li     getTok(tokI).int_data[3] = loc.getRawEncoding();
6581*67e74705SXin Li   }
6582*67e74705SXin Li };
6583*67e74705SXin Li 
6584*67e74705SXin Li } // end anonymous namespace
6585*67e74705SXin Li 
6586*67e74705SXin Li static CXChildVisitResult
MarkMacroArgTokensVisitorDelegate(CXCursor cursor,CXCursor parent,CXClientData client_data)6587*67e74705SXin Li MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6588*67e74705SXin Li                                   CXClientData client_data) {
6589*67e74705SXin Li   return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6590*67e74705SXin Li                                                                      parent);
6591*67e74705SXin Li }
6592*67e74705SXin Li 
6593*67e74705SXin Li /// \brief Used by \c annotatePreprocessorTokens.
6594*67e74705SXin Li /// \returns true if lexing was finished, false otherwise.
lexNext(Lexer & Lex,Token & Tok,unsigned & NextIdx,unsigned NumTokens)6595*67e74705SXin Li static bool lexNext(Lexer &Lex, Token &Tok,
6596*67e74705SXin Li                    unsigned &NextIdx, unsigned NumTokens) {
6597*67e74705SXin Li   if (NextIdx >= NumTokens)
6598*67e74705SXin Li     return true;
6599*67e74705SXin Li 
6600*67e74705SXin Li   ++NextIdx;
6601*67e74705SXin Li   Lex.LexFromRawLexer(Tok);
6602*67e74705SXin Li   return Tok.is(tok::eof);
6603*67e74705SXin Li }
6604*67e74705SXin Li 
annotatePreprocessorTokens(CXTranslationUnit TU,SourceRange RegionOfInterest,CXCursor * Cursors,CXToken * Tokens,unsigned NumTokens)6605*67e74705SXin Li static void annotatePreprocessorTokens(CXTranslationUnit TU,
6606*67e74705SXin Li                                        SourceRange RegionOfInterest,
6607*67e74705SXin Li                                        CXCursor *Cursors,
6608*67e74705SXin Li                                        CXToken *Tokens,
6609*67e74705SXin Li                                        unsigned NumTokens) {
6610*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6611*67e74705SXin Li 
6612*67e74705SXin Li   Preprocessor &PP = CXXUnit->getPreprocessor();
6613*67e74705SXin Li   SourceManager &SourceMgr = CXXUnit->getSourceManager();
6614*67e74705SXin Li   std::pair<FileID, unsigned> BeginLocInfo
6615*67e74705SXin Li     = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
6616*67e74705SXin Li   std::pair<FileID, unsigned> EndLocInfo
6617*67e74705SXin Li     = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
6618*67e74705SXin Li 
6619*67e74705SXin Li   if (BeginLocInfo.first != EndLocInfo.first)
6620*67e74705SXin Li     return;
6621*67e74705SXin Li 
6622*67e74705SXin Li   StringRef Buffer;
6623*67e74705SXin Li   bool Invalid = false;
6624*67e74705SXin Li   Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6625*67e74705SXin Li   if (Buffer.empty() || Invalid)
6626*67e74705SXin Li     return;
6627*67e74705SXin Li 
6628*67e74705SXin Li   Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6629*67e74705SXin Li             CXXUnit->getASTContext().getLangOpts(),
6630*67e74705SXin Li             Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6631*67e74705SXin Li             Buffer.end());
6632*67e74705SXin Li   Lex.SetCommentRetentionState(true);
6633*67e74705SXin Li 
6634*67e74705SXin Li   unsigned NextIdx = 0;
6635*67e74705SXin Li   // Lex tokens in raw mode until we hit the end of the range, to avoid
6636*67e74705SXin Li   // entering #includes or expanding macros.
6637*67e74705SXin Li   while (true) {
6638*67e74705SXin Li     Token Tok;
6639*67e74705SXin Li     if (lexNext(Lex, Tok, NextIdx, NumTokens))
6640*67e74705SXin Li       break;
6641*67e74705SXin Li     unsigned TokIdx = NextIdx-1;
6642*67e74705SXin Li     assert(Tok.getLocation() ==
6643*67e74705SXin Li              SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
6644*67e74705SXin Li 
6645*67e74705SXin Li   reprocess:
6646*67e74705SXin Li     if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
6647*67e74705SXin Li       // We have found a preprocessing directive. Annotate the tokens
6648*67e74705SXin Li       // appropriately.
6649*67e74705SXin Li       //
6650*67e74705SXin Li       // FIXME: Some simple tests here could identify macro definitions and
6651*67e74705SXin Li       // #undefs, to provide specific cursor kinds for those.
6652*67e74705SXin Li 
6653*67e74705SXin Li       SourceLocation BeginLoc = Tok.getLocation();
6654*67e74705SXin Li       if (lexNext(Lex, Tok, NextIdx, NumTokens))
6655*67e74705SXin Li         break;
6656*67e74705SXin Li 
6657*67e74705SXin Li       MacroInfo *MI = nullptr;
6658*67e74705SXin Li       if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
6659*67e74705SXin Li         if (lexNext(Lex, Tok, NextIdx, NumTokens))
6660*67e74705SXin Li           break;
6661*67e74705SXin Li 
6662*67e74705SXin Li         if (Tok.is(tok::raw_identifier)) {
6663*67e74705SXin Li           IdentifierInfo &II =
6664*67e74705SXin Li               PP.getIdentifierTable().get(Tok.getRawIdentifier());
6665*67e74705SXin Li           SourceLocation MappedTokLoc =
6666*67e74705SXin Li               CXXUnit->mapLocationToPreamble(Tok.getLocation());
6667*67e74705SXin Li           MI = getMacroInfo(II, MappedTokLoc, TU);
6668*67e74705SXin Li         }
6669*67e74705SXin Li       }
6670*67e74705SXin Li 
6671*67e74705SXin Li       bool finished = false;
6672*67e74705SXin Li       do {
6673*67e74705SXin Li         if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6674*67e74705SXin Li           finished = true;
6675*67e74705SXin Li           break;
6676*67e74705SXin Li         }
6677*67e74705SXin Li         // If we are in a macro definition, check if the token was ever a
6678*67e74705SXin Li         // macro name and annotate it if that's the case.
6679*67e74705SXin Li         if (MI) {
6680*67e74705SXin Li           SourceLocation SaveLoc = Tok.getLocation();
6681*67e74705SXin Li           Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
6682*67e74705SXin Li           MacroDefinitionRecord *MacroDef =
6683*67e74705SXin Li               checkForMacroInMacroDefinition(MI, Tok, TU);
6684*67e74705SXin Li           Tok.setLocation(SaveLoc);
6685*67e74705SXin Li           if (MacroDef)
6686*67e74705SXin Li             Cursors[NextIdx - 1] =
6687*67e74705SXin Li                 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
6688*67e74705SXin Li         }
6689*67e74705SXin Li       } while (!Tok.isAtStartOfLine());
6690*67e74705SXin Li 
6691*67e74705SXin Li       unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6692*67e74705SXin Li       assert(TokIdx <= LastIdx);
6693*67e74705SXin Li       SourceLocation EndLoc =
6694*67e74705SXin Li           SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6695*67e74705SXin Li       CXCursor Cursor =
6696*67e74705SXin Li           MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6697*67e74705SXin Li 
6698*67e74705SXin Li       for (; TokIdx <= LastIdx; ++TokIdx)
6699*67e74705SXin Li         updateCursorAnnotation(Cursors[TokIdx], Cursor);
6700*67e74705SXin Li 
6701*67e74705SXin Li       if (finished)
6702*67e74705SXin Li         break;
6703*67e74705SXin Li       goto reprocess;
6704*67e74705SXin Li     }
6705*67e74705SXin Li   }
6706*67e74705SXin Li }
6707*67e74705SXin Li 
6708*67e74705SXin Li // This gets run a separate thread to avoid stack blowout.
clang_annotateTokensImpl(CXTranslationUnit TU,ASTUnit * CXXUnit,CXToken * Tokens,unsigned NumTokens,CXCursor * Cursors)6709*67e74705SXin Li static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6710*67e74705SXin Li                                      CXToken *Tokens, unsigned NumTokens,
6711*67e74705SXin Li                                      CXCursor *Cursors) {
6712*67e74705SXin Li   CIndexer *CXXIdx = TU->CIdx;
6713*67e74705SXin Li   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6714*67e74705SXin Li     setThreadBackgroundPriority();
6715*67e74705SXin Li 
6716*67e74705SXin Li   // Determine the region of interest, which contains all of the tokens.
6717*67e74705SXin Li   SourceRange RegionOfInterest;
6718*67e74705SXin Li   RegionOfInterest.setBegin(
6719*67e74705SXin Li     cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6720*67e74705SXin Li   RegionOfInterest.setEnd(
6721*67e74705SXin Li     cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6722*67e74705SXin Li                                                          Tokens[NumTokens-1])));
6723*67e74705SXin Li 
6724*67e74705SXin Li   // Relex the tokens within the source range to look for preprocessing
6725*67e74705SXin Li   // directives.
6726*67e74705SXin Li   annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
6727*67e74705SXin Li 
6728*67e74705SXin Li   // If begin location points inside a macro argument, set it to the expansion
6729*67e74705SXin Li   // location so we can have the full context when annotating semantically.
6730*67e74705SXin Li   {
6731*67e74705SXin Li     SourceManager &SM = CXXUnit->getSourceManager();
6732*67e74705SXin Li     SourceLocation Loc =
6733*67e74705SXin Li         SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6734*67e74705SXin Li     if (Loc.isMacroID())
6735*67e74705SXin Li       RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6736*67e74705SXin Li   }
6737*67e74705SXin Li 
6738*67e74705SXin Li   if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6739*67e74705SXin Li     // Search and mark tokens that are macro argument expansions.
6740*67e74705SXin Li     MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6741*67e74705SXin Li                                       Tokens, NumTokens);
6742*67e74705SXin Li     CursorVisitor MacroArgMarker(TU,
6743*67e74705SXin Li                                  MarkMacroArgTokensVisitorDelegate, &Visitor,
6744*67e74705SXin Li                                  /*VisitPreprocessorLast=*/true,
6745*67e74705SXin Li                                  /*VisitIncludedEntities=*/false,
6746*67e74705SXin Li                                  RegionOfInterest);
6747*67e74705SXin Li     MacroArgMarker.visitPreprocessedEntitiesInRegion();
6748*67e74705SXin Li   }
6749*67e74705SXin Li 
6750*67e74705SXin Li   // Annotate all of the source locations in the region of interest that map to
6751*67e74705SXin Li   // a specific cursor.
6752*67e74705SXin Li   AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
6753*67e74705SXin Li 
6754*67e74705SXin Li   // FIXME: We use a ridiculous stack size here because the data-recursion
6755*67e74705SXin Li   // algorithm uses a large stack frame than the non-data recursive version,
6756*67e74705SXin Li   // and AnnotationTokensWorker currently transforms the data-recursion
6757*67e74705SXin Li   // algorithm back into a traditional recursion by explicitly calling
6758*67e74705SXin Li   // VisitChildren().  We will need to remove this explicit recursive call.
6759*67e74705SXin Li   W.AnnotateTokens();
6760*67e74705SXin Li 
6761*67e74705SXin Li   // If we ran into any entities that involve context-sensitive keywords,
6762*67e74705SXin Li   // take another pass through the tokens to mark them as such.
6763*67e74705SXin Li   if (W.hasContextSensitiveKeywords()) {
6764*67e74705SXin Li     for (unsigned I = 0; I != NumTokens; ++I) {
6765*67e74705SXin Li       if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6766*67e74705SXin Li         continue;
6767*67e74705SXin Li 
6768*67e74705SXin Li       if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6769*67e74705SXin Li         IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6770*67e74705SXin Li         if (const ObjCPropertyDecl *Property
6771*67e74705SXin Li             = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6772*67e74705SXin Li           if (Property->getPropertyAttributesAsWritten() != 0 &&
6773*67e74705SXin Li               llvm::StringSwitch<bool>(II->getName())
6774*67e74705SXin Li               .Case("readonly", true)
6775*67e74705SXin Li               .Case("assign", true)
6776*67e74705SXin Li               .Case("unsafe_unretained", true)
6777*67e74705SXin Li               .Case("readwrite", true)
6778*67e74705SXin Li               .Case("retain", true)
6779*67e74705SXin Li               .Case("copy", true)
6780*67e74705SXin Li               .Case("nonatomic", true)
6781*67e74705SXin Li               .Case("atomic", true)
6782*67e74705SXin Li               .Case("getter", true)
6783*67e74705SXin Li               .Case("setter", true)
6784*67e74705SXin Li               .Case("strong", true)
6785*67e74705SXin Li               .Case("weak", true)
6786*67e74705SXin Li               .Case("class", true)
6787*67e74705SXin Li               .Default(false))
6788*67e74705SXin Li             Tokens[I].int_data[0] = CXToken_Keyword;
6789*67e74705SXin Li         }
6790*67e74705SXin Li         continue;
6791*67e74705SXin Li       }
6792*67e74705SXin Li 
6793*67e74705SXin Li       if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6794*67e74705SXin Li           Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6795*67e74705SXin Li         IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6796*67e74705SXin Li         if (llvm::StringSwitch<bool>(II->getName())
6797*67e74705SXin Li             .Case("in", true)
6798*67e74705SXin Li             .Case("out", true)
6799*67e74705SXin Li             .Case("inout", true)
6800*67e74705SXin Li             .Case("oneway", true)
6801*67e74705SXin Li             .Case("bycopy", true)
6802*67e74705SXin Li             .Case("byref", true)
6803*67e74705SXin Li             .Default(false))
6804*67e74705SXin Li           Tokens[I].int_data[0] = CXToken_Keyword;
6805*67e74705SXin Li         continue;
6806*67e74705SXin Li       }
6807*67e74705SXin Li 
6808*67e74705SXin Li       if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6809*67e74705SXin Li           Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6810*67e74705SXin Li         Tokens[I].int_data[0] = CXToken_Keyword;
6811*67e74705SXin Li         continue;
6812*67e74705SXin Li       }
6813*67e74705SXin Li     }
6814*67e74705SXin Li   }
6815*67e74705SXin Li }
6816*67e74705SXin Li 
6817*67e74705SXin Li extern "C" {
6818*67e74705SXin Li 
clang_annotateTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens,CXCursor * Cursors)6819*67e74705SXin Li void clang_annotateTokens(CXTranslationUnit TU,
6820*67e74705SXin Li                           CXToken *Tokens, unsigned NumTokens,
6821*67e74705SXin Li                           CXCursor *Cursors) {
6822*67e74705SXin Li   if (isNotUsableTU(TU)) {
6823*67e74705SXin Li     LOG_BAD_TU(TU);
6824*67e74705SXin Li     return;
6825*67e74705SXin Li   }
6826*67e74705SXin Li   if (NumTokens == 0 || !Tokens || !Cursors) {
6827*67e74705SXin Li     LOG_FUNC_SECTION { *Log << "<null input>"; }
6828*67e74705SXin Li     return;
6829*67e74705SXin Li   }
6830*67e74705SXin Li 
6831*67e74705SXin Li   LOG_FUNC_SECTION {
6832*67e74705SXin Li     *Log << TU << ' ';
6833*67e74705SXin Li     CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6834*67e74705SXin Li     CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6835*67e74705SXin Li     *Log << clang_getRange(bloc, eloc);
6836*67e74705SXin Li   }
6837*67e74705SXin Li 
6838*67e74705SXin Li   // Any token we don't specifically annotate will have a NULL cursor.
6839*67e74705SXin Li   CXCursor C = clang_getNullCursor();
6840*67e74705SXin Li   for (unsigned I = 0; I != NumTokens; ++I)
6841*67e74705SXin Li     Cursors[I] = C;
6842*67e74705SXin Li 
6843*67e74705SXin Li   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6844*67e74705SXin Li   if (!CXXUnit)
6845*67e74705SXin Li     return;
6846*67e74705SXin Li 
6847*67e74705SXin Li   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6848*67e74705SXin Li 
6849*67e74705SXin Li   auto AnnotateTokensImpl = [=]() {
6850*67e74705SXin Li     clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6851*67e74705SXin Li   };
6852*67e74705SXin Li   llvm::CrashRecoveryContext CRC;
6853*67e74705SXin Li   if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
6854*67e74705SXin Li     fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6855*67e74705SXin Li   }
6856*67e74705SXin Li }
6857*67e74705SXin Li 
6858*67e74705SXin Li } // end: extern "C"
6859*67e74705SXin Li 
6860*67e74705SXin Li //===----------------------------------------------------------------------===//
6861*67e74705SXin Li // Operations for querying linkage of a cursor.
6862*67e74705SXin Li //===----------------------------------------------------------------------===//
6863*67e74705SXin Li 
6864*67e74705SXin Li extern "C" {
clang_getCursorLinkage(CXCursor cursor)6865*67e74705SXin Li CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6866*67e74705SXin Li   if (!clang_isDeclaration(cursor.kind))
6867*67e74705SXin Li     return CXLinkage_Invalid;
6868*67e74705SXin Li 
6869*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(cursor);
6870*67e74705SXin Li   if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6871*67e74705SXin Li     switch (ND->getLinkageInternal()) {
6872*67e74705SXin Li       case NoLinkage:
6873*67e74705SXin Li       case VisibleNoLinkage: return CXLinkage_NoLinkage;
6874*67e74705SXin Li       case InternalLinkage: return CXLinkage_Internal;
6875*67e74705SXin Li       case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6876*67e74705SXin Li       case ExternalLinkage: return CXLinkage_External;
6877*67e74705SXin Li     };
6878*67e74705SXin Li 
6879*67e74705SXin Li   return CXLinkage_Invalid;
6880*67e74705SXin Li }
6881*67e74705SXin Li } // end: extern "C"
6882*67e74705SXin Li 
6883*67e74705SXin Li //===----------------------------------------------------------------------===//
6884*67e74705SXin Li // Operations for querying visibility of a cursor.
6885*67e74705SXin Li //===----------------------------------------------------------------------===//
6886*67e74705SXin Li 
6887*67e74705SXin Li extern "C" {
clang_getCursorVisibility(CXCursor cursor)6888*67e74705SXin Li CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
6889*67e74705SXin Li   if (!clang_isDeclaration(cursor.kind))
6890*67e74705SXin Li     return CXVisibility_Invalid;
6891*67e74705SXin Li 
6892*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(cursor);
6893*67e74705SXin Li   if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
6894*67e74705SXin Li     switch (ND->getVisibility()) {
6895*67e74705SXin Li       case HiddenVisibility: return CXVisibility_Hidden;
6896*67e74705SXin Li       case ProtectedVisibility: return CXVisibility_Protected;
6897*67e74705SXin Li       case DefaultVisibility: return CXVisibility_Default;
6898*67e74705SXin Li     };
6899*67e74705SXin Li 
6900*67e74705SXin Li   return CXVisibility_Invalid;
6901*67e74705SXin Li }
6902*67e74705SXin Li } // end: extern "C"
6903*67e74705SXin Li 
6904*67e74705SXin Li //===----------------------------------------------------------------------===//
6905*67e74705SXin Li // Operations for querying language of a cursor.
6906*67e74705SXin Li //===----------------------------------------------------------------------===//
6907*67e74705SXin Li 
getDeclLanguage(const Decl * D)6908*67e74705SXin Li static CXLanguageKind getDeclLanguage(const Decl *D) {
6909*67e74705SXin Li   if (!D)
6910*67e74705SXin Li     return CXLanguage_C;
6911*67e74705SXin Li 
6912*67e74705SXin Li   switch (D->getKind()) {
6913*67e74705SXin Li     default:
6914*67e74705SXin Li       break;
6915*67e74705SXin Li     case Decl::ImplicitParam:
6916*67e74705SXin Li     case Decl::ObjCAtDefsField:
6917*67e74705SXin Li     case Decl::ObjCCategory:
6918*67e74705SXin Li     case Decl::ObjCCategoryImpl:
6919*67e74705SXin Li     case Decl::ObjCCompatibleAlias:
6920*67e74705SXin Li     case Decl::ObjCImplementation:
6921*67e74705SXin Li     case Decl::ObjCInterface:
6922*67e74705SXin Li     case Decl::ObjCIvar:
6923*67e74705SXin Li     case Decl::ObjCMethod:
6924*67e74705SXin Li     case Decl::ObjCProperty:
6925*67e74705SXin Li     case Decl::ObjCPropertyImpl:
6926*67e74705SXin Li     case Decl::ObjCProtocol:
6927*67e74705SXin Li     case Decl::ObjCTypeParam:
6928*67e74705SXin Li       return CXLanguage_ObjC;
6929*67e74705SXin Li     case Decl::CXXConstructor:
6930*67e74705SXin Li     case Decl::CXXConversion:
6931*67e74705SXin Li     case Decl::CXXDestructor:
6932*67e74705SXin Li     case Decl::CXXMethod:
6933*67e74705SXin Li     case Decl::CXXRecord:
6934*67e74705SXin Li     case Decl::ClassTemplate:
6935*67e74705SXin Li     case Decl::ClassTemplatePartialSpecialization:
6936*67e74705SXin Li     case Decl::ClassTemplateSpecialization:
6937*67e74705SXin Li     case Decl::Friend:
6938*67e74705SXin Li     case Decl::FriendTemplate:
6939*67e74705SXin Li     case Decl::FunctionTemplate:
6940*67e74705SXin Li     case Decl::LinkageSpec:
6941*67e74705SXin Li     case Decl::Namespace:
6942*67e74705SXin Li     case Decl::NamespaceAlias:
6943*67e74705SXin Li     case Decl::NonTypeTemplateParm:
6944*67e74705SXin Li     case Decl::StaticAssert:
6945*67e74705SXin Li     case Decl::TemplateTemplateParm:
6946*67e74705SXin Li     case Decl::TemplateTypeParm:
6947*67e74705SXin Li     case Decl::UnresolvedUsingTypename:
6948*67e74705SXin Li     case Decl::UnresolvedUsingValue:
6949*67e74705SXin Li     case Decl::Using:
6950*67e74705SXin Li     case Decl::UsingDirective:
6951*67e74705SXin Li     case Decl::UsingShadow:
6952*67e74705SXin Li       return CXLanguage_CPlusPlus;
6953*67e74705SXin Li   }
6954*67e74705SXin Li 
6955*67e74705SXin Li   return CXLanguage_C;
6956*67e74705SXin Li }
6957*67e74705SXin Li 
6958*67e74705SXin Li extern "C" {
6959*67e74705SXin Li 
getCursorAvailabilityForDecl(const Decl * D)6960*67e74705SXin Li static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6961*67e74705SXin Li   if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
6962*67e74705SXin Li     return CXAvailability_NotAvailable;
6963*67e74705SXin Li 
6964*67e74705SXin Li   switch (D->getAvailability()) {
6965*67e74705SXin Li   case AR_Available:
6966*67e74705SXin Li   case AR_NotYetIntroduced:
6967*67e74705SXin Li     if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6968*67e74705SXin Li       return getCursorAvailabilityForDecl(
6969*67e74705SXin Li           cast<Decl>(EnumConst->getDeclContext()));
6970*67e74705SXin Li     return CXAvailability_Available;
6971*67e74705SXin Li 
6972*67e74705SXin Li   case AR_Deprecated:
6973*67e74705SXin Li     return CXAvailability_Deprecated;
6974*67e74705SXin Li 
6975*67e74705SXin Li   case AR_Unavailable:
6976*67e74705SXin Li     return CXAvailability_NotAvailable;
6977*67e74705SXin Li   }
6978*67e74705SXin Li 
6979*67e74705SXin Li   llvm_unreachable("Unknown availability kind!");
6980*67e74705SXin Li }
6981*67e74705SXin Li 
clang_getCursorAvailability(CXCursor cursor)6982*67e74705SXin Li enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6983*67e74705SXin Li   if (clang_isDeclaration(cursor.kind))
6984*67e74705SXin Li     if (const Decl *D = cxcursor::getCursorDecl(cursor))
6985*67e74705SXin Li       return getCursorAvailabilityForDecl(D);
6986*67e74705SXin Li 
6987*67e74705SXin Li   return CXAvailability_Available;
6988*67e74705SXin Li }
6989*67e74705SXin Li 
convertVersion(VersionTuple In)6990*67e74705SXin Li static CXVersion convertVersion(VersionTuple In) {
6991*67e74705SXin Li   CXVersion Out = { -1, -1, -1 };
6992*67e74705SXin Li   if (In.empty())
6993*67e74705SXin Li     return Out;
6994*67e74705SXin Li 
6995*67e74705SXin Li   Out.Major = In.getMajor();
6996*67e74705SXin Li 
6997*67e74705SXin Li   Optional<unsigned> Minor = In.getMinor();
6998*67e74705SXin Li   if (Minor.hasValue())
6999*67e74705SXin Li     Out.Minor = *Minor;
7000*67e74705SXin Li   else
7001*67e74705SXin Li     return Out;
7002*67e74705SXin Li 
7003*67e74705SXin Li   Optional<unsigned> Subminor = In.getSubminor();
7004*67e74705SXin Li   if (Subminor.hasValue())
7005*67e74705SXin Li     Out.Subminor = *Subminor;
7006*67e74705SXin Li 
7007*67e74705SXin Li   return Out;
7008*67e74705SXin Li }
7009*67e74705SXin Li 
getCursorPlatformAvailabilityForDecl(const Decl * D,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,CXPlatformAvailability * availability,int availability_size)7010*67e74705SXin Li static int getCursorPlatformAvailabilityForDecl(const Decl *D,
7011*67e74705SXin Li                                                 int *always_deprecated,
7012*67e74705SXin Li                                                 CXString *deprecated_message,
7013*67e74705SXin Li                                                 int *always_unavailable,
7014*67e74705SXin Li                                                 CXString *unavailable_message,
7015*67e74705SXin Li                                            CXPlatformAvailability *availability,
7016*67e74705SXin Li                                                 int availability_size) {
7017*67e74705SXin Li   bool HadAvailAttr = false;
7018*67e74705SXin Li   int N = 0;
7019*67e74705SXin Li   for (auto A : D->attrs()) {
7020*67e74705SXin Li     if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
7021*67e74705SXin Li       HadAvailAttr = true;
7022*67e74705SXin Li       if (always_deprecated)
7023*67e74705SXin Li         *always_deprecated = 1;
7024*67e74705SXin Li       if (deprecated_message) {
7025*67e74705SXin Li         clang_disposeString(*deprecated_message);
7026*67e74705SXin Li         *deprecated_message = cxstring::createDup(Deprecated->getMessage());
7027*67e74705SXin Li       }
7028*67e74705SXin Li       continue;
7029*67e74705SXin Li     }
7030*67e74705SXin Li 
7031*67e74705SXin Li     if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
7032*67e74705SXin Li       HadAvailAttr = true;
7033*67e74705SXin Li       if (always_unavailable)
7034*67e74705SXin Li         *always_unavailable = 1;
7035*67e74705SXin Li       if (unavailable_message) {
7036*67e74705SXin Li         clang_disposeString(*unavailable_message);
7037*67e74705SXin Li         *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7038*67e74705SXin Li       }
7039*67e74705SXin Li       continue;
7040*67e74705SXin Li     }
7041*67e74705SXin Li 
7042*67e74705SXin Li     if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
7043*67e74705SXin Li       HadAvailAttr = true;
7044*67e74705SXin Li       if (N < availability_size) {
7045*67e74705SXin Li         availability[N].Platform
7046*67e74705SXin Li           = cxstring::createDup(Avail->getPlatform()->getName());
7047*67e74705SXin Li         availability[N].Introduced = convertVersion(Avail->getIntroduced());
7048*67e74705SXin Li         availability[N].Deprecated = convertVersion(Avail->getDeprecated());
7049*67e74705SXin Li         availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
7050*67e74705SXin Li         availability[N].Unavailable = Avail->getUnavailable();
7051*67e74705SXin Li         availability[N].Message = cxstring::createDup(Avail->getMessage());
7052*67e74705SXin Li       }
7053*67e74705SXin Li       ++N;
7054*67e74705SXin Li     }
7055*67e74705SXin Li   }
7056*67e74705SXin Li 
7057*67e74705SXin Li   if (!HadAvailAttr)
7058*67e74705SXin Li     if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7059*67e74705SXin Li       return getCursorPlatformAvailabilityForDecl(
7060*67e74705SXin Li                                         cast<Decl>(EnumConst->getDeclContext()),
7061*67e74705SXin Li                                                   always_deprecated,
7062*67e74705SXin Li                                                   deprecated_message,
7063*67e74705SXin Li                                                   always_unavailable,
7064*67e74705SXin Li                                                   unavailable_message,
7065*67e74705SXin Li                                                   availability,
7066*67e74705SXin Li                                                   availability_size);
7067*67e74705SXin Li 
7068*67e74705SXin Li   return N;
7069*67e74705SXin Li }
7070*67e74705SXin Li 
clang_getCursorPlatformAvailability(CXCursor cursor,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,CXPlatformAvailability * availability,int availability_size)7071*67e74705SXin Li int clang_getCursorPlatformAvailability(CXCursor cursor,
7072*67e74705SXin Li                                         int *always_deprecated,
7073*67e74705SXin Li                                         CXString *deprecated_message,
7074*67e74705SXin Li                                         int *always_unavailable,
7075*67e74705SXin Li                                         CXString *unavailable_message,
7076*67e74705SXin Li                                         CXPlatformAvailability *availability,
7077*67e74705SXin Li                                         int availability_size) {
7078*67e74705SXin Li   if (always_deprecated)
7079*67e74705SXin Li     *always_deprecated = 0;
7080*67e74705SXin Li   if (deprecated_message)
7081*67e74705SXin Li     *deprecated_message = cxstring::createEmpty();
7082*67e74705SXin Li   if (always_unavailable)
7083*67e74705SXin Li     *always_unavailable = 0;
7084*67e74705SXin Li   if (unavailable_message)
7085*67e74705SXin Li     *unavailable_message = cxstring::createEmpty();
7086*67e74705SXin Li 
7087*67e74705SXin Li   if (!clang_isDeclaration(cursor.kind))
7088*67e74705SXin Li     return 0;
7089*67e74705SXin Li 
7090*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(cursor);
7091*67e74705SXin Li   if (!D)
7092*67e74705SXin Li     return 0;
7093*67e74705SXin Li 
7094*67e74705SXin Li   return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
7095*67e74705SXin Li                                               deprecated_message,
7096*67e74705SXin Li                                               always_unavailable,
7097*67e74705SXin Li                                               unavailable_message,
7098*67e74705SXin Li                                               availability,
7099*67e74705SXin Li                                               availability_size);
7100*67e74705SXin Li }
7101*67e74705SXin Li 
clang_disposeCXPlatformAvailability(CXPlatformAvailability * availability)7102*67e74705SXin Li void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
7103*67e74705SXin Li   clang_disposeString(availability->Platform);
7104*67e74705SXin Li   clang_disposeString(availability->Message);
7105*67e74705SXin Li }
7106*67e74705SXin Li 
clang_getCursorLanguage(CXCursor cursor)7107*67e74705SXin Li CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
7108*67e74705SXin Li   if (clang_isDeclaration(cursor.kind))
7109*67e74705SXin Li     return getDeclLanguage(cxcursor::getCursorDecl(cursor));
7110*67e74705SXin Li 
7111*67e74705SXin Li   return CXLanguage_Invalid;
7112*67e74705SXin Li }
7113*67e74705SXin Li 
7114*67e74705SXin Li  /// \brief If the given cursor is the "templated" declaration
7115*67e74705SXin Li  /// descibing a class or function template, return the class or
7116*67e74705SXin Li  /// function template.
maybeGetTemplateCursor(const Decl * D)7117*67e74705SXin Li static const Decl *maybeGetTemplateCursor(const Decl *D) {
7118*67e74705SXin Li   if (!D)
7119*67e74705SXin Li     return nullptr;
7120*67e74705SXin Li 
7121*67e74705SXin Li   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7122*67e74705SXin Li     if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
7123*67e74705SXin Li       return FunTmpl;
7124*67e74705SXin Li 
7125*67e74705SXin Li   if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
7126*67e74705SXin Li     if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
7127*67e74705SXin Li       return ClassTmpl;
7128*67e74705SXin Li 
7129*67e74705SXin Li   return D;
7130*67e74705SXin Li }
7131*67e74705SXin Li 
7132*67e74705SXin Li 
clang_Cursor_getStorageClass(CXCursor C)7133*67e74705SXin Li enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
7134*67e74705SXin Li   StorageClass sc = SC_None;
7135*67e74705SXin Li   const Decl *D = getCursorDecl(C);
7136*67e74705SXin Li   if (D) {
7137*67e74705SXin Li     if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
7138*67e74705SXin Li       sc = FD->getStorageClass();
7139*67e74705SXin Li     } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
7140*67e74705SXin Li       sc = VD->getStorageClass();
7141*67e74705SXin Li     } else {
7142*67e74705SXin Li       return CX_SC_Invalid;
7143*67e74705SXin Li     }
7144*67e74705SXin Li   } else {
7145*67e74705SXin Li     return CX_SC_Invalid;
7146*67e74705SXin Li   }
7147*67e74705SXin Li   switch (sc) {
7148*67e74705SXin Li   case SC_None:
7149*67e74705SXin Li     return CX_SC_None;
7150*67e74705SXin Li   case SC_Extern:
7151*67e74705SXin Li     return CX_SC_Extern;
7152*67e74705SXin Li   case SC_Static:
7153*67e74705SXin Li     return CX_SC_Static;
7154*67e74705SXin Li   case SC_PrivateExtern:
7155*67e74705SXin Li     return CX_SC_PrivateExtern;
7156*67e74705SXin Li   case SC_Auto:
7157*67e74705SXin Li     return CX_SC_Auto;
7158*67e74705SXin Li   case SC_Register:
7159*67e74705SXin Li     return CX_SC_Register;
7160*67e74705SXin Li   }
7161*67e74705SXin Li   llvm_unreachable("Unhandled storage class!");
7162*67e74705SXin Li }
7163*67e74705SXin Li 
clang_getCursorSemanticParent(CXCursor cursor)7164*67e74705SXin Li CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
7165*67e74705SXin Li   if (clang_isDeclaration(cursor.kind)) {
7166*67e74705SXin Li     if (const Decl *D = getCursorDecl(cursor)) {
7167*67e74705SXin Li       const DeclContext *DC = D->getDeclContext();
7168*67e74705SXin Li       if (!DC)
7169*67e74705SXin Li         return clang_getNullCursor();
7170*67e74705SXin Li 
7171*67e74705SXin Li       return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7172*67e74705SXin Li                           getCursorTU(cursor));
7173*67e74705SXin Li     }
7174*67e74705SXin Li   }
7175*67e74705SXin Li 
7176*67e74705SXin Li   if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
7177*67e74705SXin Li     if (const Decl *D = getCursorDecl(cursor))
7178*67e74705SXin Li       return MakeCXCursor(D, getCursorTU(cursor));
7179*67e74705SXin Li   }
7180*67e74705SXin Li 
7181*67e74705SXin Li   return clang_getNullCursor();
7182*67e74705SXin Li }
7183*67e74705SXin Li 
clang_getCursorLexicalParent(CXCursor cursor)7184*67e74705SXin Li CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
7185*67e74705SXin Li   if (clang_isDeclaration(cursor.kind)) {
7186*67e74705SXin Li     if (const Decl *D = getCursorDecl(cursor)) {
7187*67e74705SXin Li       const DeclContext *DC = D->getLexicalDeclContext();
7188*67e74705SXin Li       if (!DC)
7189*67e74705SXin Li         return clang_getNullCursor();
7190*67e74705SXin Li 
7191*67e74705SXin Li       return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
7192*67e74705SXin Li                           getCursorTU(cursor));
7193*67e74705SXin Li     }
7194*67e74705SXin Li   }
7195*67e74705SXin Li 
7196*67e74705SXin Li   // FIXME: Note that we can't easily compute the lexical context of a
7197*67e74705SXin Li   // statement or expression, so we return nothing.
7198*67e74705SXin Li   return clang_getNullCursor();
7199*67e74705SXin Li }
7200*67e74705SXin Li 
clang_getIncludedFile(CXCursor cursor)7201*67e74705SXin Li CXFile clang_getIncludedFile(CXCursor cursor) {
7202*67e74705SXin Li   if (cursor.kind != CXCursor_InclusionDirective)
7203*67e74705SXin Li     return nullptr;
7204*67e74705SXin Li 
7205*67e74705SXin Li   const InclusionDirective *ID = getCursorInclusionDirective(cursor);
7206*67e74705SXin Li   return const_cast<FileEntry *>(ID->getFile());
7207*67e74705SXin Li }
7208*67e74705SXin Li 
clang_Cursor_getObjCPropertyAttributes(CXCursor C,unsigned reserved)7209*67e74705SXin Li unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
7210*67e74705SXin Li   if (C.kind != CXCursor_ObjCPropertyDecl)
7211*67e74705SXin Li     return CXObjCPropertyAttr_noattr;
7212*67e74705SXin Li 
7213*67e74705SXin Li   unsigned Result = CXObjCPropertyAttr_noattr;
7214*67e74705SXin Li   const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
7215*67e74705SXin Li   ObjCPropertyDecl::PropertyAttributeKind Attr =
7216*67e74705SXin Li       PD->getPropertyAttributesAsWritten();
7217*67e74705SXin Li 
7218*67e74705SXin Li #define SET_CXOBJCPROP_ATTR(A) \
7219*67e74705SXin Li   if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
7220*67e74705SXin Li     Result |= CXObjCPropertyAttr_##A
7221*67e74705SXin Li   SET_CXOBJCPROP_ATTR(readonly);
7222*67e74705SXin Li   SET_CXOBJCPROP_ATTR(getter);
7223*67e74705SXin Li   SET_CXOBJCPROP_ATTR(assign);
7224*67e74705SXin Li   SET_CXOBJCPROP_ATTR(readwrite);
7225*67e74705SXin Li   SET_CXOBJCPROP_ATTR(retain);
7226*67e74705SXin Li   SET_CXOBJCPROP_ATTR(copy);
7227*67e74705SXin Li   SET_CXOBJCPROP_ATTR(nonatomic);
7228*67e74705SXin Li   SET_CXOBJCPROP_ATTR(setter);
7229*67e74705SXin Li   SET_CXOBJCPROP_ATTR(atomic);
7230*67e74705SXin Li   SET_CXOBJCPROP_ATTR(weak);
7231*67e74705SXin Li   SET_CXOBJCPROP_ATTR(strong);
7232*67e74705SXin Li   SET_CXOBJCPROP_ATTR(unsafe_unretained);
7233*67e74705SXin Li   SET_CXOBJCPROP_ATTR(class);
7234*67e74705SXin Li #undef SET_CXOBJCPROP_ATTR
7235*67e74705SXin Li 
7236*67e74705SXin Li   return Result;
7237*67e74705SXin Li }
7238*67e74705SXin Li 
clang_Cursor_getObjCDeclQualifiers(CXCursor C)7239*67e74705SXin Li unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
7240*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7241*67e74705SXin Li     return CXObjCDeclQualifier_None;
7242*67e74705SXin Li 
7243*67e74705SXin Li   Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
7244*67e74705SXin Li   const Decl *D = getCursorDecl(C);
7245*67e74705SXin Li   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7246*67e74705SXin Li     QT = MD->getObjCDeclQualifier();
7247*67e74705SXin Li   else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
7248*67e74705SXin Li     QT = PD->getObjCDeclQualifier();
7249*67e74705SXin Li   if (QT == Decl::OBJC_TQ_None)
7250*67e74705SXin Li     return CXObjCDeclQualifier_None;
7251*67e74705SXin Li 
7252*67e74705SXin Li   unsigned Result = CXObjCDeclQualifier_None;
7253*67e74705SXin Li   if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
7254*67e74705SXin Li   if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
7255*67e74705SXin Li   if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
7256*67e74705SXin Li   if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
7257*67e74705SXin Li   if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
7258*67e74705SXin Li   if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
7259*67e74705SXin Li 
7260*67e74705SXin Li   return Result;
7261*67e74705SXin Li }
7262*67e74705SXin Li 
clang_Cursor_isObjCOptional(CXCursor C)7263*67e74705SXin Li unsigned clang_Cursor_isObjCOptional(CXCursor C) {
7264*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7265*67e74705SXin Li     return 0;
7266*67e74705SXin Li 
7267*67e74705SXin Li   const Decl *D = getCursorDecl(C);
7268*67e74705SXin Li   if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
7269*67e74705SXin Li     return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
7270*67e74705SXin Li   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7271*67e74705SXin Li     return MD->getImplementationControl() == ObjCMethodDecl::Optional;
7272*67e74705SXin Li 
7273*67e74705SXin Li   return 0;
7274*67e74705SXin Li }
7275*67e74705SXin Li 
clang_Cursor_isVariadic(CXCursor C)7276*67e74705SXin Li unsigned clang_Cursor_isVariadic(CXCursor C) {
7277*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7278*67e74705SXin Li     return 0;
7279*67e74705SXin Li 
7280*67e74705SXin Li   const Decl *D = getCursorDecl(C);
7281*67e74705SXin Li   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
7282*67e74705SXin Li     return FD->isVariadic();
7283*67e74705SXin Li   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
7284*67e74705SXin Li     return MD->isVariadic();
7285*67e74705SXin Li 
7286*67e74705SXin Li   return 0;
7287*67e74705SXin Li }
7288*67e74705SXin Li 
clang_Cursor_getCommentRange(CXCursor C)7289*67e74705SXin Li CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
7290*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7291*67e74705SXin Li     return clang_getNullRange();
7292*67e74705SXin Li 
7293*67e74705SXin Li   const Decl *D = getCursorDecl(C);
7294*67e74705SXin Li   ASTContext &Context = getCursorContext(C);
7295*67e74705SXin Li   const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7296*67e74705SXin Li   if (!RC)
7297*67e74705SXin Li     return clang_getNullRange();
7298*67e74705SXin Li 
7299*67e74705SXin Li   return cxloc::translateSourceRange(Context, RC->getSourceRange());
7300*67e74705SXin Li }
7301*67e74705SXin Li 
clang_Cursor_getRawCommentText(CXCursor C)7302*67e74705SXin Li CXString clang_Cursor_getRawCommentText(CXCursor C) {
7303*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7304*67e74705SXin Li     return cxstring::createNull();
7305*67e74705SXin Li 
7306*67e74705SXin Li   const Decl *D = getCursorDecl(C);
7307*67e74705SXin Li   ASTContext &Context = getCursorContext(C);
7308*67e74705SXin Li   const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7309*67e74705SXin Li   StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
7310*67e74705SXin Li                            StringRef();
7311*67e74705SXin Li 
7312*67e74705SXin Li   // Don't duplicate the string because RawText points directly into source
7313*67e74705SXin Li   // code.
7314*67e74705SXin Li   return cxstring::createRef(RawText);
7315*67e74705SXin Li }
7316*67e74705SXin Li 
clang_Cursor_getBriefCommentText(CXCursor C)7317*67e74705SXin Li CXString clang_Cursor_getBriefCommentText(CXCursor C) {
7318*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7319*67e74705SXin Li     return cxstring::createNull();
7320*67e74705SXin Li 
7321*67e74705SXin Li   const Decl *D = getCursorDecl(C);
7322*67e74705SXin Li   const ASTContext &Context = getCursorContext(C);
7323*67e74705SXin Li   const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
7324*67e74705SXin Li 
7325*67e74705SXin Li   if (RC) {
7326*67e74705SXin Li     StringRef BriefText = RC->getBriefText(Context);
7327*67e74705SXin Li 
7328*67e74705SXin Li     // Don't duplicate the string because RawComment ensures that this memory
7329*67e74705SXin Li     // will not go away.
7330*67e74705SXin Li     return cxstring::createRef(BriefText);
7331*67e74705SXin Li   }
7332*67e74705SXin Li 
7333*67e74705SXin Li   return cxstring::createNull();
7334*67e74705SXin Li }
7335*67e74705SXin Li 
clang_Cursor_getModule(CXCursor C)7336*67e74705SXin Li CXModule clang_Cursor_getModule(CXCursor C) {
7337*67e74705SXin Li   if (C.kind == CXCursor_ModuleImportDecl) {
7338*67e74705SXin Li     if (const ImportDecl *ImportD =
7339*67e74705SXin Li             dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
7340*67e74705SXin Li       return ImportD->getImportedModule();
7341*67e74705SXin Li   }
7342*67e74705SXin Li 
7343*67e74705SXin Li   return nullptr;
7344*67e74705SXin Li }
7345*67e74705SXin Li 
clang_getModuleForFile(CXTranslationUnit TU,CXFile File)7346*67e74705SXin Li CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
7347*67e74705SXin Li   if (isNotUsableTU(TU)) {
7348*67e74705SXin Li     LOG_BAD_TU(TU);
7349*67e74705SXin Li     return nullptr;
7350*67e74705SXin Li   }
7351*67e74705SXin Li   if (!File)
7352*67e74705SXin Li     return nullptr;
7353*67e74705SXin Li   FileEntry *FE = static_cast<FileEntry *>(File);
7354*67e74705SXin Li 
7355*67e74705SXin Li   ASTUnit &Unit = *cxtu::getASTUnit(TU);
7356*67e74705SXin Li   HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
7357*67e74705SXin Li   ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
7358*67e74705SXin Li 
7359*67e74705SXin Li   return Header.getModule();
7360*67e74705SXin Li }
7361*67e74705SXin Li 
clang_Module_getASTFile(CXModule CXMod)7362*67e74705SXin Li CXFile clang_Module_getASTFile(CXModule CXMod) {
7363*67e74705SXin Li   if (!CXMod)
7364*67e74705SXin Li     return nullptr;
7365*67e74705SXin Li   Module *Mod = static_cast<Module*>(CXMod);
7366*67e74705SXin Li   return const_cast<FileEntry *>(Mod->getASTFile());
7367*67e74705SXin Li }
7368*67e74705SXin Li 
clang_Module_getParent(CXModule CXMod)7369*67e74705SXin Li CXModule clang_Module_getParent(CXModule CXMod) {
7370*67e74705SXin Li   if (!CXMod)
7371*67e74705SXin Li     return nullptr;
7372*67e74705SXin Li   Module *Mod = static_cast<Module*>(CXMod);
7373*67e74705SXin Li   return Mod->Parent;
7374*67e74705SXin Li }
7375*67e74705SXin Li 
clang_Module_getName(CXModule CXMod)7376*67e74705SXin Li CXString clang_Module_getName(CXModule CXMod) {
7377*67e74705SXin Li   if (!CXMod)
7378*67e74705SXin Li     return cxstring::createEmpty();
7379*67e74705SXin Li   Module *Mod = static_cast<Module*>(CXMod);
7380*67e74705SXin Li   return cxstring::createDup(Mod->Name);
7381*67e74705SXin Li }
7382*67e74705SXin Li 
clang_Module_getFullName(CXModule CXMod)7383*67e74705SXin Li CXString clang_Module_getFullName(CXModule CXMod) {
7384*67e74705SXin Li   if (!CXMod)
7385*67e74705SXin Li     return cxstring::createEmpty();
7386*67e74705SXin Li   Module *Mod = static_cast<Module*>(CXMod);
7387*67e74705SXin Li   return cxstring::createDup(Mod->getFullModuleName());
7388*67e74705SXin Li }
7389*67e74705SXin Li 
clang_Module_isSystem(CXModule CXMod)7390*67e74705SXin Li int clang_Module_isSystem(CXModule CXMod) {
7391*67e74705SXin Li   if (!CXMod)
7392*67e74705SXin Li     return 0;
7393*67e74705SXin Li   Module *Mod = static_cast<Module*>(CXMod);
7394*67e74705SXin Li   return Mod->IsSystem;
7395*67e74705SXin Li }
7396*67e74705SXin Li 
clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,CXModule CXMod)7397*67e74705SXin Li unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
7398*67e74705SXin Li                                             CXModule CXMod) {
7399*67e74705SXin Li   if (isNotUsableTU(TU)) {
7400*67e74705SXin Li     LOG_BAD_TU(TU);
7401*67e74705SXin Li     return 0;
7402*67e74705SXin Li   }
7403*67e74705SXin Li   if (!CXMod)
7404*67e74705SXin Li     return 0;
7405*67e74705SXin Li   Module *Mod = static_cast<Module*>(CXMod);
7406*67e74705SXin Li   FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7407*67e74705SXin Li   ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7408*67e74705SXin Li   return TopHeaders.size();
7409*67e74705SXin Li }
7410*67e74705SXin Li 
clang_Module_getTopLevelHeader(CXTranslationUnit TU,CXModule CXMod,unsigned Index)7411*67e74705SXin Li CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
7412*67e74705SXin Li                                       CXModule CXMod, unsigned Index) {
7413*67e74705SXin Li   if (isNotUsableTU(TU)) {
7414*67e74705SXin Li     LOG_BAD_TU(TU);
7415*67e74705SXin Li     return nullptr;
7416*67e74705SXin Li   }
7417*67e74705SXin Li   if (!CXMod)
7418*67e74705SXin Li     return nullptr;
7419*67e74705SXin Li   Module *Mod = static_cast<Module*>(CXMod);
7420*67e74705SXin Li   FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
7421*67e74705SXin Li 
7422*67e74705SXin Li   ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
7423*67e74705SXin Li   if (Index < TopHeaders.size())
7424*67e74705SXin Li     return const_cast<FileEntry *>(TopHeaders[Index]);
7425*67e74705SXin Li 
7426*67e74705SXin Li   return nullptr;
7427*67e74705SXin Li }
7428*67e74705SXin Li 
7429*67e74705SXin Li } // end: extern "C"
7430*67e74705SXin Li 
7431*67e74705SXin Li //===----------------------------------------------------------------------===//
7432*67e74705SXin Li // C++ AST instrospection.
7433*67e74705SXin Li //===----------------------------------------------------------------------===//
7434*67e74705SXin Li 
7435*67e74705SXin Li extern "C" {
7436*67e74705SXin Li 
clang_CXXConstructor_isDefaultConstructor(CXCursor C)7437*67e74705SXin Li unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
7438*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7439*67e74705SXin Li     return 0;
7440*67e74705SXin Li 
7441*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(C);
7442*67e74705SXin Li   const CXXConstructorDecl *Constructor =
7443*67e74705SXin Li       D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7444*67e74705SXin Li   return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
7445*67e74705SXin Li }
7446*67e74705SXin Li 
clang_CXXConstructor_isCopyConstructor(CXCursor C)7447*67e74705SXin Li unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
7448*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7449*67e74705SXin Li     return 0;
7450*67e74705SXin Li 
7451*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(C);
7452*67e74705SXin Li   const CXXConstructorDecl *Constructor =
7453*67e74705SXin Li       D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7454*67e74705SXin Li   return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
7455*67e74705SXin Li }
7456*67e74705SXin Li 
clang_CXXConstructor_isMoveConstructor(CXCursor C)7457*67e74705SXin Li unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
7458*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7459*67e74705SXin Li     return 0;
7460*67e74705SXin Li 
7461*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(C);
7462*67e74705SXin Li   const CXXConstructorDecl *Constructor =
7463*67e74705SXin Li       D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7464*67e74705SXin Li   return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
7465*67e74705SXin Li }
7466*67e74705SXin Li 
clang_CXXConstructor_isConvertingConstructor(CXCursor C)7467*67e74705SXin Li unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
7468*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7469*67e74705SXin Li     return 0;
7470*67e74705SXin Li 
7471*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(C);
7472*67e74705SXin Li   const CXXConstructorDecl *Constructor =
7473*67e74705SXin Li       D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
7474*67e74705SXin Li   // Passing 'false' excludes constructors marked 'explicit'.
7475*67e74705SXin Li   return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
7476*67e74705SXin Li }
7477*67e74705SXin Li 
clang_CXXField_isMutable(CXCursor C)7478*67e74705SXin Li unsigned clang_CXXField_isMutable(CXCursor C) {
7479*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7480*67e74705SXin Li     return 0;
7481*67e74705SXin Li 
7482*67e74705SXin Li   if (const auto D = cxcursor::getCursorDecl(C))
7483*67e74705SXin Li     if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
7484*67e74705SXin Li       return FD->isMutable() ? 1 : 0;
7485*67e74705SXin Li   return 0;
7486*67e74705SXin Li }
7487*67e74705SXin Li 
clang_CXXMethod_isPureVirtual(CXCursor C)7488*67e74705SXin Li unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
7489*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7490*67e74705SXin Li     return 0;
7491*67e74705SXin Li 
7492*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(C);
7493*67e74705SXin Li   const CXXMethodDecl *Method =
7494*67e74705SXin Li       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7495*67e74705SXin Li   return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
7496*67e74705SXin Li }
7497*67e74705SXin Li 
clang_CXXMethod_isConst(CXCursor C)7498*67e74705SXin Li unsigned clang_CXXMethod_isConst(CXCursor C) {
7499*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7500*67e74705SXin Li     return 0;
7501*67e74705SXin Li 
7502*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(C);
7503*67e74705SXin Li   const CXXMethodDecl *Method =
7504*67e74705SXin Li       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7505*67e74705SXin Li   return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
7506*67e74705SXin Li }
7507*67e74705SXin Li 
clang_CXXMethod_isDefaulted(CXCursor C)7508*67e74705SXin Li unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
7509*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7510*67e74705SXin Li     return 0;
7511*67e74705SXin Li 
7512*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(C);
7513*67e74705SXin Li   const CXXMethodDecl *Method =
7514*67e74705SXin Li       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7515*67e74705SXin Li   return (Method && Method->isDefaulted()) ? 1 : 0;
7516*67e74705SXin Li }
7517*67e74705SXin Li 
clang_CXXMethod_isStatic(CXCursor C)7518*67e74705SXin Li unsigned clang_CXXMethod_isStatic(CXCursor C) {
7519*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7520*67e74705SXin Li     return 0;
7521*67e74705SXin Li 
7522*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(C);
7523*67e74705SXin Li   const CXXMethodDecl *Method =
7524*67e74705SXin Li       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7525*67e74705SXin Li   return (Method && Method->isStatic()) ? 1 : 0;
7526*67e74705SXin Li }
7527*67e74705SXin Li 
clang_CXXMethod_isVirtual(CXCursor C)7528*67e74705SXin Li unsigned clang_CXXMethod_isVirtual(CXCursor C) {
7529*67e74705SXin Li   if (!clang_isDeclaration(C.kind))
7530*67e74705SXin Li     return 0;
7531*67e74705SXin Li 
7532*67e74705SXin Li   const Decl *D = cxcursor::getCursorDecl(C);
7533*67e74705SXin Li   const CXXMethodDecl *Method =
7534*67e74705SXin Li       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
7535*67e74705SXin Li   return (Method && Method->isVirtual()) ? 1 : 0;
7536*67e74705SXin Li }
7537*67e74705SXin Li } // end: extern "C"
7538*67e74705SXin Li 
7539*67e74705SXin Li //===----------------------------------------------------------------------===//
7540*67e74705SXin Li // Attribute introspection.
7541*67e74705SXin Li //===----------------------------------------------------------------------===//
7542*67e74705SXin Li 
7543*67e74705SXin Li extern "C" {
clang_getIBOutletCollectionType(CXCursor C)7544*67e74705SXin Li CXType clang_getIBOutletCollectionType(CXCursor C) {
7545*67e74705SXin Li   if (C.kind != CXCursor_IBOutletCollectionAttr)
7546*67e74705SXin Li     return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
7547*67e74705SXin Li 
7548*67e74705SXin Li   const IBOutletCollectionAttr *A =
7549*67e74705SXin Li     cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
7550*67e74705SXin Li 
7551*67e74705SXin Li   return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
7552*67e74705SXin Li }
7553*67e74705SXin Li } // end: extern "C"
7554*67e74705SXin Li 
7555*67e74705SXin Li //===----------------------------------------------------------------------===//
7556*67e74705SXin Li // Inspecting memory usage.
7557*67e74705SXin Li //===----------------------------------------------------------------------===//
7558*67e74705SXin Li 
7559*67e74705SXin Li typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
7560*67e74705SXin Li 
createCXTUResourceUsageEntry(MemUsageEntries & entries,enum CXTUResourceUsageKind k,unsigned long amount)7561*67e74705SXin Li static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
7562*67e74705SXin Li                                               enum CXTUResourceUsageKind k,
7563*67e74705SXin Li                                               unsigned long amount) {
7564*67e74705SXin Li   CXTUResourceUsageEntry entry = { k, amount };
7565*67e74705SXin Li   entries.push_back(entry);
7566*67e74705SXin Li }
7567*67e74705SXin Li 
7568*67e74705SXin Li extern "C" {
7569*67e74705SXin Li 
clang_getTUResourceUsageName(CXTUResourceUsageKind kind)7570*67e74705SXin Li const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
7571*67e74705SXin Li   const char *str = "";
7572*67e74705SXin Li   switch (kind) {
7573*67e74705SXin Li     case CXTUResourceUsage_AST:
7574*67e74705SXin Li       str = "ASTContext: expressions, declarations, and types";
7575*67e74705SXin Li       break;
7576*67e74705SXin Li     case CXTUResourceUsage_Identifiers:
7577*67e74705SXin Li       str = "ASTContext: identifiers";
7578*67e74705SXin Li       break;
7579*67e74705SXin Li     case CXTUResourceUsage_Selectors:
7580*67e74705SXin Li       str = "ASTContext: selectors";
7581*67e74705SXin Li       break;
7582*67e74705SXin Li     case CXTUResourceUsage_GlobalCompletionResults:
7583*67e74705SXin Li       str = "Code completion: cached global results";
7584*67e74705SXin Li       break;
7585*67e74705SXin Li     case CXTUResourceUsage_SourceManagerContentCache:
7586*67e74705SXin Li       str = "SourceManager: content cache allocator";
7587*67e74705SXin Li       break;
7588*67e74705SXin Li     case CXTUResourceUsage_AST_SideTables:
7589*67e74705SXin Li       str = "ASTContext: side tables";
7590*67e74705SXin Li       break;
7591*67e74705SXin Li     case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
7592*67e74705SXin Li       str = "SourceManager: malloc'ed memory buffers";
7593*67e74705SXin Li       break;
7594*67e74705SXin Li     case CXTUResourceUsage_SourceManager_Membuffer_MMap:
7595*67e74705SXin Li       str = "SourceManager: mmap'ed memory buffers";
7596*67e74705SXin Li       break;
7597*67e74705SXin Li     case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
7598*67e74705SXin Li       str = "ExternalASTSource: malloc'ed memory buffers";
7599*67e74705SXin Li       break;
7600*67e74705SXin Li     case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
7601*67e74705SXin Li       str = "ExternalASTSource: mmap'ed memory buffers";
7602*67e74705SXin Li       break;
7603*67e74705SXin Li     case CXTUResourceUsage_Preprocessor:
7604*67e74705SXin Li       str = "Preprocessor: malloc'ed memory";
7605*67e74705SXin Li       break;
7606*67e74705SXin Li     case CXTUResourceUsage_PreprocessingRecord:
7607*67e74705SXin Li       str = "Preprocessor: PreprocessingRecord";
7608*67e74705SXin Li       break;
7609*67e74705SXin Li     case CXTUResourceUsage_SourceManager_DataStructures:
7610*67e74705SXin Li       str = "SourceManager: data structures and tables";
7611*67e74705SXin Li       break;
7612*67e74705SXin Li     case CXTUResourceUsage_Preprocessor_HeaderSearch:
7613*67e74705SXin Li       str = "Preprocessor: header search tables";
7614*67e74705SXin Li       break;
7615*67e74705SXin Li   }
7616*67e74705SXin Li   return str;
7617*67e74705SXin Li }
7618*67e74705SXin Li 
clang_getCXTUResourceUsage(CXTranslationUnit TU)7619*67e74705SXin Li CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
7620*67e74705SXin Li   if (isNotUsableTU(TU)) {
7621*67e74705SXin Li     LOG_BAD_TU(TU);
7622*67e74705SXin Li     CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
7623*67e74705SXin Li     return usage;
7624*67e74705SXin Li   }
7625*67e74705SXin Li 
7626*67e74705SXin Li   ASTUnit *astUnit = cxtu::getASTUnit(TU);
7627*67e74705SXin Li   std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
7628*67e74705SXin Li   ASTContext &astContext = astUnit->getASTContext();
7629*67e74705SXin Li 
7630*67e74705SXin Li   // How much memory is used by AST nodes and types?
7631*67e74705SXin Li   createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7632*67e74705SXin Li     (unsigned long) astContext.getASTAllocatedMemory());
7633*67e74705SXin Li 
7634*67e74705SXin Li   // How much memory is used by identifiers?
7635*67e74705SXin Li   createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7636*67e74705SXin Li     (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7637*67e74705SXin Li 
7638*67e74705SXin Li   // How much memory is used for selectors?
7639*67e74705SXin Li   createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7640*67e74705SXin Li     (unsigned long) astContext.Selectors.getTotalMemory());
7641*67e74705SXin Li 
7642*67e74705SXin Li   // How much memory is used by ASTContext's side tables?
7643*67e74705SXin Li   createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7644*67e74705SXin Li     (unsigned long) astContext.getSideTableAllocatedMemory());
7645*67e74705SXin Li 
7646*67e74705SXin Li   // How much memory is used for caching global code completion results?
7647*67e74705SXin Li   unsigned long completionBytes = 0;
7648*67e74705SXin Li   if (GlobalCodeCompletionAllocator *completionAllocator =
7649*67e74705SXin Li       astUnit->getCachedCompletionAllocator().get()) {
7650*67e74705SXin Li     completionBytes = completionAllocator->getTotalMemory();
7651*67e74705SXin Li   }
7652*67e74705SXin Li   createCXTUResourceUsageEntry(*entries,
7653*67e74705SXin Li                                CXTUResourceUsage_GlobalCompletionResults,
7654*67e74705SXin Li                                completionBytes);
7655*67e74705SXin Li 
7656*67e74705SXin Li   // How much memory is being used by SourceManager's content cache?
7657*67e74705SXin Li   createCXTUResourceUsageEntry(*entries,
7658*67e74705SXin Li           CXTUResourceUsage_SourceManagerContentCache,
7659*67e74705SXin Li           (unsigned long) astContext.getSourceManager().getContentCacheSize());
7660*67e74705SXin Li 
7661*67e74705SXin Li   // How much memory is being used by the MemoryBuffer's in SourceManager?
7662*67e74705SXin Li   const SourceManager::MemoryBufferSizes &srcBufs =
7663*67e74705SXin Li     astUnit->getSourceManager().getMemoryBufferSizes();
7664*67e74705SXin Li 
7665*67e74705SXin Li   createCXTUResourceUsageEntry(*entries,
7666*67e74705SXin Li                                CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7667*67e74705SXin Li                                (unsigned long) srcBufs.malloc_bytes);
7668*67e74705SXin Li   createCXTUResourceUsageEntry(*entries,
7669*67e74705SXin Li                                CXTUResourceUsage_SourceManager_Membuffer_MMap,
7670*67e74705SXin Li                                (unsigned long) srcBufs.mmap_bytes);
7671*67e74705SXin Li   createCXTUResourceUsageEntry(*entries,
7672*67e74705SXin Li                                CXTUResourceUsage_SourceManager_DataStructures,
7673*67e74705SXin Li                                (unsigned long) astContext.getSourceManager()
7674*67e74705SXin Li                                 .getDataStructureSizes());
7675*67e74705SXin Li 
7676*67e74705SXin Li   // How much memory is being used by the ExternalASTSource?
7677*67e74705SXin Li   if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7678*67e74705SXin Li     const ExternalASTSource::MemoryBufferSizes &sizes =
7679*67e74705SXin Li       esrc->getMemoryBufferSizes();
7680*67e74705SXin Li 
7681*67e74705SXin Li     createCXTUResourceUsageEntry(*entries,
7682*67e74705SXin Li       CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7683*67e74705SXin Li                                  (unsigned long) sizes.malloc_bytes);
7684*67e74705SXin Li     createCXTUResourceUsageEntry(*entries,
7685*67e74705SXin Li       CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7686*67e74705SXin Li                                  (unsigned long) sizes.mmap_bytes);
7687*67e74705SXin Li   }
7688*67e74705SXin Li 
7689*67e74705SXin Li   // How much memory is being used by the Preprocessor?
7690*67e74705SXin Li   Preprocessor &pp = astUnit->getPreprocessor();
7691*67e74705SXin Li   createCXTUResourceUsageEntry(*entries,
7692*67e74705SXin Li                                CXTUResourceUsage_Preprocessor,
7693*67e74705SXin Li                                pp.getTotalMemory());
7694*67e74705SXin Li 
7695*67e74705SXin Li   if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7696*67e74705SXin Li     createCXTUResourceUsageEntry(*entries,
7697*67e74705SXin Li                                  CXTUResourceUsage_PreprocessingRecord,
7698*67e74705SXin Li                                  pRec->getTotalMemory());
7699*67e74705SXin Li   }
7700*67e74705SXin Li 
7701*67e74705SXin Li   createCXTUResourceUsageEntry(*entries,
7702*67e74705SXin Li                                CXTUResourceUsage_Preprocessor_HeaderSearch,
7703*67e74705SXin Li                                pp.getHeaderSearchInfo().getTotalMemory());
7704*67e74705SXin Li 
7705*67e74705SXin Li   CXTUResourceUsage usage = { (void*) entries.get(),
7706*67e74705SXin Li                             (unsigned) entries->size(),
7707*67e74705SXin Li                             !entries->empty() ? &(*entries)[0] : nullptr };
7708*67e74705SXin Li   entries.release();
7709*67e74705SXin Li   return usage;
7710*67e74705SXin Li }
7711*67e74705SXin Li 
clang_disposeCXTUResourceUsage(CXTUResourceUsage usage)7712*67e74705SXin Li void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7713*67e74705SXin Li   if (usage.data)
7714*67e74705SXin Li     delete (MemUsageEntries*) usage.data;
7715*67e74705SXin Li }
7716*67e74705SXin Li 
clang_getSkippedRanges(CXTranslationUnit TU,CXFile file)7717*67e74705SXin Li CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7718*67e74705SXin Li   CXSourceRangeList *skipped = new CXSourceRangeList;
7719*67e74705SXin Li   skipped->count = 0;
7720*67e74705SXin Li   skipped->ranges = nullptr;
7721*67e74705SXin Li 
7722*67e74705SXin Li   if (isNotUsableTU(TU)) {
7723*67e74705SXin Li     LOG_BAD_TU(TU);
7724*67e74705SXin Li     return skipped;
7725*67e74705SXin Li   }
7726*67e74705SXin Li 
7727*67e74705SXin Li   if (!file)
7728*67e74705SXin Li     return skipped;
7729*67e74705SXin Li 
7730*67e74705SXin Li   ASTUnit *astUnit = cxtu::getASTUnit(TU);
7731*67e74705SXin Li   PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7732*67e74705SXin Li   if (!ppRec)
7733*67e74705SXin Li     return skipped;
7734*67e74705SXin Li 
7735*67e74705SXin Li   ASTContext &Ctx = astUnit->getASTContext();
7736*67e74705SXin Li   SourceManager &sm = Ctx.getSourceManager();
7737*67e74705SXin Li   FileEntry *fileEntry = static_cast<FileEntry *>(file);
7738*67e74705SXin Li   FileID wantedFileID = sm.translateFile(fileEntry);
7739*67e74705SXin Li 
7740*67e74705SXin Li   const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7741*67e74705SXin Li   std::vector<SourceRange> wantedRanges;
7742*67e74705SXin Li   for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7743*67e74705SXin Li        i != ei; ++i) {
7744*67e74705SXin Li     if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7745*67e74705SXin Li       wantedRanges.push_back(*i);
7746*67e74705SXin Li   }
7747*67e74705SXin Li 
7748*67e74705SXin Li   skipped->count = wantedRanges.size();
7749*67e74705SXin Li   skipped->ranges = new CXSourceRange[skipped->count];
7750*67e74705SXin Li   for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7751*67e74705SXin Li     skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7752*67e74705SXin Li 
7753*67e74705SXin Li   return skipped;
7754*67e74705SXin Li }
7755*67e74705SXin Li 
clang_disposeSourceRangeList(CXSourceRangeList * ranges)7756*67e74705SXin Li void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7757*67e74705SXin Li   if (ranges) {
7758*67e74705SXin Li     delete[] ranges->ranges;
7759*67e74705SXin Li     delete ranges;
7760*67e74705SXin Li   }
7761*67e74705SXin Li }
7762*67e74705SXin Li 
7763*67e74705SXin Li } // end extern "C"
7764*67e74705SXin Li 
PrintLibclangResourceUsage(CXTranslationUnit TU)7765*67e74705SXin Li void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7766*67e74705SXin Li   CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7767*67e74705SXin Li   for (unsigned I = 0; I != Usage.numEntries; ++I)
7768*67e74705SXin Li     fprintf(stderr, "  %s: %lu\n",
7769*67e74705SXin Li             clang_getTUResourceUsageName(Usage.entries[I].kind),
7770*67e74705SXin Li             Usage.entries[I].amount);
7771*67e74705SXin Li 
7772*67e74705SXin Li   clang_disposeCXTUResourceUsage(Usage);
7773*67e74705SXin Li }
7774*67e74705SXin Li 
7775*67e74705SXin Li //===----------------------------------------------------------------------===//
7776*67e74705SXin Li // Misc. utility functions.
7777*67e74705SXin Li //===----------------------------------------------------------------------===//
7778*67e74705SXin Li 
7779*67e74705SXin Li /// Default to using an 8 MB stack size on "safety" threads.
7780*67e74705SXin Li static unsigned SafetyStackThreadSize = 8 << 20;
7781*67e74705SXin Li 
7782*67e74705SXin Li namespace clang {
7783*67e74705SXin Li 
RunSafely(llvm::CrashRecoveryContext & CRC,llvm::function_ref<void ()> Fn,unsigned Size)7784*67e74705SXin Li bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
7785*67e74705SXin Li                unsigned Size) {
7786*67e74705SXin Li   if (!Size)
7787*67e74705SXin Li     Size = GetSafetyThreadStackSize();
7788*67e74705SXin Li   if (Size)
7789*67e74705SXin Li     return CRC.RunSafelyOnThread(Fn, Size);
7790*67e74705SXin Li   return CRC.RunSafely(Fn);
7791*67e74705SXin Li }
7792*67e74705SXin Li 
GetSafetyThreadStackSize()7793*67e74705SXin Li unsigned GetSafetyThreadStackSize() {
7794*67e74705SXin Li   return SafetyStackThreadSize;
7795*67e74705SXin Li }
7796*67e74705SXin Li 
SetSafetyThreadStackSize(unsigned Value)7797*67e74705SXin Li void SetSafetyThreadStackSize(unsigned Value) {
7798*67e74705SXin Li   SafetyStackThreadSize = Value;
7799*67e74705SXin Li }
7800*67e74705SXin Li 
7801*67e74705SXin Li }
7802*67e74705SXin Li 
setThreadBackgroundPriority()7803*67e74705SXin Li void clang::setThreadBackgroundPriority() {
7804*67e74705SXin Li   if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7805*67e74705SXin Li     return;
7806*67e74705SXin Li 
7807*67e74705SXin Li #ifdef USE_DARWIN_THREADS
7808*67e74705SXin Li   setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7809*67e74705SXin Li #endif
7810*67e74705SXin Li }
7811*67e74705SXin Li 
printDiagsToStderr(ASTUnit * Unit)7812*67e74705SXin Li void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7813*67e74705SXin Li   if (!Unit)
7814*67e74705SXin Li     return;
7815*67e74705SXin Li 
7816*67e74705SXin Li   for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7817*67e74705SXin Li                                   DEnd = Unit->stored_diag_end();
7818*67e74705SXin Li        D != DEnd; ++D) {
7819*67e74705SXin Li     CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
7820*67e74705SXin Li     CXString Msg = clang_formatDiagnostic(&Diag,
7821*67e74705SXin Li                                 clang_defaultDiagnosticDisplayOptions());
7822*67e74705SXin Li     fprintf(stderr, "%s\n", clang_getCString(Msg));
7823*67e74705SXin Li     clang_disposeString(Msg);
7824*67e74705SXin Li   }
7825*67e74705SXin Li #ifdef LLVM_ON_WIN32
7826*67e74705SXin Li   // On Windows, force a flush, since there may be multiple copies of
7827*67e74705SXin Li   // stderr and stdout in the file system, all with different buffers
7828*67e74705SXin Li   // but writing to the same device.
7829*67e74705SXin Li   fflush(stderr);
7830*67e74705SXin Li #endif
7831*67e74705SXin Li }
7832*67e74705SXin Li 
getMacroInfo(const IdentifierInfo & II,SourceLocation MacroDefLoc,CXTranslationUnit TU)7833*67e74705SXin Li MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7834*67e74705SXin Li                                  SourceLocation MacroDefLoc,
7835*67e74705SXin Li                                  CXTranslationUnit TU){
7836*67e74705SXin Li   if (MacroDefLoc.isInvalid() || !TU)
7837*67e74705SXin Li     return nullptr;
7838*67e74705SXin Li   if (!II.hadMacroDefinition())
7839*67e74705SXin Li     return nullptr;
7840*67e74705SXin Li 
7841*67e74705SXin Li   ASTUnit *Unit = cxtu::getASTUnit(TU);
7842*67e74705SXin Li   Preprocessor &PP = Unit->getPreprocessor();
7843*67e74705SXin Li   MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
7844*67e74705SXin Li   if (MD) {
7845*67e74705SXin Li     for (MacroDirective::DefInfo
7846*67e74705SXin Li            Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7847*67e74705SXin Li       if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7848*67e74705SXin Li         return Def.getMacroInfo();
7849*67e74705SXin Li     }
7850*67e74705SXin Li   }
7851*67e74705SXin Li 
7852*67e74705SXin Li   return nullptr;
7853*67e74705SXin Li }
7854*67e74705SXin Li 
getMacroInfo(const MacroDefinitionRecord * MacroDef,CXTranslationUnit TU)7855*67e74705SXin Li const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
7856*67e74705SXin Li                                        CXTranslationUnit TU) {
7857*67e74705SXin Li   if (!MacroDef || !TU)
7858*67e74705SXin Li     return nullptr;
7859*67e74705SXin Li   const IdentifierInfo *II = MacroDef->getName();
7860*67e74705SXin Li   if (!II)
7861*67e74705SXin Li     return nullptr;
7862*67e74705SXin Li 
7863*67e74705SXin Li   return getMacroInfo(*II, MacroDef->getLocation(), TU);
7864*67e74705SXin Li }
7865*67e74705SXin Li 
7866*67e74705SXin Li MacroDefinitionRecord *
checkForMacroInMacroDefinition(const MacroInfo * MI,const Token & Tok,CXTranslationUnit TU)7867*67e74705SXin Li cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7868*67e74705SXin Li                                         CXTranslationUnit TU) {
7869*67e74705SXin Li   if (!MI || !TU)
7870*67e74705SXin Li     return nullptr;
7871*67e74705SXin Li   if (Tok.isNot(tok::raw_identifier))
7872*67e74705SXin Li     return nullptr;
7873*67e74705SXin Li 
7874*67e74705SXin Li   if (MI->getNumTokens() == 0)
7875*67e74705SXin Li     return nullptr;
7876*67e74705SXin Li   SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7877*67e74705SXin Li                        MI->getDefinitionEndLoc());
7878*67e74705SXin Li   ASTUnit *Unit = cxtu::getASTUnit(TU);
7879*67e74705SXin Li 
7880*67e74705SXin Li   // Check that the token is inside the definition and not its argument list.
7881*67e74705SXin Li   SourceManager &SM = Unit->getSourceManager();
7882*67e74705SXin Li   if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
7883*67e74705SXin Li     return nullptr;
7884*67e74705SXin Li   if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
7885*67e74705SXin Li     return nullptr;
7886*67e74705SXin Li 
7887*67e74705SXin Li   Preprocessor &PP = Unit->getPreprocessor();
7888*67e74705SXin Li   PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7889*67e74705SXin Li   if (!PPRec)
7890*67e74705SXin Li     return nullptr;
7891*67e74705SXin Li 
7892*67e74705SXin Li   IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
7893*67e74705SXin Li   if (!II.hadMacroDefinition())
7894*67e74705SXin Li     return nullptr;
7895*67e74705SXin Li 
7896*67e74705SXin Li   // Check that the identifier is not one of the macro arguments.
7897*67e74705SXin Li   if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
7898*67e74705SXin Li     return nullptr;
7899*67e74705SXin Li 
7900*67e74705SXin Li   MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
7901*67e74705SXin Li   if (!InnerMD)
7902*67e74705SXin Li     return nullptr;
7903*67e74705SXin Li 
7904*67e74705SXin Li   return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
7905*67e74705SXin Li }
7906*67e74705SXin Li 
7907*67e74705SXin Li MacroDefinitionRecord *
checkForMacroInMacroDefinition(const MacroInfo * MI,SourceLocation Loc,CXTranslationUnit TU)7908*67e74705SXin Li cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7909*67e74705SXin Li                                         CXTranslationUnit TU) {
7910*67e74705SXin Li   if (Loc.isInvalid() || !MI || !TU)
7911*67e74705SXin Li     return nullptr;
7912*67e74705SXin Li 
7913*67e74705SXin Li   if (MI->getNumTokens() == 0)
7914*67e74705SXin Li     return nullptr;
7915*67e74705SXin Li   ASTUnit *Unit = cxtu::getASTUnit(TU);
7916*67e74705SXin Li   Preprocessor &PP = Unit->getPreprocessor();
7917*67e74705SXin Li   if (!PP.getPreprocessingRecord())
7918*67e74705SXin Li     return nullptr;
7919*67e74705SXin Li   Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7920*67e74705SXin Li   Token Tok;
7921*67e74705SXin Li   if (PP.getRawToken(Loc, Tok))
7922*67e74705SXin Li     return nullptr;
7923*67e74705SXin Li 
7924*67e74705SXin Li   return checkForMacroInMacroDefinition(MI, Tok, TU);
7925*67e74705SXin Li }
7926*67e74705SXin Li 
7927*67e74705SXin Li extern "C" {
7928*67e74705SXin Li 
clang_getClangVersion()7929*67e74705SXin Li CXString clang_getClangVersion() {
7930*67e74705SXin Li   return cxstring::createDup(getClangFullVersion());
7931*67e74705SXin Li }
7932*67e74705SXin Li 
7933*67e74705SXin Li } // end: extern "C"
7934*67e74705SXin Li 
operator <<(CXTranslationUnit TU)7935*67e74705SXin Li Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7936*67e74705SXin Li   if (TU) {
7937*67e74705SXin Li     if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
7938*67e74705SXin Li       LogOS << '<' << Unit->getMainFileName() << '>';
7939*67e74705SXin Li       if (Unit->isMainFileAST())
7940*67e74705SXin Li         LogOS << " (" << Unit->getASTFileName() << ')';
7941*67e74705SXin Li       return *this;
7942*67e74705SXin Li     }
7943*67e74705SXin Li   } else {
7944*67e74705SXin Li     LogOS << "<NULL TU>";
7945*67e74705SXin Li   }
7946*67e74705SXin Li   return *this;
7947*67e74705SXin Li }
7948*67e74705SXin Li 
operator <<(const FileEntry * FE)7949*67e74705SXin Li Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7950*67e74705SXin Li   *this << FE->getName();
7951*67e74705SXin Li   return *this;
7952*67e74705SXin Li }
7953*67e74705SXin Li 
operator <<(CXCursor cursor)7954*67e74705SXin Li Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7955*67e74705SXin Li   CXString cursorName = clang_getCursorDisplayName(cursor);
7956*67e74705SXin Li   *this << cursorName << "@" << clang_getCursorLocation(cursor);
7957*67e74705SXin Li   clang_disposeString(cursorName);
7958*67e74705SXin Li   return *this;
7959*67e74705SXin Li }
7960*67e74705SXin Li 
operator <<(CXSourceLocation Loc)7961*67e74705SXin Li Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7962*67e74705SXin Li   CXFile File;
7963*67e74705SXin Li   unsigned Line, Column;
7964*67e74705SXin Li   clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
7965*67e74705SXin Li   CXString FileName = clang_getFileName(File);
7966*67e74705SXin Li   *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7967*67e74705SXin Li   clang_disposeString(FileName);
7968*67e74705SXin Li   return *this;
7969*67e74705SXin Li }
7970*67e74705SXin Li 
operator <<(CXSourceRange range)7971*67e74705SXin Li Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7972*67e74705SXin Li   CXSourceLocation BLoc = clang_getRangeStart(range);
7973*67e74705SXin Li   CXSourceLocation ELoc = clang_getRangeEnd(range);
7974*67e74705SXin Li 
7975*67e74705SXin Li   CXFile BFile;
7976*67e74705SXin Li   unsigned BLine, BColumn;
7977*67e74705SXin Li   clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
7978*67e74705SXin Li 
7979*67e74705SXin Li   CXFile EFile;
7980*67e74705SXin Li   unsigned ELine, EColumn;
7981*67e74705SXin Li   clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
7982*67e74705SXin Li 
7983*67e74705SXin Li   CXString BFileName = clang_getFileName(BFile);
7984*67e74705SXin Li   if (BFile == EFile) {
7985*67e74705SXin Li     *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7986*67e74705SXin Li                          BLine, BColumn, ELine, EColumn);
7987*67e74705SXin Li   } else {
7988*67e74705SXin Li     CXString EFileName = clang_getFileName(EFile);
7989*67e74705SXin Li     *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7990*67e74705SXin Li                           BLine, BColumn)
7991*67e74705SXin Li           << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7992*67e74705SXin Li                           ELine, EColumn);
7993*67e74705SXin Li     clang_disposeString(EFileName);
7994*67e74705SXin Li   }
7995*67e74705SXin Li   clang_disposeString(BFileName);
7996*67e74705SXin Li   return *this;
7997*67e74705SXin Li }
7998*67e74705SXin Li 
operator <<(CXString Str)7999*67e74705SXin Li Logger &cxindex::Logger::operator<<(CXString Str) {
8000*67e74705SXin Li   *this << clang_getCString(Str);
8001*67e74705SXin Li   return *this;
8002*67e74705SXin Li }
8003*67e74705SXin Li 
operator <<(const llvm::format_object_base & Fmt)8004*67e74705SXin Li Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
8005*67e74705SXin Li   LogOS << Fmt;
8006*67e74705SXin Li   return *this;
8007*67e74705SXin Li }
8008*67e74705SXin Li 
8009*67e74705SXin Li static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
8010*67e74705SXin Li 
~Logger()8011*67e74705SXin Li cxindex::Logger::~Logger() {
8012*67e74705SXin Li   llvm::sys::ScopedLock L(*LoggingMutex);
8013*67e74705SXin Li 
8014*67e74705SXin Li   static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
8015*67e74705SXin Li 
8016*67e74705SXin Li   raw_ostream &OS = llvm::errs();
8017*67e74705SXin Li   OS << "[libclang:" << Name << ':';
8018*67e74705SXin Li 
8019*67e74705SXin Li #ifdef USE_DARWIN_THREADS
8020*67e74705SXin Li   // TODO: Portability.
8021*67e74705SXin Li   mach_port_t tid = pthread_mach_thread_np(pthread_self());
8022*67e74705SXin Li   OS << tid << ':';
8023*67e74705SXin Li #endif
8024*67e74705SXin Li 
8025*67e74705SXin Li   llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
8026*67e74705SXin Li   OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
8027*67e74705SXin Li   OS << Msg << '\n';
8028*67e74705SXin Li 
8029*67e74705SXin Li   if (Trace) {
8030*67e74705SXin Li     llvm::sys::PrintStackTrace(OS);
8031*67e74705SXin Li     OS << "--------------------------------------------------\n";
8032*67e74705SXin Li   }
8033*67e74705SXin Li }
8034*67e74705SXin Li 
8035*67e74705SXin Li #ifdef CLANG_TOOL_EXTRA_BUILD
8036*67e74705SXin Li // This anchor is used to force the linker to link the clang-tidy plugin.
8037*67e74705SXin Li extern volatile int ClangTidyPluginAnchorSource;
8038*67e74705SXin Li static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
8039*67e74705SXin Li     ClangTidyPluginAnchorSource;
8040*67e74705SXin Li #endif
8041