106f32e7eSjoerg //===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file implements the main API hooks in the Clang-C Source Indexing
1006f32e7eSjoerg // library.
1106f32e7eSjoerg //
1206f32e7eSjoerg //===----------------------------------------------------------------------===//
1306f32e7eSjoerg 
1406f32e7eSjoerg #include "CIndexDiagnostic.h"
1506f32e7eSjoerg #include "CIndexer.h"
1606f32e7eSjoerg #include "CLog.h"
1706f32e7eSjoerg #include "CXCursor.h"
1806f32e7eSjoerg #include "CXSourceLocation.h"
1906f32e7eSjoerg #include "CXString.h"
2006f32e7eSjoerg #include "CXTranslationUnit.h"
2106f32e7eSjoerg #include "CXType.h"
2206f32e7eSjoerg #include "CursorVisitor.h"
2306f32e7eSjoerg #include "clang-c/FatalErrorHandler.h"
2406f32e7eSjoerg #include "clang/AST/Attr.h"
25*13fbcb42Sjoerg #include "clang/AST/DeclObjCCommon.h"
2606f32e7eSjoerg #include "clang/AST/Mangle.h"
27*13fbcb42Sjoerg #include "clang/AST/OpenMPClause.h"
2806f32e7eSjoerg #include "clang/AST/StmtVisitor.h"
2906f32e7eSjoerg #include "clang/Basic/Diagnostic.h"
3006f32e7eSjoerg #include "clang/Basic/DiagnosticCategories.h"
3106f32e7eSjoerg #include "clang/Basic/DiagnosticIDs.h"
3206f32e7eSjoerg #include "clang/Basic/Stack.h"
3306f32e7eSjoerg #include "clang/Basic/TargetInfo.h"
3406f32e7eSjoerg #include "clang/Basic/Version.h"
3506f32e7eSjoerg #include "clang/Frontend/ASTUnit.h"
3606f32e7eSjoerg #include "clang/Frontend/CompilerInstance.h"
3706f32e7eSjoerg #include "clang/Index/CommentToXML.h"
3806f32e7eSjoerg #include "clang/Lex/HeaderSearch.h"
3906f32e7eSjoerg #include "clang/Lex/Lexer.h"
4006f32e7eSjoerg #include "clang/Lex/PreprocessingRecord.h"
4106f32e7eSjoerg #include "clang/Lex/Preprocessor.h"
4206f32e7eSjoerg #include "llvm/ADT/Optional.h"
4306f32e7eSjoerg #include "llvm/ADT/STLExtras.h"
4406f32e7eSjoerg #include "llvm/ADT/StringSwitch.h"
4506f32e7eSjoerg #include "llvm/Config/llvm-config.h"
4606f32e7eSjoerg #include "llvm/Support/Compiler.h"
4706f32e7eSjoerg #include "llvm/Support/CrashRecoveryContext.h"
4806f32e7eSjoerg #include "llvm/Support/Format.h"
4906f32e7eSjoerg #include "llvm/Support/ManagedStatic.h"
5006f32e7eSjoerg #include "llvm/Support/MemoryBuffer.h"
5106f32e7eSjoerg #include "llvm/Support/Program.h"
5206f32e7eSjoerg #include "llvm/Support/SaveAndRestore.h"
5306f32e7eSjoerg #include "llvm/Support/Signals.h"
5406f32e7eSjoerg #include "llvm/Support/TargetSelect.h"
5506f32e7eSjoerg #include "llvm/Support/Threading.h"
5606f32e7eSjoerg #include "llvm/Support/Timer.h"
5706f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
5806f32e7eSjoerg #include <mutex>
5906f32e7eSjoerg 
6006f32e7eSjoerg #if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
6106f32e7eSjoerg #define USE_DARWIN_THREADS
6206f32e7eSjoerg #endif
6306f32e7eSjoerg 
6406f32e7eSjoerg #ifdef USE_DARWIN_THREADS
6506f32e7eSjoerg #include <pthread.h>
6606f32e7eSjoerg #endif
6706f32e7eSjoerg 
6806f32e7eSjoerg using namespace clang;
6906f32e7eSjoerg using namespace clang::cxcursor;
7006f32e7eSjoerg using namespace clang::cxtu;
7106f32e7eSjoerg using namespace clang::cxindex;
7206f32e7eSjoerg 
MakeCXTranslationUnit(CIndexer * CIdx,std::unique_ptr<ASTUnit> AU)7306f32e7eSjoerg CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,
7406f32e7eSjoerg                                               std::unique_ptr<ASTUnit> AU) {
7506f32e7eSjoerg   if (!AU)
7606f32e7eSjoerg     return nullptr;
7706f32e7eSjoerg   assert(CIdx);
7806f32e7eSjoerg   CXTranslationUnit D = new CXTranslationUnitImpl();
7906f32e7eSjoerg   D->CIdx = CIdx;
8006f32e7eSjoerg   D->TheASTUnit = AU.release();
8106f32e7eSjoerg   D->StringPool = new cxstring::CXStringPool();
8206f32e7eSjoerg   D->Diagnostics = nullptr;
8306f32e7eSjoerg   D->OverridenCursorsPool = createOverridenCXCursorsPool();
8406f32e7eSjoerg   D->CommentToXML = nullptr;
8506f32e7eSjoerg   D->ParsingOptions = 0;
8606f32e7eSjoerg   D->Arguments = {};
8706f32e7eSjoerg   return D;
8806f32e7eSjoerg }
8906f32e7eSjoerg 
isASTReadError(ASTUnit * AU)9006f32e7eSjoerg bool cxtu::isASTReadError(ASTUnit *AU) {
9106f32e7eSjoerg   for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
9206f32e7eSjoerg                                      DEnd = AU->stored_diag_end();
9306f32e7eSjoerg        D != DEnd; ++D) {
9406f32e7eSjoerg     if (D->getLevel() >= DiagnosticsEngine::Error &&
9506f32e7eSjoerg         DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
9606f32e7eSjoerg             diag::DiagCat_AST_Deserialization_Issue)
9706f32e7eSjoerg       return true;
9806f32e7eSjoerg   }
9906f32e7eSjoerg   return false;
10006f32e7eSjoerg }
10106f32e7eSjoerg 
~CXTUOwner()10206f32e7eSjoerg cxtu::CXTUOwner::~CXTUOwner() {
10306f32e7eSjoerg   if (TU)
10406f32e7eSjoerg     clang_disposeTranslationUnit(TU);
10506f32e7eSjoerg }
10606f32e7eSjoerg 
10706f32e7eSjoerg /// Compare two source ranges to determine their relative position in
10806f32e7eSjoerg /// the translation unit.
RangeCompare(SourceManager & SM,SourceRange R1,SourceRange R2)109*13fbcb42Sjoerg static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1,
11006f32e7eSjoerg                                           SourceRange R2) {
11106f32e7eSjoerg   assert(R1.isValid() && "First range is invalid?");
11206f32e7eSjoerg   assert(R2.isValid() && "Second range is invalid?");
11306f32e7eSjoerg   if (R1.getEnd() != R2.getBegin() &&
11406f32e7eSjoerg       SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
11506f32e7eSjoerg     return RangeBefore;
11606f32e7eSjoerg   if (R2.getEnd() != R1.getBegin() &&
11706f32e7eSjoerg       SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
11806f32e7eSjoerg     return RangeAfter;
11906f32e7eSjoerg   return RangeOverlap;
12006f32e7eSjoerg }
12106f32e7eSjoerg 
12206f32e7eSjoerg /// Determine if a source location falls within, before, or after a
12306f32e7eSjoerg ///   a given source range.
LocationCompare(SourceManager & SM,SourceLocation L,SourceRange R)12406f32e7eSjoerg static RangeComparisonResult LocationCompare(SourceManager &SM,
12506f32e7eSjoerg                                              SourceLocation L, SourceRange R) {
12606f32e7eSjoerg   assert(R.isValid() && "First range is invalid?");
12706f32e7eSjoerg   assert(L.isValid() && "Second range is invalid?");
12806f32e7eSjoerg   if (L == R.getBegin() || L == R.getEnd())
12906f32e7eSjoerg     return RangeOverlap;
13006f32e7eSjoerg   if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
13106f32e7eSjoerg     return RangeBefore;
13206f32e7eSjoerg   if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
13306f32e7eSjoerg     return RangeAfter;
13406f32e7eSjoerg   return RangeOverlap;
13506f32e7eSjoerg }
13606f32e7eSjoerg 
13706f32e7eSjoerg /// Translate a Clang source range into a CIndex source range.
13806f32e7eSjoerg ///
13906f32e7eSjoerg /// Clang internally represents ranges where the end location points to the
14006f32e7eSjoerg /// start of the token at the end. However, for external clients it is more
14106f32e7eSjoerg /// useful to have a CXSourceRange be a proper half-open interval. This routine
14206f32e7eSjoerg /// does the appropriate translation.
translateSourceRange(const SourceManager & SM,const LangOptions & LangOpts,const CharSourceRange & R)14306f32e7eSjoerg CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
14406f32e7eSjoerg                                           const LangOptions &LangOpts,
14506f32e7eSjoerg                                           const CharSourceRange &R) {
14606f32e7eSjoerg   // We want the last character in this location, so we will adjust the
14706f32e7eSjoerg   // location accordingly.
14806f32e7eSjoerg   SourceLocation EndLoc = R.getEnd();
14906f32e7eSjoerg   bool IsTokenRange = R.isTokenRange();
150*13fbcb42Sjoerg   if (EndLoc.isValid() && EndLoc.isMacroID() &&
151*13fbcb42Sjoerg       !SM.isMacroArgExpansion(EndLoc)) {
15206f32e7eSjoerg     CharSourceRange Expansion = SM.getExpansionRange(EndLoc);
15306f32e7eSjoerg     EndLoc = Expansion.getEnd();
15406f32e7eSjoerg     IsTokenRange = Expansion.isTokenRange();
15506f32e7eSjoerg   }
15606f32e7eSjoerg   if (IsTokenRange && EndLoc.isValid()) {
157*13fbcb42Sjoerg     unsigned Length =
158*13fbcb42Sjoerg         Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);
15906f32e7eSjoerg     EndLoc = EndLoc.getLocWithOffset(Length);
16006f32e7eSjoerg   }
16106f32e7eSjoerg 
16206f32e7eSjoerg   CXSourceRange Result = {
163*13fbcb42Sjoerg       {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};
16406f32e7eSjoerg   return Result;
16506f32e7eSjoerg }
16606f32e7eSjoerg 
translateCXRangeToCharRange(CXSourceRange R)167*13fbcb42Sjoerg CharSourceRange cxloc::translateCXRangeToCharRange(CXSourceRange R) {
168*13fbcb42Sjoerg   return CharSourceRange::getCharRange(
169*13fbcb42Sjoerg       SourceLocation::getFromRawEncoding(R.begin_int_data),
170*13fbcb42Sjoerg       SourceLocation::getFromRawEncoding(R.end_int_data));
171*13fbcb42Sjoerg }
172*13fbcb42Sjoerg 
17306f32e7eSjoerg //===----------------------------------------------------------------------===//
17406f32e7eSjoerg // Cursor visitor.
17506f32e7eSjoerg //===----------------------------------------------------------------------===//
17606f32e7eSjoerg 
17706f32e7eSjoerg static SourceRange getRawCursorExtent(CXCursor C);
17806f32e7eSjoerg static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
17906f32e7eSjoerg 
CompareRegionOfInterest(SourceRange R)18006f32e7eSjoerg RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
18106f32e7eSjoerg   return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
18206f32e7eSjoerg }
18306f32e7eSjoerg 
18406f32e7eSjoerg /// Visit the given cursor and, if requested by the visitor,
18506f32e7eSjoerg /// its children.
18606f32e7eSjoerg ///
18706f32e7eSjoerg /// \param Cursor the cursor to visit.
18806f32e7eSjoerg ///
18906f32e7eSjoerg /// \param CheckedRegionOfInterest if true, then the caller already checked
19006f32e7eSjoerg /// that this cursor is within the region of interest.
19106f32e7eSjoerg ///
19206f32e7eSjoerg /// \returns true if the visitation should be aborted, false if it
19306f32e7eSjoerg /// should continue.
Visit(CXCursor Cursor,bool CheckedRegionOfInterest)19406f32e7eSjoerg bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
19506f32e7eSjoerg   if (clang_isInvalid(Cursor.kind))
19606f32e7eSjoerg     return false;
19706f32e7eSjoerg 
19806f32e7eSjoerg   if (clang_isDeclaration(Cursor.kind)) {
19906f32e7eSjoerg     const Decl *D = getCursorDecl(Cursor);
20006f32e7eSjoerg     if (!D) {
20106f32e7eSjoerg       assert(0 && "Invalid declaration cursor");
20206f32e7eSjoerg       return true; // abort.
20306f32e7eSjoerg     }
20406f32e7eSjoerg 
20506f32e7eSjoerg     // Ignore implicit declarations, unless it's an objc method because
20606f32e7eSjoerg     // currently we should report implicit methods for properties when indexing.
20706f32e7eSjoerg     if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
20806f32e7eSjoerg       return false;
20906f32e7eSjoerg   }
21006f32e7eSjoerg 
21106f32e7eSjoerg   // If we have a range of interest, and this cursor doesn't intersect with it,
21206f32e7eSjoerg   // we're done.
21306f32e7eSjoerg   if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
21406f32e7eSjoerg     SourceRange Range = getRawCursorExtent(Cursor);
21506f32e7eSjoerg     if (Range.isInvalid() || CompareRegionOfInterest(Range))
21606f32e7eSjoerg       return false;
21706f32e7eSjoerg   }
21806f32e7eSjoerg 
21906f32e7eSjoerg   switch (Visitor(Cursor, Parent, ClientData)) {
22006f32e7eSjoerg   case CXChildVisit_Break:
22106f32e7eSjoerg     return true;
22206f32e7eSjoerg 
22306f32e7eSjoerg   case CXChildVisit_Continue:
22406f32e7eSjoerg     return false;
22506f32e7eSjoerg 
22606f32e7eSjoerg   case CXChildVisit_Recurse: {
22706f32e7eSjoerg     bool ret = VisitChildren(Cursor);
22806f32e7eSjoerg     if (PostChildrenVisitor)
22906f32e7eSjoerg       if (PostChildrenVisitor(Cursor, ClientData))
23006f32e7eSjoerg         return true;
23106f32e7eSjoerg     return ret;
23206f32e7eSjoerg   }
23306f32e7eSjoerg   }
23406f32e7eSjoerg 
23506f32e7eSjoerg   llvm_unreachable("Invalid CXChildVisitResult!");
23606f32e7eSjoerg }
23706f32e7eSjoerg 
visitPreprocessedEntitiesInRange(SourceRange R,PreprocessingRecord & PPRec,CursorVisitor & Visitor)23806f32e7eSjoerg static bool visitPreprocessedEntitiesInRange(SourceRange R,
23906f32e7eSjoerg                                              PreprocessingRecord &PPRec,
24006f32e7eSjoerg                                              CursorVisitor &Visitor) {
24106f32e7eSjoerg   SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
24206f32e7eSjoerg   FileID FID;
24306f32e7eSjoerg 
24406f32e7eSjoerg   if (!Visitor.shouldVisitIncludedEntities()) {
24506f32e7eSjoerg     // If the begin/end of the range lie in the same FileID, do the optimization
246*13fbcb42Sjoerg     // where we skip preprocessed entities that do not come from the same
247*13fbcb42Sjoerg     // FileID.
24806f32e7eSjoerg     FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
24906f32e7eSjoerg     if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
25006f32e7eSjoerg       FID = FileID();
25106f32e7eSjoerg   }
25206f32e7eSjoerg 
25306f32e7eSjoerg   const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
25406f32e7eSjoerg   return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
25506f32e7eSjoerg                                            PPRec, FID);
25606f32e7eSjoerg }
25706f32e7eSjoerg 
visitFileRegion()25806f32e7eSjoerg bool CursorVisitor::visitFileRegion() {
25906f32e7eSjoerg   if (RegionOfInterest.isInvalid())
26006f32e7eSjoerg     return false;
26106f32e7eSjoerg 
26206f32e7eSjoerg   ASTUnit *Unit = cxtu::getASTUnit(TU);
26306f32e7eSjoerg   SourceManager &SM = Unit->getSourceManager();
26406f32e7eSjoerg 
265*13fbcb42Sjoerg   std::pair<FileID, unsigned> Begin = SM.getDecomposedLoc(
266*13fbcb42Sjoerg                                   SM.getFileLoc(RegionOfInterest.getBegin())),
267*13fbcb42Sjoerg                               End = SM.getDecomposedLoc(
268*13fbcb42Sjoerg                                   SM.getFileLoc(RegionOfInterest.getEnd()));
26906f32e7eSjoerg 
27006f32e7eSjoerg   if (End.first != Begin.first) {
27106f32e7eSjoerg     // If the end does not reside in the same file, try to recover by
27206f32e7eSjoerg     // picking the end of the file of begin location.
27306f32e7eSjoerg     End.first = Begin.first;
27406f32e7eSjoerg     End.second = SM.getFileIDSize(Begin.first);
27506f32e7eSjoerg   }
27606f32e7eSjoerg 
27706f32e7eSjoerg   assert(Begin.first == End.first);
27806f32e7eSjoerg   if (Begin.second > End.second)
27906f32e7eSjoerg     return false;
28006f32e7eSjoerg 
28106f32e7eSjoerg   FileID File = Begin.first;
28206f32e7eSjoerg   unsigned Offset = Begin.second;
28306f32e7eSjoerg   unsigned Length = End.second - Begin.second;
28406f32e7eSjoerg 
28506f32e7eSjoerg   if (!VisitDeclsOnly && !VisitPreprocessorLast)
28606f32e7eSjoerg     if (visitPreprocessedEntitiesInRegion())
28706f32e7eSjoerg       return true; // visitation break.
28806f32e7eSjoerg 
28906f32e7eSjoerg   if (visitDeclsFromFileRegion(File, Offset, Length))
29006f32e7eSjoerg     return true; // visitation break.
29106f32e7eSjoerg 
29206f32e7eSjoerg   if (!VisitDeclsOnly && VisitPreprocessorLast)
29306f32e7eSjoerg     return visitPreprocessedEntitiesInRegion();
29406f32e7eSjoerg 
29506f32e7eSjoerg   return false;
29606f32e7eSjoerg }
29706f32e7eSjoerg 
isInLexicalContext(Decl * D,DeclContext * DC)29806f32e7eSjoerg static bool isInLexicalContext(Decl *D, DeclContext *DC) {
29906f32e7eSjoerg   if (!DC)
30006f32e7eSjoerg     return false;
30106f32e7eSjoerg 
302*13fbcb42Sjoerg   for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;
303*13fbcb42Sjoerg        DeclDC = DeclDC->getLexicalParent()) {
30406f32e7eSjoerg     if (DeclDC == DC)
30506f32e7eSjoerg       return true;
30606f32e7eSjoerg   }
30706f32e7eSjoerg   return false;
30806f32e7eSjoerg }
30906f32e7eSjoerg 
visitDeclsFromFileRegion(FileID File,unsigned Offset,unsigned Length)310*13fbcb42Sjoerg bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,
311*13fbcb42Sjoerg                                              unsigned Length) {
31206f32e7eSjoerg   ASTUnit *Unit = cxtu::getASTUnit(TU);
31306f32e7eSjoerg   SourceManager &SM = Unit->getSourceManager();
31406f32e7eSjoerg   SourceRange Range = RegionOfInterest;
31506f32e7eSjoerg 
31606f32e7eSjoerg   SmallVector<Decl *, 16> Decls;
31706f32e7eSjoerg   Unit->findFileRegionDecls(File, Offset, Length, Decls);
31806f32e7eSjoerg 
31906f32e7eSjoerg   // If we didn't find any file level decls for the file, try looking at the
32006f32e7eSjoerg   // file that it was included from.
32106f32e7eSjoerg   while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
32206f32e7eSjoerg     bool Invalid = false;
32306f32e7eSjoerg     const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
32406f32e7eSjoerg     if (Invalid)
32506f32e7eSjoerg       return false;
32606f32e7eSjoerg 
32706f32e7eSjoerg     SourceLocation Outer;
32806f32e7eSjoerg     if (SLEntry.isFile())
32906f32e7eSjoerg       Outer = SLEntry.getFile().getIncludeLoc();
33006f32e7eSjoerg     else
33106f32e7eSjoerg       Outer = SLEntry.getExpansion().getExpansionLocStart();
33206f32e7eSjoerg     if (Outer.isInvalid())
33306f32e7eSjoerg       return false;
33406f32e7eSjoerg 
33506f32e7eSjoerg     std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
33606f32e7eSjoerg     Length = 0;
33706f32e7eSjoerg     Unit->findFileRegionDecls(File, Offset, Length, Decls);
33806f32e7eSjoerg   }
33906f32e7eSjoerg 
34006f32e7eSjoerg   assert(!Decls.empty());
34106f32e7eSjoerg 
34206f32e7eSjoerg   bool VisitedAtLeastOnce = false;
34306f32e7eSjoerg   DeclContext *CurDC = nullptr;
34406f32e7eSjoerg   SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
34506f32e7eSjoerg   for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
34606f32e7eSjoerg     Decl *D = *DIt;
34706f32e7eSjoerg     if (D->getSourceRange().isInvalid())
34806f32e7eSjoerg       continue;
34906f32e7eSjoerg 
35006f32e7eSjoerg     if (isInLexicalContext(D, CurDC))
35106f32e7eSjoerg       continue;
35206f32e7eSjoerg 
35306f32e7eSjoerg     CurDC = dyn_cast<DeclContext>(D);
35406f32e7eSjoerg 
35506f32e7eSjoerg     if (TagDecl *TD = dyn_cast<TagDecl>(D))
35606f32e7eSjoerg       if (!TD->isFreeStanding())
35706f32e7eSjoerg         continue;
35806f32e7eSjoerg 
359*13fbcb42Sjoerg     RangeComparisonResult CompRes =
360*13fbcb42Sjoerg         RangeCompare(SM, D->getSourceRange(), Range);
36106f32e7eSjoerg     if (CompRes == RangeBefore)
36206f32e7eSjoerg       continue;
36306f32e7eSjoerg     if (CompRes == RangeAfter)
36406f32e7eSjoerg       break;
36506f32e7eSjoerg 
36606f32e7eSjoerg     assert(CompRes == RangeOverlap);
36706f32e7eSjoerg     VisitedAtLeastOnce = true;
36806f32e7eSjoerg 
36906f32e7eSjoerg     if (isa<ObjCContainerDecl>(D)) {
37006f32e7eSjoerg       FileDI_current = &DIt;
37106f32e7eSjoerg       FileDE_current = DE;
37206f32e7eSjoerg     } else {
37306f32e7eSjoerg       FileDI_current = nullptr;
37406f32e7eSjoerg     }
37506f32e7eSjoerg 
37606f32e7eSjoerg     if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
37706f32e7eSjoerg       return true; // visitation break.
37806f32e7eSjoerg   }
37906f32e7eSjoerg 
38006f32e7eSjoerg   if (VisitedAtLeastOnce)
38106f32e7eSjoerg     return false;
38206f32e7eSjoerg 
38306f32e7eSjoerg   // No Decls overlapped with the range. Move up the lexical context until there
38406f32e7eSjoerg   // is a context that contains the range or we reach the translation unit
38506f32e7eSjoerg   // level.
386*13fbcb42Sjoerg   DeclContext *DC = DIt == Decls.begin()
387*13fbcb42Sjoerg                         ? (*DIt)->getLexicalDeclContext()
38806f32e7eSjoerg                         : (*(DIt - 1))->getLexicalDeclContext();
38906f32e7eSjoerg 
39006f32e7eSjoerg   while (DC && !DC->isTranslationUnit()) {
39106f32e7eSjoerg     Decl *D = cast<Decl>(DC);
39206f32e7eSjoerg     SourceRange CurDeclRange = D->getSourceRange();
39306f32e7eSjoerg     if (CurDeclRange.isInvalid())
39406f32e7eSjoerg       break;
39506f32e7eSjoerg 
39606f32e7eSjoerg     if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
39706f32e7eSjoerg       if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
39806f32e7eSjoerg         return true; // visitation break.
39906f32e7eSjoerg     }
40006f32e7eSjoerg 
40106f32e7eSjoerg     DC = D->getLexicalDeclContext();
40206f32e7eSjoerg   }
40306f32e7eSjoerg 
40406f32e7eSjoerg   return false;
40506f32e7eSjoerg }
40606f32e7eSjoerg 
visitPreprocessedEntitiesInRegion()40706f32e7eSjoerg bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
40806f32e7eSjoerg   if (!AU->getPreprocessor().getPreprocessingRecord())
40906f32e7eSjoerg     return false;
41006f32e7eSjoerg 
411*13fbcb42Sjoerg   PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();
41206f32e7eSjoerg   SourceManager &SM = AU->getSourceManager();
41306f32e7eSjoerg 
41406f32e7eSjoerg   if (RegionOfInterest.isValid()) {
41506f32e7eSjoerg     SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
41606f32e7eSjoerg     SourceLocation B = MappedRange.getBegin();
41706f32e7eSjoerg     SourceLocation E = MappedRange.getEnd();
41806f32e7eSjoerg 
41906f32e7eSjoerg     if (AU->isInPreambleFileID(B)) {
42006f32e7eSjoerg       if (SM.isLoadedSourceLocation(E))
421*13fbcb42Sjoerg         return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,
422*13fbcb42Sjoerg                                                 *this);
42306f32e7eSjoerg 
42406f32e7eSjoerg       // Beginning of range lies in the preamble but it also extends beyond
42506f32e7eSjoerg       // it into the main file. Split the range into 2 parts, one covering
42606f32e7eSjoerg       // the preamble and another covering the main file. This allows subsequent
42706f32e7eSjoerg       // calls to visitPreprocessedEntitiesInRange to accept a source range that
42806f32e7eSjoerg       // lies in the same FileID, allowing it to skip preprocessed entities that
42906f32e7eSjoerg       // do not come from the same FileID.
430*13fbcb42Sjoerg       bool breaked = visitPreprocessedEntitiesInRange(
431*13fbcb42Sjoerg           SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);
432*13fbcb42Sjoerg       if (breaked)
433*13fbcb42Sjoerg         return true;
43406f32e7eSjoerg       return visitPreprocessedEntitiesInRange(
435*13fbcb42Sjoerg           SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);
43606f32e7eSjoerg     }
43706f32e7eSjoerg 
43806f32e7eSjoerg     return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
43906f32e7eSjoerg   }
44006f32e7eSjoerg 
441*13fbcb42Sjoerg   bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
44206f32e7eSjoerg 
44306f32e7eSjoerg   if (OnlyLocalDecls)
44406f32e7eSjoerg     return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
44506f32e7eSjoerg                                      PPRec);
44606f32e7eSjoerg 
44706f32e7eSjoerg   return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
44806f32e7eSjoerg }
44906f32e7eSjoerg 
45006f32e7eSjoerg template <typename InputIterator>
visitPreprocessedEntities(InputIterator First,InputIterator Last,PreprocessingRecord & PPRec,FileID FID)45106f32e7eSjoerg bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
45206f32e7eSjoerg                                               InputIterator Last,
45306f32e7eSjoerg                                               PreprocessingRecord &PPRec,
45406f32e7eSjoerg                                               FileID FID) {
45506f32e7eSjoerg   for (; First != Last; ++First) {
45606f32e7eSjoerg     if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
45706f32e7eSjoerg       continue;
45806f32e7eSjoerg 
45906f32e7eSjoerg     PreprocessedEntity *PPE = *First;
46006f32e7eSjoerg     if (!PPE)
46106f32e7eSjoerg       continue;
46206f32e7eSjoerg 
46306f32e7eSjoerg     if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
46406f32e7eSjoerg       if (Visit(MakeMacroExpansionCursor(ME, TU)))
46506f32e7eSjoerg         return true;
46606f32e7eSjoerg 
46706f32e7eSjoerg       continue;
46806f32e7eSjoerg     }
46906f32e7eSjoerg 
47006f32e7eSjoerg     if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
47106f32e7eSjoerg       if (Visit(MakeMacroDefinitionCursor(MD, TU)))
47206f32e7eSjoerg         return true;
47306f32e7eSjoerg 
47406f32e7eSjoerg       continue;
47506f32e7eSjoerg     }
47606f32e7eSjoerg 
47706f32e7eSjoerg     if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
47806f32e7eSjoerg       if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
47906f32e7eSjoerg         return true;
48006f32e7eSjoerg 
48106f32e7eSjoerg       continue;
48206f32e7eSjoerg     }
48306f32e7eSjoerg   }
48406f32e7eSjoerg 
48506f32e7eSjoerg   return false;
48606f32e7eSjoerg }
48706f32e7eSjoerg 
48806f32e7eSjoerg /// Visit the children of the given cursor.
48906f32e7eSjoerg ///
49006f32e7eSjoerg /// \returns true if the visitation should be aborted, false if it
49106f32e7eSjoerg /// should continue.
VisitChildren(CXCursor Cursor)49206f32e7eSjoerg bool CursorVisitor::VisitChildren(CXCursor Cursor) {
49306f32e7eSjoerg   if (clang_isReference(Cursor.kind) &&
49406f32e7eSjoerg       Cursor.kind != CXCursor_CXXBaseSpecifier) {
49506f32e7eSjoerg     // By definition, references have no children.
49606f32e7eSjoerg     return false;
49706f32e7eSjoerg   }
49806f32e7eSjoerg 
49906f32e7eSjoerg   // Set the Parent field to Cursor, then back to its old value once we're
50006f32e7eSjoerg   // done.
50106f32e7eSjoerg   SetParentRAII SetParent(Parent, StmtParent, Cursor);
50206f32e7eSjoerg 
50306f32e7eSjoerg   if (clang_isDeclaration(Cursor.kind)) {
50406f32e7eSjoerg     Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
50506f32e7eSjoerg     if (!D)
50606f32e7eSjoerg       return false;
50706f32e7eSjoerg 
50806f32e7eSjoerg     return VisitAttributes(D) || Visit(D);
50906f32e7eSjoerg   }
51006f32e7eSjoerg 
51106f32e7eSjoerg   if (clang_isStatement(Cursor.kind)) {
51206f32e7eSjoerg     if (const Stmt *S = getCursorStmt(Cursor))
51306f32e7eSjoerg       return Visit(S);
51406f32e7eSjoerg 
51506f32e7eSjoerg     return false;
51606f32e7eSjoerg   }
51706f32e7eSjoerg 
51806f32e7eSjoerg   if (clang_isExpression(Cursor.kind)) {
51906f32e7eSjoerg     if (const Expr *E = getCursorExpr(Cursor))
52006f32e7eSjoerg       return Visit(E);
52106f32e7eSjoerg 
52206f32e7eSjoerg     return false;
52306f32e7eSjoerg   }
52406f32e7eSjoerg 
52506f32e7eSjoerg   if (clang_isTranslationUnit(Cursor.kind)) {
52606f32e7eSjoerg     CXTranslationUnit TU = getCursorTU(Cursor);
52706f32e7eSjoerg     ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
52806f32e7eSjoerg 
52906f32e7eSjoerg     int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
53006f32e7eSjoerg     for (unsigned I = 0; I != 2; ++I) {
53106f32e7eSjoerg       if (VisitOrder[I]) {
53206f32e7eSjoerg         if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
53306f32e7eSjoerg             RegionOfInterest.isInvalid()) {
53406f32e7eSjoerg           for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
53506f32e7eSjoerg                                            TLEnd = CXXUnit->top_level_end();
53606f32e7eSjoerg                TL != TLEnd; ++TL) {
53706f32e7eSjoerg             const Optional<bool> V = handleDeclForVisitation(*TL);
53806f32e7eSjoerg             if (!V.hasValue())
53906f32e7eSjoerg               continue;
54006f32e7eSjoerg             return V.getValue();
54106f32e7eSjoerg           }
54206f32e7eSjoerg         } else if (VisitDeclContext(
54306f32e7eSjoerg                        CXXUnit->getASTContext().getTranslationUnitDecl()))
54406f32e7eSjoerg           return true;
54506f32e7eSjoerg         continue;
54606f32e7eSjoerg       }
54706f32e7eSjoerg 
54806f32e7eSjoerg       // Walk the preprocessing record.
54906f32e7eSjoerg       if (CXXUnit->getPreprocessor().getPreprocessingRecord())
55006f32e7eSjoerg         visitPreprocessedEntitiesInRegion();
55106f32e7eSjoerg     }
55206f32e7eSjoerg 
55306f32e7eSjoerg     return false;
55406f32e7eSjoerg   }
55506f32e7eSjoerg 
55606f32e7eSjoerg   if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
55706f32e7eSjoerg     if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
55806f32e7eSjoerg       if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
55906f32e7eSjoerg         return Visit(BaseTSInfo->getTypeLoc());
56006f32e7eSjoerg       }
56106f32e7eSjoerg     }
56206f32e7eSjoerg   }
56306f32e7eSjoerg 
56406f32e7eSjoerg   if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
56506f32e7eSjoerg     const IBOutletCollectionAttr *A =
56606f32e7eSjoerg         cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
56706f32e7eSjoerg     if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
56806f32e7eSjoerg       return Visit(cxcursor::MakeCursorObjCClassRef(
56906f32e7eSjoerg           ObjT->getInterface(),
57006f32e7eSjoerg           A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));
57106f32e7eSjoerg   }
57206f32e7eSjoerg 
57306f32e7eSjoerg   // If pointing inside a macro definition, check if the token is an identifier
57406f32e7eSjoerg   // that was ever defined as a macro. In such a case, create a "pseudo" macro
57506f32e7eSjoerg   // expansion cursor for that token.
57606f32e7eSjoerg   SourceLocation BeginLoc = RegionOfInterest.getBegin();
57706f32e7eSjoerg   if (Cursor.kind == CXCursor_MacroDefinition &&
57806f32e7eSjoerg       BeginLoc == RegionOfInterest.getEnd()) {
57906f32e7eSjoerg     SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
58006f32e7eSjoerg     const MacroInfo *MI =
58106f32e7eSjoerg         getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
58206f32e7eSjoerg     if (MacroDefinitionRecord *MacroDef =
58306f32e7eSjoerg             checkForMacroInMacroDefinition(MI, Loc, TU))
58406f32e7eSjoerg       return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
58506f32e7eSjoerg   }
58606f32e7eSjoerg 
58706f32e7eSjoerg   // Nothing to visit at the moment.
58806f32e7eSjoerg   return false;
58906f32e7eSjoerg }
59006f32e7eSjoerg 
VisitBlockDecl(BlockDecl * B)59106f32e7eSjoerg bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
59206f32e7eSjoerg   if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
59306f32e7eSjoerg     if (Visit(TSInfo->getTypeLoc()))
59406f32e7eSjoerg       return true;
59506f32e7eSjoerg 
59606f32e7eSjoerg   if (Stmt *Body = B->getBody())
59706f32e7eSjoerg     return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
59806f32e7eSjoerg 
59906f32e7eSjoerg   return false;
60006f32e7eSjoerg }
60106f32e7eSjoerg 
shouldVisitCursor(CXCursor Cursor)60206f32e7eSjoerg Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
60306f32e7eSjoerg   if (RegionOfInterest.isValid()) {
60406f32e7eSjoerg     SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
60506f32e7eSjoerg     if (Range.isInvalid())
60606f32e7eSjoerg       return None;
60706f32e7eSjoerg 
60806f32e7eSjoerg     switch (CompareRegionOfInterest(Range)) {
60906f32e7eSjoerg     case RangeBefore:
61006f32e7eSjoerg       // This declaration comes before the region of interest; skip it.
61106f32e7eSjoerg       return None;
61206f32e7eSjoerg 
61306f32e7eSjoerg     case RangeAfter:
61406f32e7eSjoerg       // This declaration comes after the region of interest; we're done.
61506f32e7eSjoerg       return false;
61606f32e7eSjoerg 
61706f32e7eSjoerg     case RangeOverlap:
61806f32e7eSjoerg       // This declaration overlaps the region of interest; visit it.
61906f32e7eSjoerg       break;
62006f32e7eSjoerg     }
62106f32e7eSjoerg   }
62206f32e7eSjoerg   return true;
62306f32e7eSjoerg }
62406f32e7eSjoerg 
VisitDeclContext(DeclContext * DC)62506f32e7eSjoerg bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
62606f32e7eSjoerg   DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
62706f32e7eSjoerg 
62806f32e7eSjoerg   // FIXME: Eventually remove.  This part of a hack to support proper
62906f32e7eSjoerg   // iteration over all Decls contained lexically within an ObjC container.
63006f32e7eSjoerg   SaveAndRestore<DeclContext::decl_iterator *> DI_saved(DI_current, &I);
63106f32e7eSjoerg   SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
63206f32e7eSjoerg 
63306f32e7eSjoerg   for (; I != E; ++I) {
63406f32e7eSjoerg     Decl *D = *I;
63506f32e7eSjoerg     if (D->getLexicalDeclContext() != DC)
63606f32e7eSjoerg       continue;
637*13fbcb42Sjoerg     // Filter out synthesized property accessor redeclarations.
638*13fbcb42Sjoerg     if (isa<ObjCImplDecl>(DC))
639*13fbcb42Sjoerg       if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
640*13fbcb42Sjoerg         if (OMD->isSynthesizedAccessorStub())
641*13fbcb42Sjoerg           continue;
64206f32e7eSjoerg     const Optional<bool> V = handleDeclForVisitation(D);
64306f32e7eSjoerg     if (!V.hasValue())
64406f32e7eSjoerg       continue;
64506f32e7eSjoerg     return V.getValue();
64606f32e7eSjoerg   }
64706f32e7eSjoerg   return false;
64806f32e7eSjoerg }
64906f32e7eSjoerg 
handleDeclForVisitation(const Decl * D)65006f32e7eSjoerg Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
65106f32e7eSjoerg   CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
65206f32e7eSjoerg 
65306f32e7eSjoerg   // Ignore synthesized ivars here, otherwise if we have something like:
65406f32e7eSjoerg   //   @synthesize prop = _prop;
65506f32e7eSjoerg   // and '_prop' is not declared, we will encounter a '_prop' ivar before
65606f32e7eSjoerg   // encountering the 'prop' synthesize declaration and we will think that
65706f32e7eSjoerg   // we passed the region-of-interest.
65806f32e7eSjoerg   if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
65906f32e7eSjoerg     if (ivarD->getSynthesize())
66006f32e7eSjoerg       return None;
66106f32e7eSjoerg   }
66206f32e7eSjoerg 
66306f32e7eSjoerg   // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
66406f32e7eSjoerg   // declarations is a mismatch with the compiler semantics.
66506f32e7eSjoerg   if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
66606f32e7eSjoerg     auto *ID = cast<ObjCInterfaceDecl>(D);
66706f32e7eSjoerg     if (!ID->isThisDeclarationADefinition())
66806f32e7eSjoerg       Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
66906f32e7eSjoerg 
67006f32e7eSjoerg   } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
67106f32e7eSjoerg     auto *PD = cast<ObjCProtocolDecl>(D);
67206f32e7eSjoerg     if (!PD->isThisDeclarationADefinition())
67306f32e7eSjoerg       Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
67406f32e7eSjoerg   }
67506f32e7eSjoerg 
67606f32e7eSjoerg   const Optional<bool> V = shouldVisitCursor(Cursor);
67706f32e7eSjoerg   if (!V.hasValue())
67806f32e7eSjoerg     return None;
67906f32e7eSjoerg   if (!V.getValue())
68006f32e7eSjoerg     return false;
68106f32e7eSjoerg   if (Visit(Cursor, true))
68206f32e7eSjoerg     return true;
68306f32e7eSjoerg   return None;
68406f32e7eSjoerg }
68506f32e7eSjoerg 
VisitTranslationUnitDecl(TranslationUnitDecl * D)68606f32e7eSjoerg bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
68706f32e7eSjoerg   llvm_unreachable("Translation units are visited directly by Visit()");
68806f32e7eSjoerg }
68906f32e7eSjoerg 
VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl * D)69006f32e7eSjoerg bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
69106f32e7eSjoerg   if (VisitTemplateParameters(D->getTemplateParameters()))
69206f32e7eSjoerg     return true;
69306f32e7eSjoerg 
69406f32e7eSjoerg   return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
69506f32e7eSjoerg }
69606f32e7eSjoerg 
VisitTypeAliasDecl(TypeAliasDecl * D)69706f32e7eSjoerg bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
69806f32e7eSjoerg   if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
69906f32e7eSjoerg     return Visit(TSInfo->getTypeLoc());
70006f32e7eSjoerg 
70106f32e7eSjoerg   return false;
70206f32e7eSjoerg }
70306f32e7eSjoerg 
VisitTypedefDecl(TypedefDecl * D)70406f32e7eSjoerg bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
70506f32e7eSjoerg   if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
70606f32e7eSjoerg     return Visit(TSInfo->getTypeLoc());
70706f32e7eSjoerg 
70806f32e7eSjoerg   return false;
70906f32e7eSjoerg }
71006f32e7eSjoerg 
VisitTagDecl(TagDecl * D)711*13fbcb42Sjoerg bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }
71206f32e7eSjoerg 
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)71306f32e7eSjoerg bool CursorVisitor::VisitClassTemplateSpecializationDecl(
71406f32e7eSjoerg     ClassTemplateSpecializationDecl *D) {
71506f32e7eSjoerg   bool ShouldVisitBody = false;
71606f32e7eSjoerg   switch (D->getSpecializationKind()) {
71706f32e7eSjoerg   case TSK_Undeclared:
71806f32e7eSjoerg   case TSK_ImplicitInstantiation:
71906f32e7eSjoerg     // Nothing to visit
72006f32e7eSjoerg     return false;
72106f32e7eSjoerg 
72206f32e7eSjoerg   case TSK_ExplicitInstantiationDeclaration:
72306f32e7eSjoerg   case TSK_ExplicitInstantiationDefinition:
72406f32e7eSjoerg     break;
72506f32e7eSjoerg 
72606f32e7eSjoerg   case TSK_ExplicitSpecialization:
72706f32e7eSjoerg     ShouldVisitBody = true;
72806f32e7eSjoerg     break;
72906f32e7eSjoerg   }
73006f32e7eSjoerg 
73106f32e7eSjoerg   // Visit the template arguments used in the specialization.
73206f32e7eSjoerg   if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
73306f32e7eSjoerg     TypeLoc TL = SpecType->getTypeLoc();
73406f32e7eSjoerg     if (TemplateSpecializationTypeLoc TSTLoc =
73506f32e7eSjoerg             TL.getAs<TemplateSpecializationTypeLoc>()) {
73606f32e7eSjoerg       for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
73706f32e7eSjoerg         if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
73806f32e7eSjoerg           return true;
73906f32e7eSjoerg     }
74006f32e7eSjoerg   }
74106f32e7eSjoerg 
74206f32e7eSjoerg   return ShouldVisitBody && VisitCXXRecordDecl(D);
74306f32e7eSjoerg }
74406f32e7eSjoerg 
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)74506f32e7eSjoerg bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
74606f32e7eSjoerg     ClassTemplatePartialSpecializationDecl *D) {
74706f32e7eSjoerg   // FIXME: Visit the "outer" template parameter lists on the TagDecl
74806f32e7eSjoerg   // before visiting these template parameters.
74906f32e7eSjoerg   if (VisitTemplateParameters(D->getTemplateParameters()))
75006f32e7eSjoerg     return true;
75106f32e7eSjoerg 
75206f32e7eSjoerg   // Visit the partial specialization arguments.
75306f32e7eSjoerg   const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
75406f32e7eSjoerg   const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
75506f32e7eSjoerg   for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
75606f32e7eSjoerg     if (VisitTemplateArgumentLoc(TemplateArgs[I]))
75706f32e7eSjoerg       return true;
75806f32e7eSjoerg 
75906f32e7eSjoerg   return VisitCXXRecordDecl(D);
76006f32e7eSjoerg }
76106f32e7eSjoerg 
VisitTemplateTypeParmDecl(TemplateTypeParmDecl * D)76206f32e7eSjoerg bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
763*13fbcb42Sjoerg   if (const auto *TC = D->getTypeConstraint())
764*13fbcb42Sjoerg     if (Visit(MakeCXCursor(TC->getImmediatelyDeclaredConstraint(), StmtParent,
765*13fbcb42Sjoerg                            TU, RegionOfInterest)))
766*13fbcb42Sjoerg       return true;
767*13fbcb42Sjoerg 
76806f32e7eSjoerg   // Visit the default argument.
76906f32e7eSjoerg   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
77006f32e7eSjoerg     if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
77106f32e7eSjoerg       if (Visit(DefArg->getTypeLoc()))
77206f32e7eSjoerg         return true;
77306f32e7eSjoerg 
77406f32e7eSjoerg   return false;
77506f32e7eSjoerg }
77606f32e7eSjoerg 
VisitEnumConstantDecl(EnumConstantDecl * D)77706f32e7eSjoerg bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
77806f32e7eSjoerg   if (Expr *Init = D->getInitExpr())
77906f32e7eSjoerg     return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
78006f32e7eSjoerg   return false;
78106f32e7eSjoerg }
78206f32e7eSjoerg 
VisitDeclaratorDecl(DeclaratorDecl * DD)78306f32e7eSjoerg bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
78406f32e7eSjoerg   unsigned NumParamList = DD->getNumTemplateParameterLists();
78506f32e7eSjoerg   for (unsigned i = 0; i < NumParamList; i++) {
78606f32e7eSjoerg     TemplateParameterList *Params = DD->getTemplateParameterList(i);
78706f32e7eSjoerg     if (VisitTemplateParameters(Params))
78806f32e7eSjoerg       return true;
78906f32e7eSjoerg   }
79006f32e7eSjoerg 
79106f32e7eSjoerg   if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
79206f32e7eSjoerg     if (Visit(TSInfo->getTypeLoc()))
79306f32e7eSjoerg       return true;
79406f32e7eSjoerg 
79506f32e7eSjoerg   // Visit the nested-name-specifier, if present.
79606f32e7eSjoerg   if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
79706f32e7eSjoerg     if (VisitNestedNameSpecifierLoc(QualifierLoc))
79806f32e7eSjoerg       return true;
79906f32e7eSjoerg 
80006f32e7eSjoerg   return false;
80106f32e7eSjoerg }
80206f32e7eSjoerg 
HasTrailingReturnType(FunctionDecl * ND)80306f32e7eSjoerg static bool HasTrailingReturnType(FunctionDecl *ND) {
80406f32e7eSjoerg   const QualType Ty = ND->getType();
80506f32e7eSjoerg   if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
80606f32e7eSjoerg     if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
80706f32e7eSjoerg       return FT->hasTrailingReturn();
80806f32e7eSjoerg   }
80906f32e7eSjoerg 
81006f32e7eSjoerg   return false;
81106f32e7eSjoerg }
81206f32e7eSjoerg 
81306f32e7eSjoerg /// Compare two base or member initializers based on their source order.
CompareCXXCtorInitializers(CXXCtorInitializer * const * X,CXXCtorInitializer * const * Y)81406f32e7eSjoerg static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
81506f32e7eSjoerg                                       CXXCtorInitializer *const *Y) {
81606f32e7eSjoerg   return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
81706f32e7eSjoerg }
81806f32e7eSjoerg 
VisitFunctionDecl(FunctionDecl * ND)81906f32e7eSjoerg bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
82006f32e7eSjoerg   unsigned NumParamList = ND->getNumTemplateParameterLists();
82106f32e7eSjoerg   for (unsigned i = 0; i < NumParamList; i++) {
82206f32e7eSjoerg     TemplateParameterList *Params = ND->getTemplateParameterList(i);
82306f32e7eSjoerg     if (VisitTemplateParameters(Params))
82406f32e7eSjoerg       return true;
82506f32e7eSjoerg   }
82606f32e7eSjoerg 
82706f32e7eSjoerg   if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
82806f32e7eSjoerg     // Visit the function declaration's syntactic components in the order
82906f32e7eSjoerg     // written. This requires a bit of work.
83006f32e7eSjoerg     TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
83106f32e7eSjoerg     FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
83206f32e7eSjoerg     const bool HasTrailingRT = HasTrailingReturnType(ND);
83306f32e7eSjoerg 
83406f32e7eSjoerg     // If we have a function declared directly (without the use of a typedef),
83506f32e7eSjoerg     // visit just the return type. Otherwise, just visit the function's type
83606f32e7eSjoerg     // now.
83706f32e7eSjoerg     if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
83806f32e7eSjoerg          Visit(FTL.getReturnLoc())) ||
83906f32e7eSjoerg         (!FTL && Visit(TL)))
84006f32e7eSjoerg       return true;
84106f32e7eSjoerg 
84206f32e7eSjoerg     // Visit the nested-name-specifier, if present.
84306f32e7eSjoerg     if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
84406f32e7eSjoerg       if (VisitNestedNameSpecifierLoc(QualifierLoc))
84506f32e7eSjoerg         return true;
84606f32e7eSjoerg 
84706f32e7eSjoerg     // Visit the declaration name.
84806f32e7eSjoerg     if (!isa<CXXDestructorDecl>(ND))
84906f32e7eSjoerg       if (VisitDeclarationNameInfo(ND->getNameInfo()))
85006f32e7eSjoerg         return true;
85106f32e7eSjoerg 
85206f32e7eSjoerg     // FIXME: Visit explicitly-specified template arguments!
85306f32e7eSjoerg 
85406f32e7eSjoerg     // Visit the function parameters, if we have a function type.
85506f32e7eSjoerg     if (FTL && VisitFunctionTypeLoc(FTL, true))
85606f32e7eSjoerg       return true;
85706f32e7eSjoerg 
85806f32e7eSjoerg     // Visit the function's trailing return type.
85906f32e7eSjoerg     if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
86006f32e7eSjoerg       return true;
86106f32e7eSjoerg 
86206f32e7eSjoerg     // FIXME: Attributes?
86306f32e7eSjoerg   }
86406f32e7eSjoerg 
86506f32e7eSjoerg   if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
86606f32e7eSjoerg     if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
86706f32e7eSjoerg       // Find the initializers that were written in the source.
86806f32e7eSjoerg       SmallVector<CXXCtorInitializer *, 4> WrittenInits;
86906f32e7eSjoerg       for (auto *I : Constructor->inits()) {
87006f32e7eSjoerg         if (!I->isWritten())
87106f32e7eSjoerg           continue;
87206f32e7eSjoerg 
87306f32e7eSjoerg         WrittenInits.push_back(I);
87406f32e7eSjoerg       }
87506f32e7eSjoerg 
87606f32e7eSjoerg       // Sort the initializers in source order
87706f32e7eSjoerg       llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
87806f32e7eSjoerg                            &CompareCXXCtorInitializers);
87906f32e7eSjoerg 
88006f32e7eSjoerg       // Visit the initializers in source order
88106f32e7eSjoerg       for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
88206f32e7eSjoerg         CXXCtorInitializer *Init = WrittenInits[I];
88306f32e7eSjoerg         if (Init->isAnyMemberInitializer()) {
88406f32e7eSjoerg           if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
88506f32e7eSjoerg                                         Init->getMemberLocation(), TU)))
88606f32e7eSjoerg             return true;
88706f32e7eSjoerg         } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
88806f32e7eSjoerg           if (Visit(TInfo->getTypeLoc()))
88906f32e7eSjoerg             return true;
89006f32e7eSjoerg         }
89106f32e7eSjoerg 
89206f32e7eSjoerg         // Visit the initializer value.
89306f32e7eSjoerg         if (Expr *Initializer = Init->getInit())
89406f32e7eSjoerg           if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
89506f32e7eSjoerg             return true;
89606f32e7eSjoerg       }
89706f32e7eSjoerg     }
89806f32e7eSjoerg 
89906f32e7eSjoerg     if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
90006f32e7eSjoerg       return true;
90106f32e7eSjoerg   }
90206f32e7eSjoerg 
90306f32e7eSjoerg   return false;
90406f32e7eSjoerg }
90506f32e7eSjoerg 
VisitFieldDecl(FieldDecl * D)90606f32e7eSjoerg bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
90706f32e7eSjoerg   if (VisitDeclaratorDecl(D))
90806f32e7eSjoerg     return true;
90906f32e7eSjoerg 
91006f32e7eSjoerg   if (Expr *BitWidth = D->getBitWidth())
91106f32e7eSjoerg     return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
91206f32e7eSjoerg 
91306f32e7eSjoerg   if (Expr *Init = D->getInClassInitializer())
91406f32e7eSjoerg     return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
91506f32e7eSjoerg 
91606f32e7eSjoerg   return false;
91706f32e7eSjoerg }
91806f32e7eSjoerg 
VisitVarDecl(VarDecl * D)91906f32e7eSjoerg bool CursorVisitor::VisitVarDecl(VarDecl *D) {
92006f32e7eSjoerg   if (VisitDeclaratorDecl(D))
92106f32e7eSjoerg     return true;
92206f32e7eSjoerg 
92306f32e7eSjoerg   if (Expr *Init = D->getInit())
92406f32e7eSjoerg     return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
92506f32e7eSjoerg 
92606f32e7eSjoerg   return false;
92706f32e7eSjoerg }
92806f32e7eSjoerg 
VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl * D)92906f32e7eSjoerg bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
93006f32e7eSjoerg   if (VisitDeclaratorDecl(D))
93106f32e7eSjoerg     return true;
93206f32e7eSjoerg 
93306f32e7eSjoerg   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
93406f32e7eSjoerg     if (Expr *DefArg = D->getDefaultArgument())
93506f32e7eSjoerg       return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
93606f32e7eSjoerg 
93706f32e7eSjoerg   return false;
93806f32e7eSjoerg }
93906f32e7eSjoerg 
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)94006f32e7eSjoerg bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
94106f32e7eSjoerg   // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
94206f32e7eSjoerg   // before visiting these template parameters.
94306f32e7eSjoerg   if (VisitTemplateParameters(D->getTemplateParameters()))
94406f32e7eSjoerg     return true;
94506f32e7eSjoerg 
94606f32e7eSjoerg   auto *FD = D->getTemplatedDecl();
94706f32e7eSjoerg   return VisitAttributes(FD) || VisitFunctionDecl(FD);
94806f32e7eSjoerg }
94906f32e7eSjoerg 
VisitClassTemplateDecl(ClassTemplateDecl * D)95006f32e7eSjoerg bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
95106f32e7eSjoerg   // FIXME: Visit the "outer" template parameter lists on the TagDecl
95206f32e7eSjoerg   // before visiting these template parameters.
95306f32e7eSjoerg   if (VisitTemplateParameters(D->getTemplateParameters()))
95406f32e7eSjoerg     return true;
95506f32e7eSjoerg 
95606f32e7eSjoerg   auto *CD = D->getTemplatedDecl();
95706f32e7eSjoerg   return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
95806f32e7eSjoerg }
95906f32e7eSjoerg 
VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl * D)96006f32e7eSjoerg bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
96106f32e7eSjoerg   if (VisitTemplateParameters(D->getTemplateParameters()))
96206f32e7eSjoerg     return true;
96306f32e7eSjoerg 
96406f32e7eSjoerg   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
96506f32e7eSjoerg       VisitTemplateArgumentLoc(D->getDefaultArgument()))
96606f32e7eSjoerg     return true;
96706f32e7eSjoerg 
96806f32e7eSjoerg   return false;
96906f32e7eSjoerg }
97006f32e7eSjoerg 
VisitObjCTypeParamDecl(ObjCTypeParamDecl * D)97106f32e7eSjoerg bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
97206f32e7eSjoerg   // Visit the bound, if it's explicit.
97306f32e7eSjoerg   if (D->hasExplicitBound()) {
97406f32e7eSjoerg     if (auto TInfo = D->getTypeSourceInfo()) {
97506f32e7eSjoerg       if (Visit(TInfo->getTypeLoc()))
97606f32e7eSjoerg         return true;
97706f32e7eSjoerg     }
97806f32e7eSjoerg   }
97906f32e7eSjoerg 
98006f32e7eSjoerg   return false;
98106f32e7eSjoerg }
98206f32e7eSjoerg 
VisitObjCMethodDecl(ObjCMethodDecl * ND)98306f32e7eSjoerg bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
98406f32e7eSjoerg   if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
98506f32e7eSjoerg     if (Visit(TSInfo->getTypeLoc()))
98606f32e7eSjoerg       return true;
98706f32e7eSjoerg 
98806f32e7eSjoerg   for (const auto *P : ND->parameters()) {
98906f32e7eSjoerg     if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
99006f32e7eSjoerg       return true;
99106f32e7eSjoerg   }
99206f32e7eSjoerg 
99306f32e7eSjoerg   return ND->isThisDeclarationADefinition() &&
99406f32e7eSjoerg          Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
99506f32e7eSjoerg }
99606f32e7eSjoerg 
99706f32e7eSjoerg template <typename DeclIt>
addRangedDeclsInContainer(DeclIt * DI_current,DeclIt DE_current,SourceManager & SM,SourceLocation EndLoc,SmallVectorImpl<Decl * > & Decls)99806f32e7eSjoerg static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
99906f32e7eSjoerg                                       SourceManager &SM, SourceLocation EndLoc,
100006f32e7eSjoerg                                       SmallVectorImpl<Decl *> &Decls) {
100106f32e7eSjoerg   DeclIt next = *DI_current;
100206f32e7eSjoerg   while (++next != DE_current) {
100306f32e7eSjoerg     Decl *D_next = *next;
100406f32e7eSjoerg     if (!D_next)
100506f32e7eSjoerg       break;
100606f32e7eSjoerg     SourceLocation L = D_next->getBeginLoc();
100706f32e7eSjoerg     if (!L.isValid())
100806f32e7eSjoerg       break;
100906f32e7eSjoerg     if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
101006f32e7eSjoerg       *DI_current = next;
101106f32e7eSjoerg       Decls.push_back(D_next);
101206f32e7eSjoerg       continue;
101306f32e7eSjoerg     }
101406f32e7eSjoerg     break;
101506f32e7eSjoerg   }
101606f32e7eSjoerg }
101706f32e7eSjoerg 
VisitObjCContainerDecl(ObjCContainerDecl * D)101806f32e7eSjoerg bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
101906f32e7eSjoerg   // FIXME: Eventually convert back to just 'VisitDeclContext()'.  Essentially
102006f32e7eSjoerg   // an @implementation can lexically contain Decls that are not properly
102106f32e7eSjoerg   // nested in the AST.  When we identify such cases, we need to retrofit
102206f32e7eSjoerg   // this nesting here.
102306f32e7eSjoerg   if (!DI_current && !FileDI_current)
102406f32e7eSjoerg     return VisitDeclContext(D);
102506f32e7eSjoerg 
102606f32e7eSjoerg   // Scan the Decls that immediately come after the container
102706f32e7eSjoerg   // in the current DeclContext.  If any fall within the
102806f32e7eSjoerg   // container's lexical region, stash them into a vector
102906f32e7eSjoerg   // for later processing.
103006f32e7eSjoerg   SmallVector<Decl *, 24> DeclsInContainer;
103106f32e7eSjoerg   SourceLocation EndLoc = D->getSourceRange().getEnd();
103206f32e7eSjoerg   SourceManager &SM = AU->getSourceManager();
103306f32e7eSjoerg   if (EndLoc.isValid()) {
103406f32e7eSjoerg     if (DI_current) {
103506f32e7eSjoerg       addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
103606f32e7eSjoerg                                 DeclsInContainer);
103706f32e7eSjoerg     } else {
103806f32e7eSjoerg       addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
103906f32e7eSjoerg                                 DeclsInContainer);
104006f32e7eSjoerg     }
104106f32e7eSjoerg   }
104206f32e7eSjoerg 
104306f32e7eSjoerg   // The common case.
104406f32e7eSjoerg   if (DeclsInContainer.empty())
104506f32e7eSjoerg     return VisitDeclContext(D);
104606f32e7eSjoerg 
104706f32e7eSjoerg   // Get all the Decls in the DeclContext, and sort them with the
104806f32e7eSjoerg   // additional ones we've collected.  Then visit them.
104906f32e7eSjoerg   for (auto *SubDecl : D->decls()) {
105006f32e7eSjoerg     if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
105106f32e7eSjoerg         SubDecl->getBeginLoc().isInvalid())
105206f32e7eSjoerg       continue;
105306f32e7eSjoerg     DeclsInContainer.push_back(SubDecl);
105406f32e7eSjoerg   }
105506f32e7eSjoerg 
105606f32e7eSjoerg   // Now sort the Decls so that they appear in lexical order.
1057*13fbcb42Sjoerg   llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {
105806f32e7eSjoerg     SourceLocation L_A = A->getBeginLoc();
105906f32e7eSjoerg     SourceLocation L_B = B->getBeginLoc();
1060*13fbcb42Sjoerg     return L_A != L_B
1061*13fbcb42Sjoerg                ? SM.isBeforeInTranslationUnit(L_A, L_B)
1062*13fbcb42Sjoerg                : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());
106306f32e7eSjoerg   });
106406f32e7eSjoerg 
106506f32e7eSjoerg   // Now visit the decls.
106606f32e7eSjoerg   for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),
1067*13fbcb42Sjoerg                                          E = DeclsInContainer.end();
1068*13fbcb42Sjoerg        I != E; ++I) {
106906f32e7eSjoerg     CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
107006f32e7eSjoerg     const Optional<bool> &V = shouldVisitCursor(Cursor);
107106f32e7eSjoerg     if (!V.hasValue())
107206f32e7eSjoerg       continue;
107306f32e7eSjoerg     if (!V.getValue())
107406f32e7eSjoerg       return false;
107506f32e7eSjoerg     if (Visit(Cursor, true))
107606f32e7eSjoerg       return true;
107706f32e7eSjoerg   }
107806f32e7eSjoerg   return false;
107906f32e7eSjoerg }
108006f32e7eSjoerg 
VisitObjCCategoryDecl(ObjCCategoryDecl * ND)108106f32e7eSjoerg bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
108206f32e7eSjoerg   if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
108306f32e7eSjoerg                                    TU)))
108406f32e7eSjoerg     return true;
108506f32e7eSjoerg 
108606f32e7eSjoerg   if (VisitObjCTypeParamList(ND->getTypeParamList()))
108706f32e7eSjoerg     return true;
108806f32e7eSjoerg 
108906f32e7eSjoerg   ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
109006f32e7eSjoerg   for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1091*13fbcb42Sjoerg                                            E = ND->protocol_end();
1092*13fbcb42Sjoerg        I != E; ++I, ++PL)
109306f32e7eSjoerg     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
109406f32e7eSjoerg       return true;
109506f32e7eSjoerg 
109606f32e7eSjoerg   return VisitObjCContainerDecl(ND);
109706f32e7eSjoerg }
109806f32e7eSjoerg 
VisitObjCProtocolDecl(ObjCProtocolDecl * PID)109906f32e7eSjoerg bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
110006f32e7eSjoerg   if (!PID->isThisDeclarationADefinition())
110106f32e7eSjoerg     return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
110206f32e7eSjoerg 
110306f32e7eSjoerg   ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
110406f32e7eSjoerg   for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1105*13fbcb42Sjoerg                                            E = PID->protocol_end();
1106*13fbcb42Sjoerg        I != E; ++I, ++PL)
110706f32e7eSjoerg     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
110806f32e7eSjoerg       return true;
110906f32e7eSjoerg 
111006f32e7eSjoerg   return VisitObjCContainerDecl(PID);
111106f32e7eSjoerg }
111206f32e7eSjoerg 
VisitObjCPropertyDecl(ObjCPropertyDecl * PD)111306f32e7eSjoerg bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
111406f32e7eSjoerg   if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
111506f32e7eSjoerg     return true;
111606f32e7eSjoerg 
111706f32e7eSjoerg   // FIXME: This implements a workaround with @property declarations also being
111806f32e7eSjoerg   // installed in the DeclContext for the @interface.  Eventually this code
111906f32e7eSjoerg   // should be removed.
112006f32e7eSjoerg   ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
112106f32e7eSjoerg   if (!CDecl || !CDecl->IsClassExtension())
112206f32e7eSjoerg     return false;
112306f32e7eSjoerg 
112406f32e7eSjoerg   ObjCInterfaceDecl *ID = CDecl->getClassInterface();
112506f32e7eSjoerg   if (!ID)
112606f32e7eSjoerg     return false;
112706f32e7eSjoerg 
112806f32e7eSjoerg   IdentifierInfo *PropertyId = PD->getIdentifier();
1129*13fbcb42Sjoerg   ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
1130*13fbcb42Sjoerg       cast<DeclContext>(ID), PropertyId, PD->getQueryKind());
113106f32e7eSjoerg 
113206f32e7eSjoerg   if (!prevDecl)
113306f32e7eSjoerg     return false;
113406f32e7eSjoerg 
113506f32e7eSjoerg   // Visit synthesized methods since they will be skipped when visiting
113606f32e7eSjoerg   // the @interface.
113706f32e7eSjoerg   if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
113806f32e7eSjoerg     if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
113906f32e7eSjoerg       if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
114006f32e7eSjoerg         return true;
114106f32e7eSjoerg 
114206f32e7eSjoerg   if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
114306f32e7eSjoerg     if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
114406f32e7eSjoerg       if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
114506f32e7eSjoerg         return true;
114606f32e7eSjoerg 
114706f32e7eSjoerg   return false;
114806f32e7eSjoerg }
114906f32e7eSjoerg 
VisitObjCTypeParamList(ObjCTypeParamList * typeParamList)115006f32e7eSjoerg bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
115106f32e7eSjoerg   if (!typeParamList)
115206f32e7eSjoerg     return false;
115306f32e7eSjoerg 
115406f32e7eSjoerg   for (auto *typeParam : *typeParamList) {
115506f32e7eSjoerg     // Visit the type parameter.
115606f32e7eSjoerg     if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
115706f32e7eSjoerg       return true;
115806f32e7eSjoerg   }
115906f32e7eSjoerg 
116006f32e7eSjoerg   return false;
116106f32e7eSjoerg }
116206f32e7eSjoerg 
VisitObjCInterfaceDecl(ObjCInterfaceDecl * D)116306f32e7eSjoerg bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
116406f32e7eSjoerg   if (!D->isThisDeclarationADefinition()) {
116506f32e7eSjoerg     // Forward declaration is treated like a reference.
116606f32e7eSjoerg     return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
116706f32e7eSjoerg   }
116806f32e7eSjoerg 
116906f32e7eSjoerg   // Objective-C type parameters.
117006f32e7eSjoerg   if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
117106f32e7eSjoerg     return true;
117206f32e7eSjoerg 
117306f32e7eSjoerg   // Issue callbacks for super class.
1174*13fbcb42Sjoerg   if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
1175*13fbcb42Sjoerg                                 D->getSuperClass(), D->getSuperClassLoc(), TU)))
117606f32e7eSjoerg     return true;
117706f32e7eSjoerg 
117806f32e7eSjoerg   if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
117906f32e7eSjoerg     if (Visit(SuperClassTInfo->getTypeLoc()))
118006f32e7eSjoerg       return true;
118106f32e7eSjoerg 
118206f32e7eSjoerg   ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
118306f32e7eSjoerg   for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1184*13fbcb42Sjoerg                                             E = D->protocol_end();
1185*13fbcb42Sjoerg        I != E; ++I, ++PL)
118606f32e7eSjoerg     if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
118706f32e7eSjoerg       return true;
118806f32e7eSjoerg 
118906f32e7eSjoerg   return VisitObjCContainerDecl(D);
119006f32e7eSjoerg }
119106f32e7eSjoerg 
VisitObjCImplDecl(ObjCImplDecl * D)119206f32e7eSjoerg bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
119306f32e7eSjoerg   return VisitObjCContainerDecl(D);
119406f32e7eSjoerg }
119506f32e7eSjoerg 
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * D)119606f32e7eSjoerg bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
119706f32e7eSjoerg   // 'ID' could be null when dealing with invalid code.
119806f32e7eSjoerg   if (ObjCInterfaceDecl *ID = D->getClassInterface())
119906f32e7eSjoerg     if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
120006f32e7eSjoerg       return true;
120106f32e7eSjoerg 
120206f32e7eSjoerg   return VisitObjCImplDecl(D);
120306f32e7eSjoerg }
120406f32e7eSjoerg 
VisitObjCImplementationDecl(ObjCImplementationDecl * D)120506f32e7eSjoerg bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
120606f32e7eSjoerg #if 0
120706f32e7eSjoerg   // Issue callbacks for super class.
120806f32e7eSjoerg   // FIXME: No source location information!
120906f32e7eSjoerg   if (D->getSuperClass() &&
121006f32e7eSjoerg       Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
121106f32e7eSjoerg                                         D->getSuperClassLoc(),
121206f32e7eSjoerg                                         TU)))
121306f32e7eSjoerg     return true;
121406f32e7eSjoerg #endif
121506f32e7eSjoerg 
121606f32e7eSjoerg   return VisitObjCImplDecl(D);
121706f32e7eSjoerg }
121806f32e7eSjoerg 
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * PD)121906f32e7eSjoerg bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
122006f32e7eSjoerg   if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
122106f32e7eSjoerg     if (PD->isIvarNameSpecified())
122206f32e7eSjoerg       return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
122306f32e7eSjoerg 
122406f32e7eSjoerg   return false;
122506f32e7eSjoerg }
122606f32e7eSjoerg 
VisitNamespaceDecl(NamespaceDecl * D)122706f32e7eSjoerg bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
122806f32e7eSjoerg   return VisitDeclContext(D);
122906f32e7eSjoerg }
123006f32e7eSjoerg 
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)123106f32e7eSjoerg bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
123206f32e7eSjoerg   // Visit nested-name-specifier.
123306f32e7eSjoerg   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
123406f32e7eSjoerg     if (VisitNestedNameSpecifierLoc(QualifierLoc))
123506f32e7eSjoerg       return true;
123606f32e7eSjoerg 
123706f32e7eSjoerg   return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
123806f32e7eSjoerg                                       D->getTargetNameLoc(), TU));
123906f32e7eSjoerg }
124006f32e7eSjoerg 
VisitUsingDecl(UsingDecl * D)124106f32e7eSjoerg bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
124206f32e7eSjoerg   // Visit nested-name-specifier.
124306f32e7eSjoerg   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
124406f32e7eSjoerg     if (VisitNestedNameSpecifierLoc(QualifierLoc))
124506f32e7eSjoerg       return true;
124606f32e7eSjoerg   }
124706f32e7eSjoerg 
124806f32e7eSjoerg   if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
124906f32e7eSjoerg     return true;
125006f32e7eSjoerg 
125106f32e7eSjoerg   return VisitDeclarationNameInfo(D->getNameInfo());
125206f32e7eSjoerg }
125306f32e7eSjoerg 
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)125406f32e7eSjoerg bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
125506f32e7eSjoerg   // Visit nested-name-specifier.
125606f32e7eSjoerg   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
125706f32e7eSjoerg     if (VisitNestedNameSpecifierLoc(QualifierLoc))
125806f32e7eSjoerg       return true;
125906f32e7eSjoerg 
126006f32e7eSjoerg   return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
126106f32e7eSjoerg                                       D->getIdentLocation(), TU));
126206f32e7eSjoerg }
126306f32e7eSjoerg 
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)126406f32e7eSjoerg bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
126506f32e7eSjoerg   // Visit nested-name-specifier.
126606f32e7eSjoerg   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
126706f32e7eSjoerg     if (VisitNestedNameSpecifierLoc(QualifierLoc))
126806f32e7eSjoerg       return true;
126906f32e7eSjoerg   }
127006f32e7eSjoerg 
127106f32e7eSjoerg   return VisitDeclarationNameInfo(D->getNameInfo());
127206f32e7eSjoerg }
127306f32e7eSjoerg 
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)127406f32e7eSjoerg bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
127506f32e7eSjoerg     UnresolvedUsingTypenameDecl *D) {
127606f32e7eSjoerg   // Visit nested-name-specifier.
127706f32e7eSjoerg   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
127806f32e7eSjoerg     if (VisitNestedNameSpecifierLoc(QualifierLoc))
127906f32e7eSjoerg       return true;
128006f32e7eSjoerg 
128106f32e7eSjoerg   return false;
128206f32e7eSjoerg }
128306f32e7eSjoerg 
VisitStaticAssertDecl(StaticAssertDecl * D)128406f32e7eSjoerg bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
128506f32e7eSjoerg   if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
128606f32e7eSjoerg     return true;
128706f32e7eSjoerg   if (StringLiteral *Message = D->getMessage())
128806f32e7eSjoerg     if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
128906f32e7eSjoerg       return true;
129006f32e7eSjoerg   return false;
129106f32e7eSjoerg }
129206f32e7eSjoerg 
VisitFriendDecl(FriendDecl * D)129306f32e7eSjoerg bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {
129406f32e7eSjoerg   if (NamedDecl *FriendD = D->getFriendDecl()) {
129506f32e7eSjoerg     if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))
129606f32e7eSjoerg       return true;
129706f32e7eSjoerg   } else if (TypeSourceInfo *TI = D->getFriendType()) {
129806f32e7eSjoerg     if (Visit(TI->getTypeLoc()))
129906f32e7eSjoerg       return true;
130006f32e7eSjoerg   }
130106f32e7eSjoerg   return false;
130206f32e7eSjoerg }
130306f32e7eSjoerg 
VisitDecompositionDecl(DecompositionDecl * D)1304*13fbcb42Sjoerg bool CursorVisitor::VisitDecompositionDecl(DecompositionDecl *D) {
1305*13fbcb42Sjoerg   for (auto *B : D->bindings()) {
1306*13fbcb42Sjoerg     if (Visit(MakeCXCursor(B, TU, RegionOfInterest)))
1307*13fbcb42Sjoerg       return true;
1308*13fbcb42Sjoerg   }
1309*13fbcb42Sjoerg   return VisitVarDecl(D);
1310*13fbcb42Sjoerg }
1311*13fbcb42Sjoerg 
VisitDeclarationNameInfo(DeclarationNameInfo Name)131206f32e7eSjoerg bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
131306f32e7eSjoerg   switch (Name.getName().getNameKind()) {
131406f32e7eSjoerg   case clang::DeclarationName::Identifier:
131506f32e7eSjoerg   case clang::DeclarationName::CXXLiteralOperatorName:
131606f32e7eSjoerg   case clang::DeclarationName::CXXDeductionGuideName:
131706f32e7eSjoerg   case clang::DeclarationName::CXXOperatorName:
131806f32e7eSjoerg   case clang::DeclarationName::CXXUsingDirective:
131906f32e7eSjoerg     return false;
132006f32e7eSjoerg 
132106f32e7eSjoerg   case clang::DeclarationName::CXXConstructorName:
132206f32e7eSjoerg   case clang::DeclarationName::CXXDestructorName:
132306f32e7eSjoerg   case clang::DeclarationName::CXXConversionFunctionName:
132406f32e7eSjoerg     if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
132506f32e7eSjoerg       return Visit(TSInfo->getTypeLoc());
132606f32e7eSjoerg     return false;
132706f32e7eSjoerg 
132806f32e7eSjoerg   case clang::DeclarationName::ObjCZeroArgSelector:
132906f32e7eSjoerg   case clang::DeclarationName::ObjCOneArgSelector:
133006f32e7eSjoerg   case clang::DeclarationName::ObjCMultiArgSelector:
133106f32e7eSjoerg     // FIXME: Per-identifier location info?
133206f32e7eSjoerg     return false;
133306f32e7eSjoerg   }
133406f32e7eSjoerg 
133506f32e7eSjoerg   llvm_unreachable("Invalid DeclarationName::Kind!");
133606f32e7eSjoerg }
133706f32e7eSjoerg 
VisitNestedNameSpecifier(NestedNameSpecifier * NNS,SourceRange Range)133806f32e7eSjoerg bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
133906f32e7eSjoerg                                              SourceRange Range) {
134006f32e7eSjoerg   // FIXME: This whole routine is a hack to work around the lack of proper
134106f32e7eSjoerg   // source information in nested-name-specifiers (PR5791). Since we do have
134206f32e7eSjoerg   // a beginning source location, we can visit the first component of the
134306f32e7eSjoerg   // nested-name-specifier, if it's a single-token component.
134406f32e7eSjoerg   if (!NNS)
134506f32e7eSjoerg     return false;
134606f32e7eSjoerg 
134706f32e7eSjoerg   // Get the first component in the nested-name-specifier.
134806f32e7eSjoerg   while (NestedNameSpecifier *Prefix = NNS->getPrefix())
134906f32e7eSjoerg     NNS = Prefix;
135006f32e7eSjoerg 
135106f32e7eSjoerg   switch (NNS->getKind()) {
135206f32e7eSjoerg   case NestedNameSpecifier::Namespace:
1353*13fbcb42Sjoerg     return Visit(
1354*13fbcb42Sjoerg         MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
135506f32e7eSjoerg 
135606f32e7eSjoerg   case NestedNameSpecifier::NamespaceAlias:
135706f32e7eSjoerg     return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
135806f32e7eSjoerg                                         Range.getBegin(), TU));
135906f32e7eSjoerg 
136006f32e7eSjoerg   case NestedNameSpecifier::TypeSpec: {
136106f32e7eSjoerg     // If the type has a form where we know that the beginning of the source
136206f32e7eSjoerg     // range matches up with a reference cursor. Visit the appropriate reference
136306f32e7eSjoerg     // cursor.
136406f32e7eSjoerg     const Type *T = NNS->getAsType();
136506f32e7eSjoerg     if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
136606f32e7eSjoerg       return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
136706f32e7eSjoerg     if (const TagType *Tag = dyn_cast<TagType>(T))
136806f32e7eSjoerg       return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1369*13fbcb42Sjoerg     if (const TemplateSpecializationType *TST =
1370*13fbcb42Sjoerg             dyn_cast<TemplateSpecializationType>(T))
137106f32e7eSjoerg       return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
137206f32e7eSjoerg     break;
137306f32e7eSjoerg   }
137406f32e7eSjoerg 
137506f32e7eSjoerg   case NestedNameSpecifier::TypeSpecWithTemplate:
137606f32e7eSjoerg   case NestedNameSpecifier::Global:
137706f32e7eSjoerg   case NestedNameSpecifier::Identifier:
137806f32e7eSjoerg   case NestedNameSpecifier::Super:
137906f32e7eSjoerg     break;
138006f32e7eSjoerg   }
138106f32e7eSjoerg 
138206f32e7eSjoerg   return false;
138306f32e7eSjoerg }
138406f32e7eSjoerg 
VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)1385*13fbcb42Sjoerg bool CursorVisitor::VisitNestedNameSpecifierLoc(
1386*13fbcb42Sjoerg     NestedNameSpecifierLoc Qualifier) {
138706f32e7eSjoerg   SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
138806f32e7eSjoerg   for (; Qualifier; Qualifier = Qualifier.getPrefix())
138906f32e7eSjoerg     Qualifiers.push_back(Qualifier);
139006f32e7eSjoerg 
139106f32e7eSjoerg   while (!Qualifiers.empty()) {
139206f32e7eSjoerg     NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
139306f32e7eSjoerg     NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
139406f32e7eSjoerg     switch (NNS->getKind()) {
139506f32e7eSjoerg     case NestedNameSpecifier::Namespace:
139606f32e7eSjoerg       if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1397*13fbcb42Sjoerg                                        Q.getLocalBeginLoc(), TU)))
139806f32e7eSjoerg         return true;
139906f32e7eSjoerg 
140006f32e7eSjoerg       break;
140106f32e7eSjoerg 
140206f32e7eSjoerg     case NestedNameSpecifier::NamespaceAlias:
140306f32e7eSjoerg       if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1404*13fbcb42Sjoerg                                        Q.getLocalBeginLoc(), TU)))
140506f32e7eSjoerg         return true;
140606f32e7eSjoerg 
140706f32e7eSjoerg       break;
140806f32e7eSjoerg 
140906f32e7eSjoerg     case NestedNameSpecifier::TypeSpec:
141006f32e7eSjoerg     case NestedNameSpecifier::TypeSpecWithTemplate:
141106f32e7eSjoerg       if (Visit(Q.getTypeLoc()))
141206f32e7eSjoerg         return true;
141306f32e7eSjoerg 
141406f32e7eSjoerg       break;
141506f32e7eSjoerg 
141606f32e7eSjoerg     case NestedNameSpecifier::Global:
141706f32e7eSjoerg     case NestedNameSpecifier::Identifier:
141806f32e7eSjoerg     case NestedNameSpecifier::Super:
141906f32e7eSjoerg       break;
142006f32e7eSjoerg     }
142106f32e7eSjoerg   }
142206f32e7eSjoerg 
142306f32e7eSjoerg   return false;
142406f32e7eSjoerg }
142506f32e7eSjoerg 
VisitTemplateParameters(const TemplateParameterList * Params)142606f32e7eSjoerg bool CursorVisitor::VisitTemplateParameters(
142706f32e7eSjoerg     const TemplateParameterList *Params) {
142806f32e7eSjoerg   if (!Params)
142906f32e7eSjoerg     return false;
143006f32e7eSjoerg 
143106f32e7eSjoerg   for (TemplateParameterList::const_iterator P = Params->begin(),
143206f32e7eSjoerg                                              PEnd = Params->end();
143306f32e7eSjoerg        P != PEnd; ++P) {
143406f32e7eSjoerg     if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
143506f32e7eSjoerg       return true;
143606f32e7eSjoerg   }
143706f32e7eSjoerg 
143806f32e7eSjoerg   return false;
143906f32e7eSjoerg }
144006f32e7eSjoerg 
VisitTemplateName(TemplateName Name,SourceLocation Loc)144106f32e7eSjoerg bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
144206f32e7eSjoerg   switch (Name.getKind()) {
144306f32e7eSjoerg   case TemplateName::Template:
144406f32e7eSjoerg     return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
144506f32e7eSjoerg 
144606f32e7eSjoerg   case TemplateName::OverloadedTemplate:
144706f32e7eSjoerg     // Visit the overloaded template set.
144806f32e7eSjoerg     if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
144906f32e7eSjoerg       return true;
145006f32e7eSjoerg 
145106f32e7eSjoerg     return false;
145206f32e7eSjoerg 
145306f32e7eSjoerg   case TemplateName::AssumedTemplate:
145406f32e7eSjoerg     // FIXME: Visit DeclarationName?
145506f32e7eSjoerg     return false;
145606f32e7eSjoerg 
145706f32e7eSjoerg   case TemplateName::DependentTemplate:
145806f32e7eSjoerg     // FIXME: Visit nested-name-specifier.
145906f32e7eSjoerg     return false;
146006f32e7eSjoerg 
146106f32e7eSjoerg   case TemplateName::QualifiedTemplate:
146206f32e7eSjoerg     // FIXME: Visit nested-name-specifier.
146306f32e7eSjoerg     return Visit(MakeCursorTemplateRef(
1464*13fbcb42Sjoerg         Name.getAsQualifiedTemplateName()->getDecl(), Loc, TU));
146506f32e7eSjoerg 
146606f32e7eSjoerg   case TemplateName::SubstTemplateTemplateParm:
146706f32e7eSjoerg     return Visit(MakeCursorTemplateRef(
1468*13fbcb42Sjoerg         Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));
146906f32e7eSjoerg 
147006f32e7eSjoerg   case TemplateName::SubstTemplateTemplateParmPack:
147106f32e7eSjoerg     return Visit(MakeCursorTemplateRef(
1472*13fbcb42Sjoerg         Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
1473*13fbcb42Sjoerg         TU));
147406f32e7eSjoerg   }
147506f32e7eSjoerg 
147606f32e7eSjoerg   llvm_unreachable("Invalid TemplateName::Kind!");
147706f32e7eSjoerg }
147806f32e7eSjoerg 
VisitTemplateArgumentLoc(const TemplateArgumentLoc & TAL)147906f32e7eSjoerg bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
148006f32e7eSjoerg   switch (TAL.getArgument().getKind()) {
148106f32e7eSjoerg   case TemplateArgument::Null:
148206f32e7eSjoerg   case TemplateArgument::Integral:
148306f32e7eSjoerg   case TemplateArgument::Pack:
148406f32e7eSjoerg     return false;
148506f32e7eSjoerg 
148606f32e7eSjoerg   case TemplateArgument::Type:
148706f32e7eSjoerg     if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
148806f32e7eSjoerg       return Visit(TSInfo->getTypeLoc());
148906f32e7eSjoerg     return false;
149006f32e7eSjoerg 
149106f32e7eSjoerg   case TemplateArgument::Declaration:
149206f32e7eSjoerg     if (Expr *E = TAL.getSourceDeclExpression())
149306f32e7eSjoerg       return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
149406f32e7eSjoerg     return false;
149506f32e7eSjoerg 
149606f32e7eSjoerg   case TemplateArgument::NullPtr:
149706f32e7eSjoerg     if (Expr *E = TAL.getSourceNullPtrExpression())
149806f32e7eSjoerg       return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
149906f32e7eSjoerg     return false;
150006f32e7eSjoerg 
150106f32e7eSjoerg   case TemplateArgument::Expression:
150206f32e7eSjoerg     if (Expr *E = TAL.getSourceExpression())
150306f32e7eSjoerg       return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
150406f32e7eSjoerg     return false;
150506f32e7eSjoerg 
150606f32e7eSjoerg   case TemplateArgument::Template:
150706f32e7eSjoerg   case TemplateArgument::TemplateExpansion:
150806f32e7eSjoerg     if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
150906f32e7eSjoerg       return true;
151006f32e7eSjoerg 
151106f32e7eSjoerg     return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
151206f32e7eSjoerg                              TAL.getTemplateNameLoc());
151306f32e7eSjoerg   }
151406f32e7eSjoerg 
151506f32e7eSjoerg   llvm_unreachable("Invalid TemplateArgument::Kind!");
151606f32e7eSjoerg }
151706f32e7eSjoerg 
VisitLinkageSpecDecl(LinkageSpecDecl * D)151806f32e7eSjoerg bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
151906f32e7eSjoerg   return VisitDeclContext(D);
152006f32e7eSjoerg }
152106f32e7eSjoerg 
VisitQualifiedTypeLoc(QualifiedTypeLoc TL)152206f32e7eSjoerg bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
152306f32e7eSjoerg   return Visit(TL.getUnqualifiedLoc());
152406f32e7eSjoerg }
152506f32e7eSjoerg 
VisitBuiltinTypeLoc(BuiltinTypeLoc TL)152606f32e7eSjoerg bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
152706f32e7eSjoerg   ASTContext &Context = AU->getASTContext();
152806f32e7eSjoerg 
152906f32e7eSjoerg   // Some builtin types (such as Objective-C's "id", "sel", and
153006f32e7eSjoerg   // "Class") have associated declarations. Create cursors for those.
153106f32e7eSjoerg   QualType VisitType;
153206f32e7eSjoerg   switch (TL.getTypePtr()->getKind()) {
153306f32e7eSjoerg 
153406f32e7eSjoerg   case BuiltinType::Void:
153506f32e7eSjoerg   case BuiltinType::NullPtr:
153606f32e7eSjoerg   case BuiltinType::Dependent:
153706f32e7eSjoerg #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \
153806f32e7eSjoerg   case BuiltinType::Id:
153906f32e7eSjoerg #include "clang/Basic/OpenCLImageTypes.def"
1540*13fbcb42Sjoerg #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
154106f32e7eSjoerg #include "clang/Basic/OpenCLExtensionTypes.def"
154206f32e7eSjoerg   case BuiltinType::OCLSampler:
154306f32e7eSjoerg   case BuiltinType::OCLEvent:
154406f32e7eSjoerg   case BuiltinType::OCLClkEvent:
154506f32e7eSjoerg   case BuiltinType::OCLQueue:
154606f32e7eSjoerg   case BuiltinType::OCLReserveID:
1547*13fbcb42Sjoerg #define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
154806f32e7eSjoerg #include "clang/Basic/AArch64SVEACLETypes.def"
1549*13fbcb42Sjoerg #define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
1550*13fbcb42Sjoerg #include "clang/Basic/PPCTypes.def"
1551*13fbcb42Sjoerg #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1552*13fbcb42Sjoerg #include "clang/Basic/RISCVVTypes.def"
155306f32e7eSjoerg #define BUILTIN_TYPE(Id, SingletonId)
155406f32e7eSjoerg #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
155506f32e7eSjoerg #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
155606f32e7eSjoerg #define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
155706f32e7eSjoerg #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
155806f32e7eSjoerg #include "clang/AST/BuiltinTypes.def"
155906f32e7eSjoerg     break;
156006f32e7eSjoerg 
156106f32e7eSjoerg   case BuiltinType::ObjCId:
156206f32e7eSjoerg     VisitType = Context.getObjCIdType();
156306f32e7eSjoerg     break;
156406f32e7eSjoerg 
156506f32e7eSjoerg   case BuiltinType::ObjCClass:
156606f32e7eSjoerg     VisitType = Context.getObjCClassType();
156706f32e7eSjoerg     break;
156806f32e7eSjoerg 
156906f32e7eSjoerg   case BuiltinType::ObjCSel:
157006f32e7eSjoerg     VisitType = Context.getObjCSelType();
157106f32e7eSjoerg     break;
157206f32e7eSjoerg   }
157306f32e7eSjoerg 
157406f32e7eSjoerg   if (!VisitType.isNull()) {
157506f32e7eSjoerg     if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1576*13fbcb42Sjoerg       return Visit(
1577*13fbcb42Sjoerg           MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
157806f32e7eSjoerg   }
157906f32e7eSjoerg 
158006f32e7eSjoerg   return false;
158106f32e7eSjoerg }
158206f32e7eSjoerg 
VisitTypedefTypeLoc(TypedefTypeLoc TL)158306f32e7eSjoerg bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
158406f32e7eSjoerg   return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
158506f32e7eSjoerg }
158606f32e7eSjoerg 
VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL)158706f32e7eSjoerg bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
158806f32e7eSjoerg   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
158906f32e7eSjoerg }
159006f32e7eSjoerg 
VisitTagTypeLoc(TagTypeLoc TL)159106f32e7eSjoerg bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
159206f32e7eSjoerg   if (TL.isDefinition())
159306f32e7eSjoerg     return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
159406f32e7eSjoerg 
159506f32e7eSjoerg   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
159606f32e7eSjoerg }
159706f32e7eSjoerg 
VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL)159806f32e7eSjoerg bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
159906f32e7eSjoerg   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
160006f32e7eSjoerg }
160106f32e7eSjoerg 
VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL)160206f32e7eSjoerg bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
160306f32e7eSjoerg   return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
160406f32e7eSjoerg }
160506f32e7eSjoerg 
VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL)160606f32e7eSjoerg bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
160706f32e7eSjoerg   if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
160806f32e7eSjoerg     return true;
160906f32e7eSjoerg   for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
161006f32e7eSjoerg     if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
161106f32e7eSjoerg                                         TU)))
161206f32e7eSjoerg       return true;
161306f32e7eSjoerg   }
161406f32e7eSjoerg 
161506f32e7eSjoerg   return false;
161606f32e7eSjoerg }
161706f32e7eSjoerg 
VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL)161806f32e7eSjoerg bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
161906f32e7eSjoerg   if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
162006f32e7eSjoerg     return true;
162106f32e7eSjoerg 
162206f32e7eSjoerg   for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
162306f32e7eSjoerg     if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
162406f32e7eSjoerg       return true;
162506f32e7eSjoerg   }
162606f32e7eSjoerg 
162706f32e7eSjoerg   for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
162806f32e7eSjoerg     if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
162906f32e7eSjoerg                                         TU)))
163006f32e7eSjoerg       return true;
163106f32e7eSjoerg   }
163206f32e7eSjoerg 
163306f32e7eSjoerg   return false;
163406f32e7eSjoerg }
163506f32e7eSjoerg 
VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL)163606f32e7eSjoerg bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
163706f32e7eSjoerg   return Visit(TL.getPointeeLoc());
163806f32e7eSjoerg }
163906f32e7eSjoerg 
VisitParenTypeLoc(ParenTypeLoc TL)164006f32e7eSjoerg bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
164106f32e7eSjoerg   return Visit(TL.getInnerLoc());
164206f32e7eSjoerg }
164306f32e7eSjoerg 
VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL)164406f32e7eSjoerg bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
164506f32e7eSjoerg   return Visit(TL.getInnerLoc());
164606f32e7eSjoerg }
164706f32e7eSjoerg 
VisitPointerTypeLoc(PointerTypeLoc TL)164806f32e7eSjoerg bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
164906f32e7eSjoerg   return Visit(TL.getPointeeLoc());
165006f32e7eSjoerg }
165106f32e7eSjoerg 
VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL)165206f32e7eSjoerg bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
165306f32e7eSjoerg   return Visit(TL.getPointeeLoc());
165406f32e7eSjoerg }
165506f32e7eSjoerg 
VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL)165606f32e7eSjoerg bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
165706f32e7eSjoerg   return Visit(TL.getPointeeLoc());
165806f32e7eSjoerg }
165906f32e7eSjoerg 
VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL)166006f32e7eSjoerg bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
166106f32e7eSjoerg   return Visit(TL.getPointeeLoc());
166206f32e7eSjoerg }
166306f32e7eSjoerg 
VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL)166406f32e7eSjoerg bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
166506f32e7eSjoerg   return Visit(TL.getPointeeLoc());
166606f32e7eSjoerg }
166706f32e7eSjoerg 
VisitAttributedTypeLoc(AttributedTypeLoc TL)166806f32e7eSjoerg bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
166906f32e7eSjoerg   return Visit(TL.getModifiedLoc());
167006f32e7eSjoerg }
167106f32e7eSjoerg 
VisitFunctionTypeLoc(FunctionTypeLoc TL,bool SkipResultType)167206f32e7eSjoerg bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
167306f32e7eSjoerg                                          bool SkipResultType) {
167406f32e7eSjoerg   if (!SkipResultType && Visit(TL.getReturnLoc()))
167506f32e7eSjoerg     return true;
167606f32e7eSjoerg 
167706f32e7eSjoerg   for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
167806f32e7eSjoerg     if (Decl *D = TL.getParam(I))
167906f32e7eSjoerg       if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
168006f32e7eSjoerg         return true;
168106f32e7eSjoerg 
168206f32e7eSjoerg   return false;
168306f32e7eSjoerg }
168406f32e7eSjoerg 
VisitArrayTypeLoc(ArrayTypeLoc TL)168506f32e7eSjoerg bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
168606f32e7eSjoerg   if (Visit(TL.getElementLoc()))
168706f32e7eSjoerg     return true;
168806f32e7eSjoerg 
168906f32e7eSjoerg   if (Expr *Size = TL.getSizeExpr())
169006f32e7eSjoerg     return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
169106f32e7eSjoerg 
169206f32e7eSjoerg   return false;
169306f32e7eSjoerg }
169406f32e7eSjoerg 
VisitDecayedTypeLoc(DecayedTypeLoc TL)169506f32e7eSjoerg bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
169606f32e7eSjoerg   return Visit(TL.getOriginalLoc());
169706f32e7eSjoerg }
169806f32e7eSjoerg 
VisitAdjustedTypeLoc(AdjustedTypeLoc TL)169906f32e7eSjoerg bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
170006f32e7eSjoerg   return Visit(TL.getOriginalLoc());
170106f32e7eSjoerg }
170206f32e7eSjoerg 
VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL)170306f32e7eSjoerg bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
170406f32e7eSjoerg     DeducedTemplateSpecializationTypeLoc TL) {
170506f32e7eSjoerg   if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
170606f32e7eSjoerg                         TL.getTemplateNameLoc()))
170706f32e7eSjoerg     return true;
170806f32e7eSjoerg 
170906f32e7eSjoerg   return false;
171006f32e7eSjoerg }
171106f32e7eSjoerg 
VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL)171206f32e7eSjoerg bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
171306f32e7eSjoerg     TemplateSpecializationTypeLoc TL) {
171406f32e7eSjoerg   // Visit the template name.
171506f32e7eSjoerg   if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
171606f32e7eSjoerg                         TL.getTemplateNameLoc()))
171706f32e7eSjoerg     return true;
171806f32e7eSjoerg 
171906f32e7eSjoerg   // Visit the template arguments.
172006f32e7eSjoerg   for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
172106f32e7eSjoerg     if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
172206f32e7eSjoerg       return true;
172306f32e7eSjoerg 
172406f32e7eSjoerg   return false;
172506f32e7eSjoerg }
172606f32e7eSjoerg 
VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL)172706f32e7eSjoerg bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
172806f32e7eSjoerg   return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
172906f32e7eSjoerg }
173006f32e7eSjoerg 
VisitTypeOfTypeLoc(TypeOfTypeLoc TL)173106f32e7eSjoerg bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
173206f32e7eSjoerg   if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
173306f32e7eSjoerg     return Visit(TSInfo->getTypeLoc());
173406f32e7eSjoerg 
173506f32e7eSjoerg   return false;
173606f32e7eSjoerg }
173706f32e7eSjoerg 
VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL)173806f32e7eSjoerg bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
173906f32e7eSjoerg   if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
174006f32e7eSjoerg     return Visit(TSInfo->getTypeLoc());
174106f32e7eSjoerg 
174206f32e7eSjoerg   return false;
174306f32e7eSjoerg }
174406f32e7eSjoerg 
VisitDependentNameTypeLoc(DependentNameTypeLoc TL)174506f32e7eSjoerg bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
174606f32e7eSjoerg   return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
174706f32e7eSjoerg }
174806f32e7eSjoerg 
VisitDependentTemplateSpecializationTypeLoc(DependentTemplateSpecializationTypeLoc TL)174906f32e7eSjoerg bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
175006f32e7eSjoerg     DependentTemplateSpecializationTypeLoc TL) {
175106f32e7eSjoerg   // Visit the nested-name-specifier, if there is one.
1752*13fbcb42Sjoerg   if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
175306f32e7eSjoerg     return true;
175406f32e7eSjoerg 
175506f32e7eSjoerg   // Visit the template arguments.
175606f32e7eSjoerg   for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
175706f32e7eSjoerg     if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
175806f32e7eSjoerg       return true;
175906f32e7eSjoerg 
176006f32e7eSjoerg   return false;
176106f32e7eSjoerg }
176206f32e7eSjoerg 
VisitElaboratedTypeLoc(ElaboratedTypeLoc TL)176306f32e7eSjoerg bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
176406f32e7eSjoerg   if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
176506f32e7eSjoerg     return true;
176606f32e7eSjoerg 
176706f32e7eSjoerg   return Visit(TL.getNamedTypeLoc());
176806f32e7eSjoerg }
176906f32e7eSjoerg 
VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL)177006f32e7eSjoerg bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
177106f32e7eSjoerg   return Visit(TL.getPatternLoc());
177206f32e7eSjoerg }
177306f32e7eSjoerg 
VisitDecltypeTypeLoc(DecltypeTypeLoc TL)177406f32e7eSjoerg bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
177506f32e7eSjoerg   if (Expr *E = TL.getUnderlyingExpr())
177606f32e7eSjoerg     return Visit(MakeCXCursor(E, StmtParent, TU));
177706f32e7eSjoerg 
177806f32e7eSjoerg   return false;
177906f32e7eSjoerg }
178006f32e7eSjoerg 
VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL)178106f32e7eSjoerg bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
178206f32e7eSjoerg   return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
178306f32e7eSjoerg }
178406f32e7eSjoerg 
VisitAtomicTypeLoc(AtomicTypeLoc TL)178506f32e7eSjoerg bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
178606f32e7eSjoerg   return Visit(TL.getValueLoc());
178706f32e7eSjoerg }
178806f32e7eSjoerg 
VisitPipeTypeLoc(PipeTypeLoc TL)178906f32e7eSjoerg bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
179006f32e7eSjoerg   return Visit(TL.getValueLoc());
179106f32e7eSjoerg }
179206f32e7eSjoerg 
179306f32e7eSjoerg #define DEFAULT_TYPELOC_IMPL(CLASS, PARENT)                                    \
179406f32e7eSjoerg   bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) {               \
179506f32e7eSjoerg     return Visit##PARENT##Loc(TL);                                             \
179606f32e7eSjoerg   }
179706f32e7eSjoerg 
DEFAULT_TYPELOC_IMPL(Complex,Type)179806f32e7eSjoerg DEFAULT_TYPELOC_IMPL(Complex, Type)
179906f32e7eSjoerg DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
180006f32e7eSjoerg DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
180106f32e7eSjoerg DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
180206f32e7eSjoerg DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
180306f32e7eSjoerg DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
180406f32e7eSjoerg DEFAULT_TYPELOC_IMPL(DependentVector, Type)
180506f32e7eSjoerg DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
180606f32e7eSjoerg DEFAULT_TYPELOC_IMPL(Vector, Type)
180706f32e7eSjoerg DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1808*13fbcb42Sjoerg DEFAULT_TYPELOC_IMPL(ConstantMatrix, MatrixType)
1809*13fbcb42Sjoerg DEFAULT_TYPELOC_IMPL(DependentSizedMatrix, MatrixType)
181006f32e7eSjoerg DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
181106f32e7eSjoerg DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
181206f32e7eSjoerg DEFAULT_TYPELOC_IMPL(Record, TagType)
181306f32e7eSjoerg DEFAULT_TYPELOC_IMPL(Enum, TagType)
181406f32e7eSjoerg DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
181506f32e7eSjoerg DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
181606f32e7eSjoerg DEFAULT_TYPELOC_IMPL(Auto, Type)
1817*13fbcb42Sjoerg DEFAULT_TYPELOC_IMPL(ExtInt, Type)
1818*13fbcb42Sjoerg DEFAULT_TYPELOC_IMPL(DependentExtInt, Type)
181906f32e7eSjoerg 
182006f32e7eSjoerg bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
182106f32e7eSjoerg   // Visit the nested-name-specifier, if present.
182206f32e7eSjoerg   if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
182306f32e7eSjoerg     if (VisitNestedNameSpecifierLoc(QualifierLoc))
182406f32e7eSjoerg       return true;
182506f32e7eSjoerg 
182606f32e7eSjoerg   if (D->isCompleteDefinition()) {
182706f32e7eSjoerg     for (const auto &I : D->bases()) {
182806f32e7eSjoerg       if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
182906f32e7eSjoerg         return true;
183006f32e7eSjoerg     }
183106f32e7eSjoerg   }
183206f32e7eSjoerg 
183306f32e7eSjoerg   return VisitTagDecl(D);
183406f32e7eSjoerg }
183506f32e7eSjoerg 
VisitAttributes(Decl * D)183606f32e7eSjoerg bool CursorVisitor::VisitAttributes(Decl *D) {
183706f32e7eSjoerg   for (const auto *I : D->attrs())
183806f32e7eSjoerg     if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
183906f32e7eSjoerg          !I->isImplicit()) &&
184006f32e7eSjoerg         Visit(MakeCXCursor(I, D, TU)))
184106f32e7eSjoerg       return true;
184206f32e7eSjoerg 
184306f32e7eSjoerg   return false;
184406f32e7eSjoerg }
184506f32e7eSjoerg 
184606f32e7eSjoerg //===----------------------------------------------------------------------===//
184706f32e7eSjoerg // Data-recursive visitor methods.
184806f32e7eSjoerg //===----------------------------------------------------------------------===//
184906f32e7eSjoerg 
185006f32e7eSjoerg namespace {
185106f32e7eSjoerg #define DEF_JOB(NAME, DATA, KIND)                                              \
185206f32e7eSjoerg   class NAME : public VisitorJob {                                             \
185306f32e7eSjoerg   public:                                                                      \
1854*13fbcb42Sjoerg     NAME(const DATA *d, CXCursor parent)                                       \
1855*13fbcb42Sjoerg         : VisitorJob(parent, VisitorJob::KIND, d) {}                           \
1856*13fbcb42Sjoerg     static bool classof(const VisitorJob *VJ) {                                \
1857*13fbcb42Sjoerg       return VJ->getKind() == KIND;                                            \
1858*13fbcb42Sjoerg     }                                                                          \
185906f32e7eSjoerg     const DATA *get() const { return static_cast<const DATA *>(data[0]); }     \
186006f32e7eSjoerg   };
186106f32e7eSjoerg 
186206f32e7eSjoerg DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
186306f32e7eSjoerg DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
186406f32e7eSjoerg DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
186506f32e7eSjoerg DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
186606f32e7eSjoerg DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
186706f32e7eSjoerg DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
186806f32e7eSjoerg DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
186906f32e7eSjoerg #undef DEF_JOB
187006f32e7eSjoerg 
187106f32e7eSjoerg class ExplicitTemplateArgsVisit : public VisitorJob {
187206f32e7eSjoerg public:
ExplicitTemplateArgsVisit(const TemplateArgumentLoc * Begin,const TemplateArgumentLoc * End,CXCursor parent)187306f32e7eSjoerg   ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
187406f32e7eSjoerg                             const TemplateArgumentLoc *End, CXCursor parent)
187506f32e7eSjoerg       : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
187606f32e7eSjoerg                    End) {}
classof(const VisitorJob * VJ)187706f32e7eSjoerg   static bool classof(const VisitorJob *VJ) {
187806f32e7eSjoerg     return VJ->getKind() == ExplicitTemplateArgsVisitKind;
187906f32e7eSjoerg   }
begin() const188006f32e7eSjoerg   const TemplateArgumentLoc *begin() const {
188106f32e7eSjoerg     return static_cast<const TemplateArgumentLoc *>(data[0]);
188206f32e7eSjoerg   }
end()188306f32e7eSjoerg   const TemplateArgumentLoc *end() {
188406f32e7eSjoerg     return static_cast<const TemplateArgumentLoc *>(data[1]);
188506f32e7eSjoerg   }
188606f32e7eSjoerg };
188706f32e7eSjoerg class DeclVisit : public VisitorJob {
188806f32e7eSjoerg public:
DeclVisit(const Decl * D,CXCursor parent,bool isFirst)1889*13fbcb42Sjoerg   DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1890*13fbcb42Sjoerg       : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1891*13fbcb42Sjoerg                    isFirst ? (void *)1 : (void *)nullptr) {}
classof(const VisitorJob * VJ)189206f32e7eSjoerg   static bool classof(const VisitorJob *VJ) {
189306f32e7eSjoerg     return VJ->getKind() == DeclVisitKind;
189406f32e7eSjoerg   }
get() const189506f32e7eSjoerg   const Decl *get() const { return static_cast<const Decl *>(data[0]); }
isFirst() const189606f32e7eSjoerg   bool isFirst() const { return data[1] != nullptr; }
189706f32e7eSjoerg };
189806f32e7eSjoerg class TypeLocVisit : public VisitorJob {
189906f32e7eSjoerg public:
TypeLocVisit(TypeLoc tl,CXCursor parent)1900*13fbcb42Sjoerg   TypeLocVisit(TypeLoc tl, CXCursor parent)
1901*13fbcb42Sjoerg       : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
190206f32e7eSjoerg                    tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
190306f32e7eSjoerg 
classof(const VisitorJob * VJ)190406f32e7eSjoerg   static bool classof(const VisitorJob *VJ) {
190506f32e7eSjoerg     return VJ->getKind() == TypeLocVisitKind;
190606f32e7eSjoerg   }
190706f32e7eSjoerg 
get() const190806f32e7eSjoerg   TypeLoc get() const {
190906f32e7eSjoerg     QualType T = QualType::getFromOpaquePtr(data[0]);
191006f32e7eSjoerg     return TypeLoc(T, const_cast<void *>(data[1]));
191106f32e7eSjoerg   }
191206f32e7eSjoerg };
191306f32e7eSjoerg 
191406f32e7eSjoerg class LabelRefVisit : public VisitorJob {
191506f32e7eSjoerg public:
LabelRefVisit(LabelDecl * LD,SourceLocation labelLoc,CXCursor parent)191606f32e7eSjoerg   LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
191706f32e7eSjoerg       : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
191806f32e7eSjoerg                    labelLoc.getPtrEncoding()) {}
191906f32e7eSjoerg 
classof(const VisitorJob * VJ)192006f32e7eSjoerg   static bool classof(const VisitorJob *VJ) {
192106f32e7eSjoerg     return VJ->getKind() == VisitorJob::LabelRefVisitKind;
192206f32e7eSjoerg   }
get() const192306f32e7eSjoerg   const LabelDecl *get() const {
192406f32e7eSjoerg     return static_cast<const LabelDecl *>(data[0]);
192506f32e7eSjoerg   }
getLoc() const192606f32e7eSjoerg   SourceLocation getLoc() const {
1927*13fbcb42Sjoerg     return SourceLocation::getFromPtrEncoding(data[1]);
1928*13fbcb42Sjoerg   }
192906f32e7eSjoerg };
193006f32e7eSjoerg 
193106f32e7eSjoerg class NestedNameSpecifierLocVisit : public VisitorJob {
193206f32e7eSjoerg public:
NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier,CXCursor parent)193306f32e7eSjoerg   NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
193406f32e7eSjoerg       : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
193506f32e7eSjoerg                    Qualifier.getNestedNameSpecifier(),
193606f32e7eSjoerg                    Qualifier.getOpaqueData()) {}
193706f32e7eSjoerg 
classof(const VisitorJob * VJ)193806f32e7eSjoerg   static bool classof(const VisitorJob *VJ) {
193906f32e7eSjoerg     return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
194006f32e7eSjoerg   }
194106f32e7eSjoerg 
get() const194206f32e7eSjoerg   NestedNameSpecifierLoc get() const {
194306f32e7eSjoerg     return NestedNameSpecifierLoc(
194406f32e7eSjoerg         const_cast<NestedNameSpecifier *>(
194506f32e7eSjoerg             static_cast<const NestedNameSpecifier *>(data[0])),
194606f32e7eSjoerg         const_cast<void *>(data[1]));
194706f32e7eSjoerg   }
194806f32e7eSjoerg };
194906f32e7eSjoerg 
195006f32e7eSjoerg class DeclarationNameInfoVisit : public VisitorJob {
195106f32e7eSjoerg public:
DeclarationNameInfoVisit(const Stmt * S,CXCursor parent)195206f32e7eSjoerg   DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
195306f32e7eSjoerg       : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
classof(const VisitorJob * VJ)195406f32e7eSjoerg   static bool classof(const VisitorJob *VJ) {
195506f32e7eSjoerg     return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
195606f32e7eSjoerg   }
get() const195706f32e7eSjoerg   DeclarationNameInfo get() const {
195806f32e7eSjoerg     const Stmt *S = static_cast<const Stmt *>(data[0]);
195906f32e7eSjoerg     switch (S->getStmtClass()) {
196006f32e7eSjoerg     default:
196106f32e7eSjoerg       llvm_unreachable("Unhandled Stmt");
196206f32e7eSjoerg     case clang::Stmt::MSDependentExistsStmtClass:
196306f32e7eSjoerg       return cast<MSDependentExistsStmt>(S)->getNameInfo();
196406f32e7eSjoerg     case Stmt::CXXDependentScopeMemberExprClass:
196506f32e7eSjoerg       return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
196606f32e7eSjoerg     case Stmt::DependentScopeDeclRefExprClass:
196706f32e7eSjoerg       return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
196806f32e7eSjoerg     case Stmt::OMPCriticalDirectiveClass:
196906f32e7eSjoerg       return cast<OMPCriticalDirective>(S)->getDirectiveName();
197006f32e7eSjoerg     }
197106f32e7eSjoerg   }
197206f32e7eSjoerg };
197306f32e7eSjoerg class MemberRefVisit : public VisitorJob {
197406f32e7eSjoerg public:
MemberRefVisit(const FieldDecl * D,SourceLocation L,CXCursor parent)197506f32e7eSjoerg   MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
197606f32e7eSjoerg       : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
197706f32e7eSjoerg                    L.getPtrEncoding()) {}
classof(const VisitorJob * VJ)197806f32e7eSjoerg   static bool classof(const VisitorJob *VJ) {
197906f32e7eSjoerg     return VJ->getKind() == VisitorJob::MemberRefVisitKind;
198006f32e7eSjoerg   }
get() const198106f32e7eSjoerg   const FieldDecl *get() const {
198206f32e7eSjoerg     return static_cast<const FieldDecl *>(data[0]);
198306f32e7eSjoerg   }
getLoc() const198406f32e7eSjoerg   SourceLocation getLoc() const {
198506f32e7eSjoerg     return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)data[1]);
198606f32e7eSjoerg   }
198706f32e7eSjoerg };
198806f32e7eSjoerg class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
198906f32e7eSjoerg   friend class OMPClauseEnqueue;
199006f32e7eSjoerg   VisitorWorkList &WL;
199106f32e7eSjoerg   CXCursor Parent;
1992*13fbcb42Sjoerg 
199306f32e7eSjoerg public:
EnqueueVisitor(VisitorWorkList & wl,CXCursor parent)199406f32e7eSjoerg   EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
199506f32e7eSjoerg       : WL(wl), Parent(parent) {}
199606f32e7eSjoerg 
199706f32e7eSjoerg   void VisitAddrLabelExpr(const AddrLabelExpr *E);
199806f32e7eSjoerg   void VisitBlockExpr(const BlockExpr *B);
199906f32e7eSjoerg   void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
200006f32e7eSjoerg   void VisitCompoundStmt(const CompoundStmt *S);
VisitCXXDefaultArgExpr(const CXXDefaultArgExpr * E)2001*13fbcb42Sjoerg   void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
2002*13fbcb42Sjoerg   }
200306f32e7eSjoerg   void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
200406f32e7eSjoerg   void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
200506f32e7eSjoerg   void VisitCXXNewExpr(const CXXNewExpr *E);
200606f32e7eSjoerg   void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
200706f32e7eSjoerg   void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
200806f32e7eSjoerg   void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
200906f32e7eSjoerg   void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
201006f32e7eSjoerg   void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
201106f32e7eSjoerg   void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
201206f32e7eSjoerg   void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
201306f32e7eSjoerg   void VisitCXXCatchStmt(const CXXCatchStmt *S);
201406f32e7eSjoerg   void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
201506f32e7eSjoerg   void VisitDeclRefExpr(const DeclRefExpr *D);
201606f32e7eSjoerg   void VisitDeclStmt(const DeclStmt *S);
201706f32e7eSjoerg   void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
201806f32e7eSjoerg   void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
201906f32e7eSjoerg   void VisitExplicitCastExpr(const ExplicitCastExpr *E);
202006f32e7eSjoerg   void VisitForStmt(const ForStmt *FS);
202106f32e7eSjoerg   void VisitGotoStmt(const GotoStmt *GS);
202206f32e7eSjoerg   void VisitIfStmt(const IfStmt *If);
202306f32e7eSjoerg   void VisitInitListExpr(const InitListExpr *IE);
202406f32e7eSjoerg   void VisitMemberExpr(const MemberExpr *M);
202506f32e7eSjoerg   void VisitOffsetOfExpr(const OffsetOfExpr *E);
202606f32e7eSjoerg   void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
202706f32e7eSjoerg   void VisitObjCMessageExpr(const ObjCMessageExpr *M);
202806f32e7eSjoerg   void VisitOverloadExpr(const OverloadExpr *E);
202906f32e7eSjoerg   void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
203006f32e7eSjoerg   void VisitStmt(const Stmt *S);
203106f32e7eSjoerg   void VisitSwitchStmt(const SwitchStmt *S);
203206f32e7eSjoerg   void VisitWhileStmt(const WhileStmt *W);
203306f32e7eSjoerg   void VisitTypeTraitExpr(const TypeTraitExpr *E);
203406f32e7eSjoerg   void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
203506f32e7eSjoerg   void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
203606f32e7eSjoerg   void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
203706f32e7eSjoerg   void VisitVAArgExpr(const VAArgExpr *E);
203806f32e7eSjoerg   void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
203906f32e7eSjoerg   void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
204006f32e7eSjoerg   void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
204106f32e7eSjoerg   void VisitLambdaExpr(const LambdaExpr *E);
204206f32e7eSjoerg   void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
2043*13fbcb42Sjoerg   void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
204406f32e7eSjoerg   void VisitOMPLoopDirective(const OMPLoopDirective *D);
204506f32e7eSjoerg   void VisitOMPParallelDirective(const OMPParallelDirective *D);
204606f32e7eSjoerg   void VisitOMPSimdDirective(const OMPSimdDirective *D);
2047*13fbcb42Sjoerg   void VisitOMPTileDirective(const OMPTileDirective *D);
204806f32e7eSjoerg   void VisitOMPForDirective(const OMPForDirective *D);
204906f32e7eSjoerg   void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
205006f32e7eSjoerg   void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
205106f32e7eSjoerg   void VisitOMPSectionDirective(const OMPSectionDirective *D);
205206f32e7eSjoerg   void VisitOMPSingleDirective(const OMPSingleDirective *D);
205306f32e7eSjoerg   void VisitOMPMasterDirective(const OMPMasterDirective *D);
205406f32e7eSjoerg   void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
205506f32e7eSjoerg   void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
205606f32e7eSjoerg   void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
2057*13fbcb42Sjoerg   void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
205806f32e7eSjoerg   void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
205906f32e7eSjoerg   void VisitOMPTaskDirective(const OMPTaskDirective *D);
206006f32e7eSjoerg   void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
206106f32e7eSjoerg   void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
206206f32e7eSjoerg   void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
206306f32e7eSjoerg   void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
206406f32e7eSjoerg   void
206506f32e7eSjoerg   VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
206606f32e7eSjoerg   void VisitOMPCancelDirective(const OMPCancelDirective *D);
206706f32e7eSjoerg   void VisitOMPFlushDirective(const OMPFlushDirective *D);
2068*13fbcb42Sjoerg   void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
2069*13fbcb42Sjoerg   void VisitOMPScanDirective(const OMPScanDirective *D);
207006f32e7eSjoerg   void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
207106f32e7eSjoerg   void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
207206f32e7eSjoerg   void VisitOMPTargetDirective(const OMPTargetDirective *D);
207306f32e7eSjoerg   void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
207406f32e7eSjoerg   void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
207506f32e7eSjoerg   void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
207606f32e7eSjoerg   void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
207706f32e7eSjoerg   void
207806f32e7eSjoerg   VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
207906f32e7eSjoerg   void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
208006f32e7eSjoerg   void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
208106f32e7eSjoerg   void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
208206f32e7eSjoerg   void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
208306f32e7eSjoerg   void
208406f32e7eSjoerg   VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
208506f32e7eSjoerg   void VisitOMPParallelMasterTaskLoopDirective(
208606f32e7eSjoerg       const OMPParallelMasterTaskLoopDirective *D);
2087*13fbcb42Sjoerg   void VisitOMPParallelMasterTaskLoopSimdDirective(
2088*13fbcb42Sjoerg       const OMPParallelMasterTaskLoopSimdDirective *D);
208906f32e7eSjoerg   void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
209006f32e7eSjoerg   void VisitOMPDistributeParallelForDirective(
209106f32e7eSjoerg       const OMPDistributeParallelForDirective *D);
209206f32e7eSjoerg   void VisitOMPDistributeParallelForSimdDirective(
209306f32e7eSjoerg       const OMPDistributeParallelForSimdDirective *D);
209406f32e7eSjoerg   void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
209506f32e7eSjoerg   void VisitOMPTargetParallelForSimdDirective(
209606f32e7eSjoerg       const OMPTargetParallelForSimdDirective *D);
209706f32e7eSjoerg   void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
209806f32e7eSjoerg   void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
209906f32e7eSjoerg   void VisitOMPTeamsDistributeSimdDirective(
210006f32e7eSjoerg       const OMPTeamsDistributeSimdDirective *D);
210106f32e7eSjoerg   void VisitOMPTeamsDistributeParallelForSimdDirective(
210206f32e7eSjoerg       const OMPTeamsDistributeParallelForSimdDirective *D);
210306f32e7eSjoerg   void VisitOMPTeamsDistributeParallelForDirective(
210406f32e7eSjoerg       const OMPTeamsDistributeParallelForDirective *D);
210506f32e7eSjoerg   void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
210606f32e7eSjoerg   void VisitOMPTargetTeamsDistributeDirective(
210706f32e7eSjoerg       const OMPTargetTeamsDistributeDirective *D);
210806f32e7eSjoerg   void VisitOMPTargetTeamsDistributeParallelForDirective(
210906f32e7eSjoerg       const OMPTargetTeamsDistributeParallelForDirective *D);
211006f32e7eSjoerg   void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
211106f32e7eSjoerg       const OMPTargetTeamsDistributeParallelForSimdDirective *D);
211206f32e7eSjoerg   void VisitOMPTargetTeamsDistributeSimdDirective(
211306f32e7eSjoerg       const OMPTargetTeamsDistributeSimdDirective *D);
211406f32e7eSjoerg 
211506f32e7eSjoerg private:
211606f32e7eSjoerg   void AddDeclarationNameInfo(const Stmt *S);
211706f32e7eSjoerg   void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
211806f32e7eSjoerg   void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
211906f32e7eSjoerg                                unsigned NumTemplateArgs);
212006f32e7eSjoerg   void AddMemberRef(const FieldDecl *D, SourceLocation L);
212106f32e7eSjoerg   void AddStmt(const Stmt *S);
212206f32e7eSjoerg   void AddDecl(const Decl *D, bool isFirst = true);
212306f32e7eSjoerg   void AddTypeLoc(TypeSourceInfo *TI);
212406f32e7eSjoerg   void EnqueueChildren(const Stmt *S);
212506f32e7eSjoerg   void EnqueueChildren(const OMPClause *S);
212606f32e7eSjoerg };
2127*13fbcb42Sjoerg } // namespace
212806f32e7eSjoerg 
AddDeclarationNameInfo(const Stmt * S)212906f32e7eSjoerg void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
213006f32e7eSjoerg   // 'S' should always be non-null, since it comes from the
213106f32e7eSjoerg   // statement we are visiting.
213206f32e7eSjoerg   WL.push_back(DeclarationNameInfoVisit(S, Parent));
213306f32e7eSjoerg }
213406f32e7eSjoerg 
AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier)2135*13fbcb42Sjoerg void EnqueueVisitor::AddNestedNameSpecifierLoc(
2136*13fbcb42Sjoerg     NestedNameSpecifierLoc Qualifier) {
213706f32e7eSjoerg   if (Qualifier)
213806f32e7eSjoerg     WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
213906f32e7eSjoerg }
214006f32e7eSjoerg 
AddStmt(const Stmt * S)214106f32e7eSjoerg void EnqueueVisitor::AddStmt(const Stmt *S) {
214206f32e7eSjoerg   if (S)
214306f32e7eSjoerg     WL.push_back(StmtVisit(S, Parent));
214406f32e7eSjoerg }
AddDecl(const Decl * D,bool isFirst)214506f32e7eSjoerg void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
214606f32e7eSjoerg   if (D)
214706f32e7eSjoerg     WL.push_back(DeclVisit(D, Parent, isFirst));
214806f32e7eSjoerg }
AddExplicitTemplateArgs(const TemplateArgumentLoc * A,unsigned NumTemplateArgs)214906f32e7eSjoerg void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
215006f32e7eSjoerg                                              unsigned NumTemplateArgs) {
215106f32e7eSjoerg   WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
215206f32e7eSjoerg }
AddMemberRef(const FieldDecl * D,SourceLocation L)215306f32e7eSjoerg void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
215406f32e7eSjoerg   if (D)
215506f32e7eSjoerg     WL.push_back(MemberRefVisit(D, L, Parent));
215606f32e7eSjoerg }
AddTypeLoc(TypeSourceInfo * TI)215706f32e7eSjoerg void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
215806f32e7eSjoerg   if (TI)
215906f32e7eSjoerg     WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
216006f32e7eSjoerg }
EnqueueChildren(const Stmt * S)216106f32e7eSjoerg void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
216206f32e7eSjoerg   unsigned size = WL.size();
216306f32e7eSjoerg   for (const Stmt *SubStmt : S->children()) {
216406f32e7eSjoerg     AddStmt(SubStmt);
216506f32e7eSjoerg   }
216606f32e7eSjoerg   if (size == WL.size())
216706f32e7eSjoerg     return;
216806f32e7eSjoerg   // Now reverse the entries we just added.  This will match the DFS
216906f32e7eSjoerg   // ordering performed by the worklist.
217006f32e7eSjoerg   VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
217106f32e7eSjoerg   std::reverse(I, E);
217206f32e7eSjoerg }
217306f32e7eSjoerg namespace {
217406f32e7eSjoerg class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
217506f32e7eSjoerg   EnqueueVisitor *Visitor;
217606f32e7eSjoerg   /// Process clauses with list of variables.
2177*13fbcb42Sjoerg   template <typename T> void VisitOMPClauseList(T *Node);
2178*13fbcb42Sjoerg 
217906f32e7eSjoerg public:
OMPClauseEnqueue(EnqueueVisitor * Visitor)218006f32e7eSjoerg   OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
2181*13fbcb42Sjoerg #define GEN_CLANG_CLAUSE_CLASS
2182*13fbcb42Sjoerg #define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2183*13fbcb42Sjoerg #include "llvm/Frontend/OpenMP/OMP.inc"
218406f32e7eSjoerg   void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
218506f32e7eSjoerg   void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
218606f32e7eSjoerg };
218706f32e7eSjoerg 
VisitOMPClauseWithPreInit(const OMPClauseWithPreInit * C)218806f32e7eSjoerg void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
218906f32e7eSjoerg     const OMPClauseWithPreInit *C) {
219006f32e7eSjoerg   Visitor->AddStmt(C->getPreInitStmt());
219106f32e7eSjoerg }
219206f32e7eSjoerg 
VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate * C)219306f32e7eSjoerg void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
219406f32e7eSjoerg     const OMPClauseWithPostUpdate *C) {
219506f32e7eSjoerg   VisitOMPClauseWithPreInit(C);
219606f32e7eSjoerg   Visitor->AddStmt(C->getPostUpdateExpr());
219706f32e7eSjoerg }
219806f32e7eSjoerg 
VisitOMPIfClause(const OMPIfClause * C)219906f32e7eSjoerg void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
220006f32e7eSjoerg   VisitOMPClauseWithPreInit(C);
220106f32e7eSjoerg   Visitor->AddStmt(C->getCondition());
220206f32e7eSjoerg }
220306f32e7eSjoerg 
VisitOMPFinalClause(const OMPFinalClause * C)220406f32e7eSjoerg void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
220506f32e7eSjoerg   Visitor->AddStmt(C->getCondition());
220606f32e7eSjoerg }
220706f32e7eSjoerg 
VisitOMPNumThreadsClause(const OMPNumThreadsClause * C)220806f32e7eSjoerg void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
220906f32e7eSjoerg   VisitOMPClauseWithPreInit(C);
221006f32e7eSjoerg   Visitor->AddStmt(C->getNumThreads());
221106f32e7eSjoerg }
221206f32e7eSjoerg 
VisitOMPSafelenClause(const OMPSafelenClause * C)221306f32e7eSjoerg void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
221406f32e7eSjoerg   Visitor->AddStmt(C->getSafelen());
221506f32e7eSjoerg }
221606f32e7eSjoerg 
VisitOMPSimdlenClause(const OMPSimdlenClause * C)221706f32e7eSjoerg void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
221806f32e7eSjoerg   Visitor->AddStmt(C->getSimdlen());
221906f32e7eSjoerg }
222006f32e7eSjoerg 
VisitOMPSizesClause(const OMPSizesClause * C)2221*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPSizesClause(const OMPSizesClause *C) {
2222*13fbcb42Sjoerg   for (auto E : C->getSizesRefs())
2223*13fbcb42Sjoerg     Visitor->AddStmt(E);
2224*13fbcb42Sjoerg }
2225*13fbcb42Sjoerg 
VisitOMPAllocatorClause(const OMPAllocatorClause * C)222606f32e7eSjoerg void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
222706f32e7eSjoerg   Visitor->AddStmt(C->getAllocator());
222806f32e7eSjoerg }
222906f32e7eSjoerg 
VisitOMPCollapseClause(const OMPCollapseClause * C)223006f32e7eSjoerg void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
223106f32e7eSjoerg   Visitor->AddStmt(C->getNumForLoops());
223206f32e7eSjoerg }
223306f32e7eSjoerg 
VisitOMPDefaultClause(const OMPDefaultClause * C)223406f32e7eSjoerg void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
223506f32e7eSjoerg 
VisitOMPProcBindClause(const OMPProcBindClause * C)223606f32e7eSjoerg void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
223706f32e7eSjoerg 
VisitOMPScheduleClause(const OMPScheduleClause * C)223806f32e7eSjoerg void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
223906f32e7eSjoerg   VisitOMPClauseWithPreInit(C);
224006f32e7eSjoerg   Visitor->AddStmt(C->getChunkSize());
224106f32e7eSjoerg }
224206f32e7eSjoerg 
VisitOMPOrderedClause(const OMPOrderedClause * C)224306f32e7eSjoerg void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
224406f32e7eSjoerg   Visitor->AddStmt(C->getNumForLoops());
224506f32e7eSjoerg }
224606f32e7eSjoerg 
VisitOMPDetachClause(const OMPDetachClause * C)2247*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2248*13fbcb42Sjoerg   Visitor->AddStmt(C->getEventHandler());
2249*13fbcb42Sjoerg }
2250*13fbcb42Sjoerg 
VisitOMPNowaitClause(const OMPNowaitClause *)225106f32e7eSjoerg void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
225206f32e7eSjoerg 
VisitOMPUntiedClause(const OMPUntiedClause *)225306f32e7eSjoerg void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
225406f32e7eSjoerg 
VisitOMPMergeableClause(const OMPMergeableClause *)225506f32e7eSjoerg void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
225606f32e7eSjoerg 
VisitOMPReadClause(const OMPReadClause *)225706f32e7eSjoerg void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
225806f32e7eSjoerg 
VisitOMPWriteClause(const OMPWriteClause *)225906f32e7eSjoerg void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
226006f32e7eSjoerg 
VisitOMPUpdateClause(const OMPUpdateClause *)226106f32e7eSjoerg void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
226206f32e7eSjoerg 
VisitOMPCaptureClause(const OMPCaptureClause *)226306f32e7eSjoerg void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
226406f32e7eSjoerg 
VisitOMPSeqCstClause(const OMPSeqCstClause *)226506f32e7eSjoerg void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
226606f32e7eSjoerg 
VisitOMPAcqRelClause(const OMPAcqRelClause *)2267*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2268*13fbcb42Sjoerg 
VisitOMPAcquireClause(const OMPAcquireClause *)2269*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2270*13fbcb42Sjoerg 
VisitOMPReleaseClause(const OMPReleaseClause *)2271*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2272*13fbcb42Sjoerg 
VisitOMPRelaxedClause(const OMPRelaxedClause *)2273*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2274*13fbcb42Sjoerg 
VisitOMPThreadsClause(const OMPThreadsClause *)227506f32e7eSjoerg void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
227606f32e7eSjoerg 
VisitOMPSIMDClause(const OMPSIMDClause *)227706f32e7eSjoerg void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
227806f32e7eSjoerg 
VisitOMPNogroupClause(const OMPNogroupClause *)227906f32e7eSjoerg void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
228006f32e7eSjoerg 
VisitOMPInitClause(const OMPInitClause * C)2281*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPInitClause(const OMPInitClause *C) {
2282*13fbcb42Sjoerg   VisitOMPClauseList(C);
2283*13fbcb42Sjoerg }
2284*13fbcb42Sjoerg 
VisitOMPUseClause(const OMPUseClause * C)2285*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPUseClause(const OMPUseClause *C) {
2286*13fbcb42Sjoerg   Visitor->AddStmt(C->getInteropVar());
2287*13fbcb42Sjoerg }
2288*13fbcb42Sjoerg 
VisitOMPDestroyClause(const OMPDestroyClause * C)2289*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *C) {
2290*13fbcb42Sjoerg   if (C->getInteropVar())
2291*13fbcb42Sjoerg     Visitor->AddStmt(C->getInteropVar());
2292*13fbcb42Sjoerg }
2293*13fbcb42Sjoerg 
VisitOMPNovariantsClause(const OMPNovariantsClause * C)2294*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPNovariantsClause(const OMPNovariantsClause *C) {
2295*13fbcb42Sjoerg   Visitor->AddStmt(C->getCondition());
2296*13fbcb42Sjoerg }
2297*13fbcb42Sjoerg 
VisitOMPNocontextClause(const OMPNocontextClause * C)2298*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPNocontextClause(const OMPNocontextClause *C) {
2299*13fbcb42Sjoerg   Visitor->AddStmt(C->getCondition());
2300*13fbcb42Sjoerg }
2301*13fbcb42Sjoerg 
VisitOMPFilterClause(const OMPFilterClause * C)2302*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPFilterClause(const OMPFilterClause *C) {
2303*13fbcb42Sjoerg   VisitOMPClauseWithPreInit(C);
2304*13fbcb42Sjoerg   Visitor->AddStmt(C->getThreadID());
2305*13fbcb42Sjoerg }
2306*13fbcb42Sjoerg 
VisitOMPUnifiedAddressClause(const OMPUnifiedAddressClause *)230706f32e7eSjoerg void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
230806f32e7eSjoerg     const OMPUnifiedAddressClause *) {}
230906f32e7eSjoerg 
VisitOMPUnifiedSharedMemoryClause(const OMPUnifiedSharedMemoryClause *)231006f32e7eSjoerg void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
231106f32e7eSjoerg     const OMPUnifiedSharedMemoryClause *) {}
231206f32e7eSjoerg 
VisitOMPReverseOffloadClause(const OMPReverseOffloadClause *)231306f32e7eSjoerg void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
231406f32e7eSjoerg     const OMPReverseOffloadClause *) {}
231506f32e7eSjoerg 
VisitOMPDynamicAllocatorsClause(const OMPDynamicAllocatorsClause *)231606f32e7eSjoerg void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
231706f32e7eSjoerg     const OMPDynamicAllocatorsClause *) {}
231806f32e7eSjoerg 
VisitOMPAtomicDefaultMemOrderClause(const OMPAtomicDefaultMemOrderClause *)231906f32e7eSjoerg void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
232006f32e7eSjoerg     const OMPAtomicDefaultMemOrderClause *) {}
232106f32e7eSjoerg 
VisitOMPDeviceClause(const OMPDeviceClause * C)232206f32e7eSjoerg void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
232306f32e7eSjoerg   Visitor->AddStmt(C->getDevice());
232406f32e7eSjoerg }
232506f32e7eSjoerg 
VisitOMPNumTeamsClause(const OMPNumTeamsClause * C)232606f32e7eSjoerg void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
232706f32e7eSjoerg   VisitOMPClauseWithPreInit(C);
232806f32e7eSjoerg   Visitor->AddStmt(C->getNumTeams());
232906f32e7eSjoerg }
233006f32e7eSjoerg 
VisitOMPThreadLimitClause(const OMPThreadLimitClause * C)2331*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2332*13fbcb42Sjoerg     const OMPThreadLimitClause *C) {
233306f32e7eSjoerg   VisitOMPClauseWithPreInit(C);
233406f32e7eSjoerg   Visitor->AddStmt(C->getThreadLimit());
233506f32e7eSjoerg }
233606f32e7eSjoerg 
VisitOMPPriorityClause(const OMPPriorityClause * C)233706f32e7eSjoerg void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
233806f32e7eSjoerg   Visitor->AddStmt(C->getPriority());
233906f32e7eSjoerg }
234006f32e7eSjoerg 
VisitOMPGrainsizeClause(const OMPGrainsizeClause * C)234106f32e7eSjoerg void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
234206f32e7eSjoerg   Visitor->AddStmt(C->getGrainsize());
234306f32e7eSjoerg }
234406f32e7eSjoerg 
VisitOMPNumTasksClause(const OMPNumTasksClause * C)234506f32e7eSjoerg void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
234606f32e7eSjoerg   Visitor->AddStmt(C->getNumTasks());
234706f32e7eSjoerg }
234806f32e7eSjoerg 
VisitOMPHintClause(const OMPHintClause * C)234906f32e7eSjoerg void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
235006f32e7eSjoerg   Visitor->AddStmt(C->getHint());
235106f32e7eSjoerg }
235206f32e7eSjoerg 
VisitOMPClauseList(T * Node)2353*13fbcb42Sjoerg template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
235406f32e7eSjoerg   for (const auto *I : Node->varlists()) {
235506f32e7eSjoerg     Visitor->AddStmt(I);
235606f32e7eSjoerg   }
235706f32e7eSjoerg }
235806f32e7eSjoerg 
VisitOMPInclusiveClause(const OMPInclusiveClause * C)2359*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2360*13fbcb42Sjoerg   VisitOMPClauseList(C);
2361*13fbcb42Sjoerg }
VisitOMPExclusiveClause(const OMPExclusiveClause * C)2362*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2363*13fbcb42Sjoerg   VisitOMPClauseList(C);
2364*13fbcb42Sjoerg }
VisitOMPAllocateClause(const OMPAllocateClause * C)236506f32e7eSjoerg void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
236606f32e7eSjoerg   VisitOMPClauseList(C);
236706f32e7eSjoerg   Visitor->AddStmt(C->getAllocator());
236806f32e7eSjoerg }
VisitOMPPrivateClause(const OMPPrivateClause * C)236906f32e7eSjoerg void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
237006f32e7eSjoerg   VisitOMPClauseList(C);
237106f32e7eSjoerg   for (const auto *E : C->private_copies()) {
237206f32e7eSjoerg     Visitor->AddStmt(E);
237306f32e7eSjoerg   }
237406f32e7eSjoerg }
VisitOMPFirstprivateClause(const OMPFirstprivateClause * C)237506f32e7eSjoerg void OMPClauseEnqueue::VisitOMPFirstprivateClause(
237606f32e7eSjoerg     const OMPFirstprivateClause *C) {
237706f32e7eSjoerg   VisitOMPClauseList(C);
237806f32e7eSjoerg   VisitOMPClauseWithPreInit(C);
237906f32e7eSjoerg   for (const auto *E : C->private_copies()) {
238006f32e7eSjoerg     Visitor->AddStmt(E);
238106f32e7eSjoerg   }
238206f32e7eSjoerg   for (const auto *E : C->inits()) {
238306f32e7eSjoerg     Visitor->AddStmt(E);
238406f32e7eSjoerg   }
238506f32e7eSjoerg }
VisitOMPLastprivateClause(const OMPLastprivateClause * C)238606f32e7eSjoerg void OMPClauseEnqueue::VisitOMPLastprivateClause(
238706f32e7eSjoerg     const OMPLastprivateClause *C) {
238806f32e7eSjoerg   VisitOMPClauseList(C);
238906f32e7eSjoerg   VisitOMPClauseWithPostUpdate(C);
239006f32e7eSjoerg   for (auto *E : C->private_copies()) {
239106f32e7eSjoerg     Visitor->AddStmt(E);
239206f32e7eSjoerg   }
239306f32e7eSjoerg   for (auto *E : C->source_exprs()) {
239406f32e7eSjoerg     Visitor->AddStmt(E);
239506f32e7eSjoerg   }
239606f32e7eSjoerg   for (auto *E : C->destination_exprs()) {
239706f32e7eSjoerg     Visitor->AddStmt(E);
239806f32e7eSjoerg   }
239906f32e7eSjoerg   for (auto *E : C->assignment_ops()) {
240006f32e7eSjoerg     Visitor->AddStmt(E);
240106f32e7eSjoerg   }
240206f32e7eSjoerg }
VisitOMPSharedClause(const OMPSharedClause * C)240306f32e7eSjoerg void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
240406f32e7eSjoerg   VisitOMPClauseList(C);
240506f32e7eSjoerg }
VisitOMPReductionClause(const OMPReductionClause * C)240606f32e7eSjoerg void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
240706f32e7eSjoerg   VisitOMPClauseList(C);
240806f32e7eSjoerg   VisitOMPClauseWithPostUpdate(C);
240906f32e7eSjoerg   for (auto *E : C->privates()) {
241006f32e7eSjoerg     Visitor->AddStmt(E);
241106f32e7eSjoerg   }
241206f32e7eSjoerg   for (auto *E : C->lhs_exprs()) {
241306f32e7eSjoerg     Visitor->AddStmt(E);
241406f32e7eSjoerg   }
241506f32e7eSjoerg   for (auto *E : C->rhs_exprs()) {
241606f32e7eSjoerg     Visitor->AddStmt(E);
241706f32e7eSjoerg   }
241806f32e7eSjoerg   for (auto *E : C->reduction_ops()) {
241906f32e7eSjoerg     Visitor->AddStmt(E);
242006f32e7eSjoerg   }
2421*13fbcb42Sjoerg   if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
2422*13fbcb42Sjoerg     for (auto *E : C->copy_ops()) {
2423*13fbcb42Sjoerg       Visitor->AddStmt(E);
2424*13fbcb42Sjoerg     }
2425*13fbcb42Sjoerg     for (auto *E : C->copy_array_temps()) {
2426*13fbcb42Sjoerg       Visitor->AddStmt(E);
2427*13fbcb42Sjoerg     }
2428*13fbcb42Sjoerg     for (auto *E : C->copy_array_elems()) {
2429*13fbcb42Sjoerg       Visitor->AddStmt(E);
2430*13fbcb42Sjoerg     }
2431*13fbcb42Sjoerg   }
243206f32e7eSjoerg }
VisitOMPTaskReductionClause(const OMPTaskReductionClause * C)243306f32e7eSjoerg void OMPClauseEnqueue::VisitOMPTaskReductionClause(
243406f32e7eSjoerg     const OMPTaskReductionClause *C) {
243506f32e7eSjoerg   VisitOMPClauseList(C);
243606f32e7eSjoerg   VisitOMPClauseWithPostUpdate(C);
243706f32e7eSjoerg   for (auto *E : C->privates()) {
243806f32e7eSjoerg     Visitor->AddStmt(E);
243906f32e7eSjoerg   }
244006f32e7eSjoerg   for (auto *E : C->lhs_exprs()) {
244106f32e7eSjoerg     Visitor->AddStmt(E);
244206f32e7eSjoerg   }
244306f32e7eSjoerg   for (auto *E : C->rhs_exprs()) {
244406f32e7eSjoerg     Visitor->AddStmt(E);
244506f32e7eSjoerg   }
244606f32e7eSjoerg   for (auto *E : C->reduction_ops()) {
244706f32e7eSjoerg     Visitor->AddStmt(E);
244806f32e7eSjoerg   }
244906f32e7eSjoerg }
VisitOMPInReductionClause(const OMPInReductionClause * C)245006f32e7eSjoerg void OMPClauseEnqueue::VisitOMPInReductionClause(
245106f32e7eSjoerg     const OMPInReductionClause *C) {
245206f32e7eSjoerg   VisitOMPClauseList(C);
245306f32e7eSjoerg   VisitOMPClauseWithPostUpdate(C);
245406f32e7eSjoerg   for (auto *E : C->privates()) {
245506f32e7eSjoerg     Visitor->AddStmt(E);
245606f32e7eSjoerg   }
245706f32e7eSjoerg   for (auto *E : C->lhs_exprs()) {
245806f32e7eSjoerg     Visitor->AddStmt(E);
245906f32e7eSjoerg   }
246006f32e7eSjoerg   for (auto *E : C->rhs_exprs()) {
246106f32e7eSjoerg     Visitor->AddStmt(E);
246206f32e7eSjoerg   }
246306f32e7eSjoerg   for (auto *E : C->reduction_ops()) {
246406f32e7eSjoerg     Visitor->AddStmt(E);
246506f32e7eSjoerg   }
246606f32e7eSjoerg   for (auto *E : C->taskgroup_descriptors())
246706f32e7eSjoerg     Visitor->AddStmt(E);
246806f32e7eSjoerg }
VisitOMPLinearClause(const OMPLinearClause * C)246906f32e7eSjoerg void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
247006f32e7eSjoerg   VisitOMPClauseList(C);
247106f32e7eSjoerg   VisitOMPClauseWithPostUpdate(C);
247206f32e7eSjoerg   for (const auto *E : C->privates()) {
247306f32e7eSjoerg     Visitor->AddStmt(E);
247406f32e7eSjoerg   }
247506f32e7eSjoerg   for (const auto *E : C->inits()) {
247606f32e7eSjoerg     Visitor->AddStmt(E);
247706f32e7eSjoerg   }
247806f32e7eSjoerg   for (const auto *E : C->updates()) {
247906f32e7eSjoerg     Visitor->AddStmt(E);
248006f32e7eSjoerg   }
248106f32e7eSjoerg   for (const auto *E : C->finals()) {
248206f32e7eSjoerg     Visitor->AddStmt(E);
248306f32e7eSjoerg   }
248406f32e7eSjoerg   Visitor->AddStmt(C->getStep());
248506f32e7eSjoerg   Visitor->AddStmt(C->getCalcStep());
248606f32e7eSjoerg }
VisitOMPAlignedClause(const OMPAlignedClause * C)248706f32e7eSjoerg void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
248806f32e7eSjoerg   VisitOMPClauseList(C);
248906f32e7eSjoerg   Visitor->AddStmt(C->getAlignment());
249006f32e7eSjoerg }
VisitOMPCopyinClause(const OMPCopyinClause * C)249106f32e7eSjoerg void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
249206f32e7eSjoerg   VisitOMPClauseList(C);
249306f32e7eSjoerg   for (auto *E : C->source_exprs()) {
249406f32e7eSjoerg     Visitor->AddStmt(E);
249506f32e7eSjoerg   }
249606f32e7eSjoerg   for (auto *E : C->destination_exprs()) {
249706f32e7eSjoerg     Visitor->AddStmt(E);
249806f32e7eSjoerg   }
249906f32e7eSjoerg   for (auto *E : C->assignment_ops()) {
250006f32e7eSjoerg     Visitor->AddStmt(E);
250106f32e7eSjoerg   }
250206f32e7eSjoerg }
VisitOMPCopyprivateClause(const OMPCopyprivateClause * C)2503*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2504*13fbcb42Sjoerg     const OMPCopyprivateClause *C) {
250506f32e7eSjoerg   VisitOMPClauseList(C);
250606f32e7eSjoerg   for (auto *E : C->source_exprs()) {
250706f32e7eSjoerg     Visitor->AddStmt(E);
250806f32e7eSjoerg   }
250906f32e7eSjoerg   for (auto *E : C->destination_exprs()) {
251006f32e7eSjoerg     Visitor->AddStmt(E);
251106f32e7eSjoerg   }
251206f32e7eSjoerg   for (auto *E : C->assignment_ops()) {
251306f32e7eSjoerg     Visitor->AddStmt(E);
251406f32e7eSjoerg   }
251506f32e7eSjoerg }
VisitOMPFlushClause(const OMPFlushClause * C)251606f32e7eSjoerg void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
251706f32e7eSjoerg   VisitOMPClauseList(C);
251806f32e7eSjoerg }
VisitOMPDepobjClause(const OMPDepobjClause * C)2519*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2520*13fbcb42Sjoerg   Visitor->AddStmt(C->getDepobj());
2521*13fbcb42Sjoerg }
VisitOMPDependClause(const OMPDependClause * C)252206f32e7eSjoerg void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
252306f32e7eSjoerg   VisitOMPClauseList(C);
252406f32e7eSjoerg }
VisitOMPMapClause(const OMPMapClause * C)252506f32e7eSjoerg void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
252606f32e7eSjoerg   VisitOMPClauseList(C);
252706f32e7eSjoerg }
VisitOMPDistScheduleClause(const OMPDistScheduleClause * C)252806f32e7eSjoerg void OMPClauseEnqueue::VisitOMPDistScheduleClause(
252906f32e7eSjoerg     const OMPDistScheduleClause *C) {
253006f32e7eSjoerg   VisitOMPClauseWithPreInit(C);
253106f32e7eSjoerg   Visitor->AddStmt(C->getChunkSize());
253206f32e7eSjoerg }
VisitOMPDefaultmapClause(const OMPDefaultmapClause *)253306f32e7eSjoerg void OMPClauseEnqueue::VisitOMPDefaultmapClause(
253406f32e7eSjoerg     const OMPDefaultmapClause * /*C*/) {}
VisitOMPToClause(const OMPToClause * C)253506f32e7eSjoerg void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
253606f32e7eSjoerg   VisitOMPClauseList(C);
253706f32e7eSjoerg }
VisitOMPFromClause(const OMPFromClause * C)253806f32e7eSjoerg void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
253906f32e7eSjoerg   VisitOMPClauseList(C);
254006f32e7eSjoerg }
VisitOMPUseDevicePtrClause(const OMPUseDevicePtrClause * C)2541*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2542*13fbcb42Sjoerg     const OMPUseDevicePtrClause *C) {
254306f32e7eSjoerg   VisitOMPClauseList(C);
254406f32e7eSjoerg }
VisitOMPUseDeviceAddrClause(const OMPUseDeviceAddrClause * C)2545*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPUseDeviceAddrClause(
2546*13fbcb42Sjoerg     const OMPUseDeviceAddrClause *C) {
254706f32e7eSjoerg   VisitOMPClauseList(C);
254806f32e7eSjoerg }
VisitOMPIsDevicePtrClause(const OMPIsDevicePtrClause * C)2549*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2550*13fbcb42Sjoerg     const OMPIsDevicePtrClause *C) {
2551*13fbcb42Sjoerg   VisitOMPClauseList(C);
255206f32e7eSjoerg }
VisitOMPNontemporalClause(const OMPNontemporalClause * C)2553*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPNontemporalClause(
2554*13fbcb42Sjoerg     const OMPNontemporalClause *C) {
2555*13fbcb42Sjoerg   VisitOMPClauseList(C);
2556*13fbcb42Sjoerg   for (const auto *E : C->private_refs())
2557*13fbcb42Sjoerg     Visitor->AddStmt(E);
2558*13fbcb42Sjoerg }
VisitOMPOrderClause(const OMPOrderClause * C)2559*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
VisitOMPUsesAllocatorsClause(const OMPUsesAllocatorsClause * C)2560*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
2561*13fbcb42Sjoerg     const OMPUsesAllocatorsClause *C) {
2562*13fbcb42Sjoerg   for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
2563*13fbcb42Sjoerg     const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);
2564*13fbcb42Sjoerg     Visitor->AddStmt(D.Allocator);
2565*13fbcb42Sjoerg     Visitor->AddStmt(D.AllocatorTraits);
2566*13fbcb42Sjoerg   }
2567*13fbcb42Sjoerg }
VisitOMPAffinityClause(const OMPAffinityClause * C)2568*13fbcb42Sjoerg void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) {
2569*13fbcb42Sjoerg   Visitor->AddStmt(C->getModifier());
2570*13fbcb42Sjoerg   for (const Expr *E : C->varlists())
2571*13fbcb42Sjoerg     Visitor->AddStmt(E);
2572*13fbcb42Sjoerg }
2573*13fbcb42Sjoerg } // namespace
257406f32e7eSjoerg 
EnqueueChildren(const OMPClause * S)257506f32e7eSjoerg void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
257606f32e7eSjoerg   unsigned size = WL.size();
257706f32e7eSjoerg   OMPClauseEnqueue Visitor(this);
257806f32e7eSjoerg   Visitor.Visit(S);
257906f32e7eSjoerg   if (size == WL.size())
258006f32e7eSjoerg     return;
258106f32e7eSjoerg   // Now reverse the entries we just added.  This will match the DFS
258206f32e7eSjoerg   // ordering performed by the worklist.
258306f32e7eSjoerg   VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
258406f32e7eSjoerg   std::reverse(I, E);
258506f32e7eSjoerg }
VisitAddrLabelExpr(const AddrLabelExpr * E)258606f32e7eSjoerg void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
258706f32e7eSjoerg   WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
258806f32e7eSjoerg }
VisitBlockExpr(const BlockExpr * B)258906f32e7eSjoerg void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
259006f32e7eSjoerg   AddDecl(B->getBlockDecl());
259106f32e7eSjoerg }
VisitCompoundLiteralExpr(const CompoundLiteralExpr * E)259206f32e7eSjoerg void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
259306f32e7eSjoerg   EnqueueChildren(E);
259406f32e7eSjoerg   AddTypeLoc(E->getTypeSourceInfo());
259506f32e7eSjoerg }
VisitCompoundStmt(const CompoundStmt * S)259606f32e7eSjoerg void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
259706f32e7eSjoerg   for (auto &I : llvm::reverse(S->body()))
259806f32e7eSjoerg     AddStmt(I);
259906f32e7eSjoerg }
VisitMSDependentExistsStmt(const MSDependentExistsStmt * S)2600*13fbcb42Sjoerg void EnqueueVisitor::VisitMSDependentExistsStmt(
2601*13fbcb42Sjoerg     const MSDependentExistsStmt *S) {
260206f32e7eSjoerg   AddStmt(S->getSubStmt());
260306f32e7eSjoerg   AddDeclarationNameInfo(S);
260406f32e7eSjoerg   if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
260506f32e7eSjoerg     AddNestedNameSpecifierLoc(QualifierLoc);
260606f32e7eSjoerg }
260706f32e7eSjoerg 
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr * E)2608*13fbcb42Sjoerg void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2609*13fbcb42Sjoerg     const CXXDependentScopeMemberExpr *E) {
261006f32e7eSjoerg   if (E->hasExplicitTemplateArgs())
261106f32e7eSjoerg     AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
261206f32e7eSjoerg   AddDeclarationNameInfo(E);
261306f32e7eSjoerg   if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
261406f32e7eSjoerg     AddNestedNameSpecifierLoc(QualifierLoc);
261506f32e7eSjoerg   if (!E->isImplicitAccess())
261606f32e7eSjoerg     AddStmt(E->getBase());
261706f32e7eSjoerg }
VisitCXXNewExpr(const CXXNewExpr * E)261806f32e7eSjoerg void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
261906f32e7eSjoerg   // Enqueue the initializer , if any.
262006f32e7eSjoerg   AddStmt(E->getInitializer());
262106f32e7eSjoerg   // Enqueue the array size, if any.
262206f32e7eSjoerg   AddStmt(E->getArraySize().getValueOr(nullptr));
262306f32e7eSjoerg   // Enqueue the allocated type.
262406f32e7eSjoerg   AddTypeLoc(E->getAllocatedTypeSourceInfo());
262506f32e7eSjoerg   // Enqueue the placement arguments.
262606f32e7eSjoerg   for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
262706f32e7eSjoerg     AddStmt(E->getPlacementArg(I - 1));
262806f32e7eSjoerg }
VisitCXXOperatorCallExpr(const CXXOperatorCallExpr * CE)262906f32e7eSjoerg void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
263006f32e7eSjoerg   for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
263106f32e7eSjoerg     AddStmt(CE->getArg(I - 1));
263206f32e7eSjoerg   AddStmt(CE->getCallee());
263306f32e7eSjoerg   AddStmt(CE->getArg(0));
263406f32e7eSjoerg }
VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr * E)263506f32e7eSjoerg void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
263606f32e7eSjoerg     const CXXPseudoDestructorExpr *E) {
263706f32e7eSjoerg   // Visit the name of the type being destroyed.
263806f32e7eSjoerg   AddTypeLoc(E->getDestroyedTypeInfo());
263906f32e7eSjoerg   // Visit the scope type that looks disturbingly like the nested-name-specifier
264006f32e7eSjoerg   // but isn't.
264106f32e7eSjoerg   AddTypeLoc(E->getScopeTypeInfo());
264206f32e7eSjoerg   // Visit the nested-name-specifier.
264306f32e7eSjoerg   if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
264406f32e7eSjoerg     AddNestedNameSpecifierLoc(QualifierLoc);
264506f32e7eSjoerg   // Visit base expression.
264606f32e7eSjoerg   AddStmt(E->getBase());
264706f32e7eSjoerg }
VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr * E)264806f32e7eSjoerg void EnqueueVisitor::VisitCXXScalarValueInitExpr(
264906f32e7eSjoerg     const CXXScalarValueInitExpr *E) {
265006f32e7eSjoerg   AddTypeLoc(E->getTypeSourceInfo());
265106f32e7eSjoerg }
VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr * E)265206f32e7eSjoerg void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
265306f32e7eSjoerg     const CXXTemporaryObjectExpr *E) {
265406f32e7eSjoerg   EnqueueChildren(E);
265506f32e7eSjoerg   AddTypeLoc(E->getTypeSourceInfo());
265606f32e7eSjoerg }
VisitCXXTypeidExpr(const CXXTypeidExpr * E)265706f32e7eSjoerg void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
265806f32e7eSjoerg   EnqueueChildren(E);
265906f32e7eSjoerg   if (E->isTypeOperand())
266006f32e7eSjoerg     AddTypeLoc(E->getTypeOperandSourceInfo());
266106f32e7eSjoerg }
266206f32e7eSjoerg 
VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr * E)266306f32e7eSjoerg void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
266406f32e7eSjoerg     const CXXUnresolvedConstructExpr *E) {
266506f32e7eSjoerg   EnqueueChildren(E);
266606f32e7eSjoerg   AddTypeLoc(E->getTypeSourceInfo());
266706f32e7eSjoerg }
VisitCXXUuidofExpr(const CXXUuidofExpr * E)266806f32e7eSjoerg void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
266906f32e7eSjoerg   EnqueueChildren(E);
267006f32e7eSjoerg   if (E->isTypeOperand())
267106f32e7eSjoerg     AddTypeLoc(E->getTypeOperandSourceInfo());
267206f32e7eSjoerg }
267306f32e7eSjoerg 
VisitCXXCatchStmt(const CXXCatchStmt * S)267406f32e7eSjoerg void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
267506f32e7eSjoerg   EnqueueChildren(S);
267606f32e7eSjoerg   AddDecl(S->getExceptionDecl());
267706f32e7eSjoerg }
267806f32e7eSjoerg 
VisitCXXForRangeStmt(const CXXForRangeStmt * S)267906f32e7eSjoerg void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
268006f32e7eSjoerg   AddStmt(S->getBody());
268106f32e7eSjoerg   AddStmt(S->getRangeInit());
268206f32e7eSjoerg   AddDecl(S->getLoopVariable());
268306f32e7eSjoerg }
268406f32e7eSjoerg 
VisitDeclRefExpr(const DeclRefExpr * DR)268506f32e7eSjoerg void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
268606f32e7eSjoerg   if (DR->hasExplicitTemplateArgs())
268706f32e7eSjoerg     AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
268806f32e7eSjoerg   WL.push_back(DeclRefExprParts(DR, Parent));
268906f32e7eSjoerg }
VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr * E)269006f32e7eSjoerg void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
269106f32e7eSjoerg     const DependentScopeDeclRefExpr *E) {
269206f32e7eSjoerg   if (E->hasExplicitTemplateArgs())
269306f32e7eSjoerg     AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
269406f32e7eSjoerg   AddDeclarationNameInfo(E);
269506f32e7eSjoerg   AddNestedNameSpecifierLoc(E->getQualifierLoc());
269606f32e7eSjoerg }
VisitDeclStmt(const DeclStmt * S)269706f32e7eSjoerg void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
269806f32e7eSjoerg   unsigned size = WL.size();
269906f32e7eSjoerg   bool isFirst = true;
270006f32e7eSjoerg   for (const auto *D : S->decls()) {
270106f32e7eSjoerg     AddDecl(D, isFirst);
270206f32e7eSjoerg     isFirst = false;
270306f32e7eSjoerg   }
270406f32e7eSjoerg   if (size == WL.size())
270506f32e7eSjoerg     return;
270606f32e7eSjoerg   // Now reverse the entries we just added.  This will match the DFS
270706f32e7eSjoerg   // ordering performed by the worklist.
270806f32e7eSjoerg   VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
270906f32e7eSjoerg   std::reverse(I, E);
271006f32e7eSjoerg }
VisitDesignatedInitExpr(const DesignatedInitExpr * E)271106f32e7eSjoerg void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
271206f32e7eSjoerg   AddStmt(E->getInit());
271306f32e7eSjoerg   for (const DesignatedInitExpr::Designator &D :
271406f32e7eSjoerg        llvm::reverse(E->designators())) {
271506f32e7eSjoerg     if (D.isFieldDesignator()) {
271606f32e7eSjoerg       if (FieldDecl *Field = D.getField())
271706f32e7eSjoerg         AddMemberRef(Field, D.getFieldLoc());
271806f32e7eSjoerg       continue;
271906f32e7eSjoerg     }
272006f32e7eSjoerg     if (D.isArrayDesignator()) {
272106f32e7eSjoerg       AddStmt(E->getArrayIndex(D));
272206f32e7eSjoerg       continue;
272306f32e7eSjoerg     }
272406f32e7eSjoerg     assert(D.isArrayRangeDesignator() && "Unknown designator kind");
272506f32e7eSjoerg     AddStmt(E->getArrayRangeEnd(D));
272606f32e7eSjoerg     AddStmt(E->getArrayRangeStart(D));
272706f32e7eSjoerg   }
272806f32e7eSjoerg }
VisitExplicitCastExpr(const ExplicitCastExpr * E)272906f32e7eSjoerg void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
273006f32e7eSjoerg   EnqueueChildren(E);
273106f32e7eSjoerg   AddTypeLoc(E->getTypeInfoAsWritten());
273206f32e7eSjoerg }
VisitForStmt(const ForStmt * FS)273306f32e7eSjoerg void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
273406f32e7eSjoerg   AddStmt(FS->getBody());
273506f32e7eSjoerg   AddStmt(FS->getInc());
273606f32e7eSjoerg   AddStmt(FS->getCond());
273706f32e7eSjoerg   AddDecl(FS->getConditionVariable());
273806f32e7eSjoerg   AddStmt(FS->getInit());
273906f32e7eSjoerg }
VisitGotoStmt(const GotoStmt * GS)274006f32e7eSjoerg void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
274106f32e7eSjoerg   WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
274206f32e7eSjoerg }
VisitIfStmt(const IfStmt * If)274306f32e7eSjoerg void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
274406f32e7eSjoerg   AddStmt(If->getElse());
274506f32e7eSjoerg   AddStmt(If->getThen());
274606f32e7eSjoerg   AddStmt(If->getCond());
2747*13fbcb42Sjoerg   AddStmt(If->getInit());
274806f32e7eSjoerg   AddDecl(If->getConditionVariable());
274906f32e7eSjoerg }
VisitInitListExpr(const InitListExpr * IE)275006f32e7eSjoerg void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
275106f32e7eSjoerg   // We care about the syntactic form of the initializer list, only.
275206f32e7eSjoerg   if (InitListExpr *Syntactic = IE->getSyntacticForm())
275306f32e7eSjoerg     IE = Syntactic;
275406f32e7eSjoerg   EnqueueChildren(IE);
275506f32e7eSjoerg }
VisitMemberExpr(const MemberExpr * M)275606f32e7eSjoerg void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
275706f32e7eSjoerg   WL.push_back(MemberExprParts(M, Parent));
275806f32e7eSjoerg 
275906f32e7eSjoerg   // If the base of the member access expression is an implicit 'this', don't
276006f32e7eSjoerg   // visit it.
276106f32e7eSjoerg   // FIXME: If we ever want to show these implicit accesses, this will be
276206f32e7eSjoerg   // unfortunate. However, clang_getCursor() relies on this behavior.
276306f32e7eSjoerg   if (M->isImplicitAccess())
276406f32e7eSjoerg     return;
276506f32e7eSjoerg 
276606f32e7eSjoerg   // Ignore base anonymous struct/union fields, otherwise they will shadow the
276706f32e7eSjoerg   // real field that we are interested in.
276806f32e7eSjoerg   if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
276906f32e7eSjoerg     if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
277006f32e7eSjoerg       if (FD->isAnonymousStructOrUnion()) {
277106f32e7eSjoerg         AddStmt(SubME->getBase());
277206f32e7eSjoerg         return;
277306f32e7eSjoerg       }
277406f32e7eSjoerg     }
277506f32e7eSjoerg   }
277606f32e7eSjoerg 
277706f32e7eSjoerg   AddStmt(M->getBase());
277806f32e7eSjoerg }
VisitObjCEncodeExpr(const ObjCEncodeExpr * E)277906f32e7eSjoerg void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
278006f32e7eSjoerg   AddTypeLoc(E->getEncodedTypeSourceInfo());
278106f32e7eSjoerg }
VisitObjCMessageExpr(const ObjCMessageExpr * M)278206f32e7eSjoerg void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
278306f32e7eSjoerg   EnqueueChildren(M);
278406f32e7eSjoerg   AddTypeLoc(M->getClassReceiverTypeInfo());
278506f32e7eSjoerg }
VisitOffsetOfExpr(const OffsetOfExpr * E)278606f32e7eSjoerg void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
278706f32e7eSjoerg   // Visit the components of the offsetof expression.
278806f32e7eSjoerg   for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
278906f32e7eSjoerg     const OffsetOfNode &Node = E->getComponent(I - 1);
279006f32e7eSjoerg     switch (Node.getKind()) {
279106f32e7eSjoerg     case OffsetOfNode::Array:
279206f32e7eSjoerg       AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
279306f32e7eSjoerg       break;
279406f32e7eSjoerg     case OffsetOfNode::Field:
279506f32e7eSjoerg       AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
279606f32e7eSjoerg       break;
279706f32e7eSjoerg     case OffsetOfNode::Identifier:
279806f32e7eSjoerg     case OffsetOfNode::Base:
279906f32e7eSjoerg       continue;
280006f32e7eSjoerg     }
280106f32e7eSjoerg   }
280206f32e7eSjoerg   // Visit the type into which we're computing the offset.
280306f32e7eSjoerg   AddTypeLoc(E->getTypeSourceInfo());
280406f32e7eSjoerg }
VisitOverloadExpr(const OverloadExpr * E)280506f32e7eSjoerg void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
280606f32e7eSjoerg   if (E->hasExplicitTemplateArgs())
280706f32e7eSjoerg     AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
280806f32e7eSjoerg   WL.push_back(OverloadExprParts(E, Parent));
280906f32e7eSjoerg }
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * E)281006f32e7eSjoerg void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
281106f32e7eSjoerg     const UnaryExprOrTypeTraitExpr *E) {
281206f32e7eSjoerg   EnqueueChildren(E);
281306f32e7eSjoerg   if (E->isArgumentType())
281406f32e7eSjoerg     AddTypeLoc(E->getArgumentTypeInfo());
281506f32e7eSjoerg }
VisitStmt(const Stmt * S)2816*13fbcb42Sjoerg void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
VisitSwitchStmt(const SwitchStmt * S)281706f32e7eSjoerg void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
281806f32e7eSjoerg   AddStmt(S->getBody());
281906f32e7eSjoerg   AddStmt(S->getCond());
282006f32e7eSjoerg   AddDecl(S->getConditionVariable());
282106f32e7eSjoerg }
282206f32e7eSjoerg 
VisitWhileStmt(const WhileStmt * W)282306f32e7eSjoerg void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
282406f32e7eSjoerg   AddStmt(W->getBody());
282506f32e7eSjoerg   AddStmt(W->getCond());
282606f32e7eSjoerg   AddDecl(W->getConditionVariable());
282706f32e7eSjoerg }
282806f32e7eSjoerg 
VisitTypeTraitExpr(const TypeTraitExpr * E)282906f32e7eSjoerg void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
283006f32e7eSjoerg   for (unsigned I = E->getNumArgs(); I > 0; --I)
283106f32e7eSjoerg     AddTypeLoc(E->getArg(I - 1));
283206f32e7eSjoerg }
283306f32e7eSjoerg 
VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr * E)283406f32e7eSjoerg void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
283506f32e7eSjoerg   AddTypeLoc(E->getQueriedTypeSourceInfo());
283606f32e7eSjoerg }
283706f32e7eSjoerg 
VisitExpressionTraitExpr(const ExpressionTraitExpr * E)283806f32e7eSjoerg void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
283906f32e7eSjoerg   EnqueueChildren(E);
284006f32e7eSjoerg }
284106f32e7eSjoerg 
VisitUnresolvedMemberExpr(const UnresolvedMemberExpr * U)284206f32e7eSjoerg void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
284306f32e7eSjoerg   VisitOverloadExpr(U);
284406f32e7eSjoerg   if (!U->isImplicitAccess())
284506f32e7eSjoerg     AddStmt(U->getBase());
284606f32e7eSjoerg }
VisitVAArgExpr(const VAArgExpr * E)284706f32e7eSjoerg void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
284806f32e7eSjoerg   AddStmt(E->getSubExpr());
284906f32e7eSjoerg   AddTypeLoc(E->getWrittenTypeInfo());
285006f32e7eSjoerg }
VisitSizeOfPackExpr(const SizeOfPackExpr * E)285106f32e7eSjoerg void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
285206f32e7eSjoerg   WL.push_back(SizeOfPackExprParts(E, Parent));
285306f32e7eSjoerg }
VisitOpaqueValueExpr(const OpaqueValueExpr * E)285406f32e7eSjoerg void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
285506f32e7eSjoerg   // If the opaque value has a source expression, just transparently
285606f32e7eSjoerg   // visit that.  This is useful for (e.g.) pseudo-object expressions.
285706f32e7eSjoerg   if (Expr *SourceExpr = E->getSourceExpr())
285806f32e7eSjoerg     return Visit(SourceExpr);
285906f32e7eSjoerg }
VisitLambdaExpr(const LambdaExpr * E)286006f32e7eSjoerg void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
286106f32e7eSjoerg   AddStmt(E->getBody());
286206f32e7eSjoerg   WL.push_back(LambdaExprParts(E, Parent));
286306f32e7eSjoerg }
VisitPseudoObjectExpr(const PseudoObjectExpr * E)286406f32e7eSjoerg void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
286506f32e7eSjoerg   // Treat the expression like its syntactic form.
286606f32e7eSjoerg   Visit(E->getSyntacticForm());
286706f32e7eSjoerg }
286806f32e7eSjoerg 
VisitOMPExecutableDirective(const OMPExecutableDirective * D)286906f32e7eSjoerg void EnqueueVisitor::VisitOMPExecutableDirective(
287006f32e7eSjoerg     const OMPExecutableDirective *D) {
287106f32e7eSjoerg   EnqueueChildren(D);
287206f32e7eSjoerg   for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
287306f32e7eSjoerg                                        E = D->clauses().end();
287406f32e7eSjoerg        I != E; ++I)
287506f32e7eSjoerg     EnqueueChildren(*I);
287606f32e7eSjoerg }
287706f32e7eSjoerg 
VisitOMPLoopBasedDirective(const OMPLoopBasedDirective * D)2878*13fbcb42Sjoerg void EnqueueVisitor::VisitOMPLoopBasedDirective(
2879*13fbcb42Sjoerg     const OMPLoopBasedDirective *D) {
288006f32e7eSjoerg   VisitOMPExecutableDirective(D);
288106f32e7eSjoerg }
288206f32e7eSjoerg 
VisitOMPLoopDirective(const OMPLoopDirective * D)2883*13fbcb42Sjoerg void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2884*13fbcb42Sjoerg   VisitOMPLoopBasedDirective(D);
2885*13fbcb42Sjoerg }
2886*13fbcb42Sjoerg 
VisitOMPParallelDirective(const OMPParallelDirective * D)288706f32e7eSjoerg void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
288806f32e7eSjoerg   VisitOMPExecutableDirective(D);
288906f32e7eSjoerg }
289006f32e7eSjoerg 
VisitOMPSimdDirective(const OMPSimdDirective * D)289106f32e7eSjoerg void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
289206f32e7eSjoerg   VisitOMPLoopDirective(D);
289306f32e7eSjoerg }
289406f32e7eSjoerg 
VisitOMPTileDirective(const OMPTileDirective * D)2895*13fbcb42Sjoerg void EnqueueVisitor::VisitOMPTileDirective(const OMPTileDirective *D) {
2896*13fbcb42Sjoerg   VisitOMPLoopBasedDirective(D);
2897*13fbcb42Sjoerg }
2898*13fbcb42Sjoerg 
VisitOMPForDirective(const OMPForDirective * D)289906f32e7eSjoerg void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
290006f32e7eSjoerg   VisitOMPLoopDirective(D);
290106f32e7eSjoerg }
290206f32e7eSjoerg 
VisitOMPForSimdDirective(const OMPForSimdDirective * D)290306f32e7eSjoerg void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
290406f32e7eSjoerg   VisitOMPLoopDirective(D);
290506f32e7eSjoerg }
290606f32e7eSjoerg 
VisitOMPSectionsDirective(const OMPSectionsDirective * D)290706f32e7eSjoerg void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
290806f32e7eSjoerg   VisitOMPExecutableDirective(D);
290906f32e7eSjoerg }
291006f32e7eSjoerg 
VisitOMPSectionDirective(const OMPSectionDirective * D)291106f32e7eSjoerg void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
291206f32e7eSjoerg   VisitOMPExecutableDirective(D);
291306f32e7eSjoerg }
291406f32e7eSjoerg 
VisitOMPSingleDirective(const OMPSingleDirective * D)291506f32e7eSjoerg void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
291606f32e7eSjoerg   VisitOMPExecutableDirective(D);
291706f32e7eSjoerg }
291806f32e7eSjoerg 
VisitOMPMasterDirective(const OMPMasterDirective * D)291906f32e7eSjoerg void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
292006f32e7eSjoerg   VisitOMPExecutableDirective(D);
292106f32e7eSjoerg }
292206f32e7eSjoerg 
VisitOMPCriticalDirective(const OMPCriticalDirective * D)292306f32e7eSjoerg void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
292406f32e7eSjoerg   VisitOMPExecutableDirective(D);
292506f32e7eSjoerg   AddDeclarationNameInfo(D);
292606f32e7eSjoerg }
292706f32e7eSjoerg 
VisitOMPParallelForDirective(const OMPParallelForDirective * D)2928*13fbcb42Sjoerg void EnqueueVisitor::VisitOMPParallelForDirective(
2929*13fbcb42Sjoerg     const OMPParallelForDirective *D) {
293006f32e7eSjoerg   VisitOMPLoopDirective(D);
293106f32e7eSjoerg }
293206f32e7eSjoerg 
VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective * D)293306f32e7eSjoerg void EnqueueVisitor::VisitOMPParallelForSimdDirective(
293406f32e7eSjoerg     const OMPParallelForSimdDirective *D) {
293506f32e7eSjoerg   VisitOMPLoopDirective(D);
293606f32e7eSjoerg }
293706f32e7eSjoerg 
VisitOMPParallelMasterDirective(const OMPParallelMasterDirective * D)2938*13fbcb42Sjoerg void EnqueueVisitor::VisitOMPParallelMasterDirective(
2939*13fbcb42Sjoerg     const OMPParallelMasterDirective *D) {
2940*13fbcb42Sjoerg   VisitOMPExecutableDirective(D);
2941*13fbcb42Sjoerg }
2942*13fbcb42Sjoerg 
VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective * D)294306f32e7eSjoerg void EnqueueVisitor::VisitOMPParallelSectionsDirective(
294406f32e7eSjoerg     const OMPParallelSectionsDirective *D) {
294506f32e7eSjoerg   VisitOMPExecutableDirective(D);
294606f32e7eSjoerg }
294706f32e7eSjoerg 
VisitOMPTaskDirective(const OMPTaskDirective * D)294806f32e7eSjoerg void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
294906f32e7eSjoerg   VisitOMPExecutableDirective(D);
295006f32e7eSjoerg }
295106f32e7eSjoerg 
VisitOMPTaskyieldDirective(const OMPTaskyieldDirective * D)2952*13fbcb42Sjoerg void EnqueueVisitor::VisitOMPTaskyieldDirective(
2953*13fbcb42Sjoerg     const OMPTaskyieldDirective *D) {
295406f32e7eSjoerg   VisitOMPExecutableDirective(D);
295506f32e7eSjoerg }
295606f32e7eSjoerg 
VisitOMPBarrierDirective(const OMPBarrierDirective * D)295706f32e7eSjoerg void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
295806f32e7eSjoerg   VisitOMPExecutableDirective(D);
295906f32e7eSjoerg }
296006f32e7eSjoerg 
VisitOMPTaskwaitDirective(const OMPTaskwaitDirective * D)296106f32e7eSjoerg void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
296206f32e7eSjoerg   VisitOMPExecutableDirective(D);
296306f32e7eSjoerg }
296406f32e7eSjoerg 
VisitOMPTaskgroupDirective(const OMPTaskgroupDirective * D)296506f32e7eSjoerg void EnqueueVisitor::VisitOMPTaskgroupDirective(
296606f32e7eSjoerg     const OMPTaskgroupDirective *D) {
296706f32e7eSjoerg   VisitOMPExecutableDirective(D);
296806f32e7eSjoerg   if (const Expr *E = D->getReductionRef())
296906f32e7eSjoerg     VisitStmt(E);
297006f32e7eSjoerg }
297106f32e7eSjoerg 
VisitOMPFlushDirective(const OMPFlushDirective * D)297206f32e7eSjoerg void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
297306f32e7eSjoerg   VisitOMPExecutableDirective(D);
297406f32e7eSjoerg }
297506f32e7eSjoerg 
VisitOMPDepobjDirective(const OMPDepobjDirective * D)2976*13fbcb42Sjoerg void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
2977*13fbcb42Sjoerg   VisitOMPExecutableDirective(D);
2978*13fbcb42Sjoerg }
2979*13fbcb42Sjoerg 
VisitOMPScanDirective(const OMPScanDirective * D)2980*13fbcb42Sjoerg void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
2981*13fbcb42Sjoerg   VisitOMPExecutableDirective(D);
2982*13fbcb42Sjoerg }
2983*13fbcb42Sjoerg 
VisitOMPOrderedDirective(const OMPOrderedDirective * D)298406f32e7eSjoerg void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
298506f32e7eSjoerg   VisitOMPExecutableDirective(D);
298606f32e7eSjoerg }
298706f32e7eSjoerg 
VisitOMPAtomicDirective(const OMPAtomicDirective * D)298806f32e7eSjoerg void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
298906f32e7eSjoerg   VisitOMPExecutableDirective(D);
299006f32e7eSjoerg }
299106f32e7eSjoerg 
VisitOMPTargetDirective(const OMPTargetDirective * D)299206f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
299306f32e7eSjoerg   VisitOMPExecutableDirective(D);
299406f32e7eSjoerg }
299506f32e7eSjoerg 
VisitOMPTargetDataDirective(const OMPTargetDataDirective * D)2996*13fbcb42Sjoerg void EnqueueVisitor::VisitOMPTargetDataDirective(
2997*13fbcb42Sjoerg     const OMPTargetDataDirective *D) {
299806f32e7eSjoerg   VisitOMPExecutableDirective(D);
299906f32e7eSjoerg }
300006f32e7eSjoerg 
VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective * D)300106f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
300206f32e7eSjoerg     const OMPTargetEnterDataDirective *D) {
300306f32e7eSjoerg   VisitOMPExecutableDirective(D);
300406f32e7eSjoerg }
300506f32e7eSjoerg 
VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective * D)300606f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetExitDataDirective(
300706f32e7eSjoerg     const OMPTargetExitDataDirective *D) {
300806f32e7eSjoerg   VisitOMPExecutableDirective(D);
300906f32e7eSjoerg }
301006f32e7eSjoerg 
VisitOMPTargetParallelDirective(const OMPTargetParallelDirective * D)301106f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetParallelDirective(
301206f32e7eSjoerg     const OMPTargetParallelDirective *D) {
301306f32e7eSjoerg   VisitOMPExecutableDirective(D);
301406f32e7eSjoerg }
301506f32e7eSjoerg 
VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective * D)301606f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetParallelForDirective(
301706f32e7eSjoerg     const OMPTargetParallelForDirective *D) {
301806f32e7eSjoerg   VisitOMPLoopDirective(D);
301906f32e7eSjoerg }
302006f32e7eSjoerg 
VisitOMPTeamsDirective(const OMPTeamsDirective * D)302106f32e7eSjoerg void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
302206f32e7eSjoerg   VisitOMPExecutableDirective(D);
302306f32e7eSjoerg }
302406f32e7eSjoerg 
VisitOMPCancellationPointDirective(const OMPCancellationPointDirective * D)302506f32e7eSjoerg void EnqueueVisitor::VisitOMPCancellationPointDirective(
302606f32e7eSjoerg     const OMPCancellationPointDirective *D) {
302706f32e7eSjoerg   VisitOMPExecutableDirective(D);
302806f32e7eSjoerg }
302906f32e7eSjoerg 
VisitOMPCancelDirective(const OMPCancelDirective * D)303006f32e7eSjoerg void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
303106f32e7eSjoerg   VisitOMPExecutableDirective(D);
303206f32e7eSjoerg }
303306f32e7eSjoerg 
VisitOMPTaskLoopDirective(const OMPTaskLoopDirective * D)303406f32e7eSjoerg void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
303506f32e7eSjoerg   VisitOMPLoopDirective(D);
303606f32e7eSjoerg }
303706f32e7eSjoerg 
VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective * D)303806f32e7eSjoerg void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
303906f32e7eSjoerg     const OMPTaskLoopSimdDirective *D) {
304006f32e7eSjoerg   VisitOMPLoopDirective(D);
304106f32e7eSjoerg }
304206f32e7eSjoerg 
VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective * D)304306f32e7eSjoerg void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
304406f32e7eSjoerg     const OMPMasterTaskLoopDirective *D) {
304506f32e7eSjoerg   VisitOMPLoopDirective(D);
304606f32e7eSjoerg }
304706f32e7eSjoerg 
VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective * D)304806f32e7eSjoerg void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
304906f32e7eSjoerg     const OMPMasterTaskLoopSimdDirective *D) {
305006f32e7eSjoerg   VisitOMPLoopDirective(D);
305106f32e7eSjoerg }
305206f32e7eSjoerg 
VisitOMPParallelMasterTaskLoopDirective(const OMPParallelMasterTaskLoopDirective * D)305306f32e7eSjoerg void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
305406f32e7eSjoerg     const OMPParallelMasterTaskLoopDirective *D) {
305506f32e7eSjoerg   VisitOMPLoopDirective(D);
305606f32e7eSjoerg }
305706f32e7eSjoerg 
VisitOMPParallelMasterTaskLoopSimdDirective(const OMPParallelMasterTaskLoopSimdDirective * D)3058*13fbcb42Sjoerg void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
3059*13fbcb42Sjoerg     const OMPParallelMasterTaskLoopSimdDirective *D) {
3060*13fbcb42Sjoerg   VisitOMPLoopDirective(D);
3061*13fbcb42Sjoerg }
3062*13fbcb42Sjoerg 
VisitOMPDistributeDirective(const OMPDistributeDirective * D)306306f32e7eSjoerg void EnqueueVisitor::VisitOMPDistributeDirective(
306406f32e7eSjoerg     const OMPDistributeDirective *D) {
306506f32e7eSjoerg   VisitOMPLoopDirective(D);
306606f32e7eSjoerg }
306706f32e7eSjoerg 
VisitOMPDistributeParallelForDirective(const OMPDistributeParallelForDirective * D)306806f32e7eSjoerg void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
306906f32e7eSjoerg     const OMPDistributeParallelForDirective *D) {
307006f32e7eSjoerg   VisitOMPLoopDirective(D);
307106f32e7eSjoerg }
307206f32e7eSjoerg 
VisitOMPDistributeParallelForSimdDirective(const OMPDistributeParallelForSimdDirective * D)307306f32e7eSjoerg void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
307406f32e7eSjoerg     const OMPDistributeParallelForSimdDirective *D) {
307506f32e7eSjoerg   VisitOMPLoopDirective(D);
307606f32e7eSjoerg }
307706f32e7eSjoerg 
VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective * D)307806f32e7eSjoerg void EnqueueVisitor::VisitOMPDistributeSimdDirective(
307906f32e7eSjoerg     const OMPDistributeSimdDirective *D) {
308006f32e7eSjoerg   VisitOMPLoopDirective(D);
308106f32e7eSjoerg }
308206f32e7eSjoerg 
VisitOMPTargetParallelForSimdDirective(const OMPTargetParallelForSimdDirective * D)308306f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
308406f32e7eSjoerg     const OMPTargetParallelForSimdDirective *D) {
308506f32e7eSjoerg   VisitOMPLoopDirective(D);
308606f32e7eSjoerg }
308706f32e7eSjoerg 
VisitOMPTargetSimdDirective(const OMPTargetSimdDirective * D)308806f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetSimdDirective(
308906f32e7eSjoerg     const OMPTargetSimdDirective *D) {
309006f32e7eSjoerg   VisitOMPLoopDirective(D);
309106f32e7eSjoerg }
309206f32e7eSjoerg 
VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective * D)309306f32e7eSjoerg void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
309406f32e7eSjoerg     const OMPTeamsDistributeDirective *D) {
309506f32e7eSjoerg   VisitOMPLoopDirective(D);
309606f32e7eSjoerg }
309706f32e7eSjoerg 
VisitOMPTeamsDistributeSimdDirective(const OMPTeamsDistributeSimdDirective * D)309806f32e7eSjoerg void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
309906f32e7eSjoerg     const OMPTeamsDistributeSimdDirective *D) {
310006f32e7eSjoerg   VisitOMPLoopDirective(D);
310106f32e7eSjoerg }
310206f32e7eSjoerg 
VisitOMPTeamsDistributeParallelForSimdDirective(const OMPTeamsDistributeParallelForSimdDirective * D)310306f32e7eSjoerg void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
310406f32e7eSjoerg     const OMPTeamsDistributeParallelForSimdDirective *D) {
310506f32e7eSjoerg   VisitOMPLoopDirective(D);
310606f32e7eSjoerg }
310706f32e7eSjoerg 
VisitOMPTeamsDistributeParallelForDirective(const OMPTeamsDistributeParallelForDirective * D)310806f32e7eSjoerg void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
310906f32e7eSjoerg     const OMPTeamsDistributeParallelForDirective *D) {
311006f32e7eSjoerg   VisitOMPLoopDirective(D);
311106f32e7eSjoerg }
311206f32e7eSjoerg 
VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective * D)311306f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetTeamsDirective(
311406f32e7eSjoerg     const OMPTargetTeamsDirective *D) {
311506f32e7eSjoerg   VisitOMPExecutableDirective(D);
311606f32e7eSjoerg }
311706f32e7eSjoerg 
VisitOMPTargetTeamsDistributeDirective(const OMPTargetTeamsDistributeDirective * D)311806f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
311906f32e7eSjoerg     const OMPTargetTeamsDistributeDirective *D) {
312006f32e7eSjoerg   VisitOMPLoopDirective(D);
312106f32e7eSjoerg }
312206f32e7eSjoerg 
VisitOMPTargetTeamsDistributeParallelForDirective(const OMPTargetTeamsDistributeParallelForDirective * D)312306f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
312406f32e7eSjoerg     const OMPTargetTeamsDistributeParallelForDirective *D) {
312506f32e7eSjoerg   VisitOMPLoopDirective(D);
312606f32e7eSjoerg }
312706f32e7eSjoerg 
VisitOMPTargetTeamsDistributeParallelForSimdDirective(const OMPTargetTeamsDistributeParallelForSimdDirective * D)312806f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
312906f32e7eSjoerg     const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
313006f32e7eSjoerg   VisitOMPLoopDirective(D);
313106f32e7eSjoerg }
313206f32e7eSjoerg 
VisitOMPTargetTeamsDistributeSimdDirective(const OMPTargetTeamsDistributeSimdDirective * D)313306f32e7eSjoerg void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
313406f32e7eSjoerg     const OMPTargetTeamsDistributeSimdDirective *D) {
313506f32e7eSjoerg   VisitOMPLoopDirective(D);
313606f32e7eSjoerg }
313706f32e7eSjoerg 
EnqueueWorkList(VisitorWorkList & WL,const Stmt * S)313806f32e7eSjoerg void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
3139*13fbcb42Sjoerg   EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3140*13fbcb42Sjoerg       .Visit(S);
314106f32e7eSjoerg }
314206f32e7eSjoerg 
IsInRegionOfInterest(CXCursor C)314306f32e7eSjoerg bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
314406f32e7eSjoerg   if (RegionOfInterest.isValid()) {
314506f32e7eSjoerg     SourceRange Range = getRawCursorExtent(C);
314606f32e7eSjoerg     if (Range.isInvalid() || CompareRegionOfInterest(Range))
314706f32e7eSjoerg       return false;
314806f32e7eSjoerg   }
314906f32e7eSjoerg   return true;
315006f32e7eSjoerg }
315106f32e7eSjoerg 
RunVisitorWorkList(VisitorWorkList & WL)315206f32e7eSjoerg bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
315306f32e7eSjoerg   while (!WL.empty()) {
315406f32e7eSjoerg     // Dequeue the worklist item.
315506f32e7eSjoerg     VisitorJob LI = WL.pop_back_val();
315606f32e7eSjoerg 
315706f32e7eSjoerg     // Set the Parent field, then back to its old value once we're done.
315806f32e7eSjoerg     SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
315906f32e7eSjoerg 
316006f32e7eSjoerg     switch (LI.getKind()) {
316106f32e7eSjoerg     case VisitorJob::DeclVisitKind: {
316206f32e7eSjoerg       const Decl *D = cast<DeclVisit>(&LI)->get();
316306f32e7eSjoerg       if (!D)
316406f32e7eSjoerg         continue;
316506f32e7eSjoerg 
316606f32e7eSjoerg       // For now, perform default visitation for Decls.
316706f32e7eSjoerg       if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
316806f32e7eSjoerg                              cast<DeclVisit>(&LI)->isFirst())))
316906f32e7eSjoerg         return true;
317006f32e7eSjoerg 
317106f32e7eSjoerg       continue;
317206f32e7eSjoerg     }
317306f32e7eSjoerg     case VisitorJob::ExplicitTemplateArgsVisitKind: {
317406f32e7eSjoerg       for (const TemplateArgumentLoc &Arg :
317506f32e7eSjoerg            *cast<ExplicitTemplateArgsVisit>(&LI)) {
317606f32e7eSjoerg         if (VisitTemplateArgumentLoc(Arg))
317706f32e7eSjoerg           return true;
317806f32e7eSjoerg       }
317906f32e7eSjoerg       continue;
318006f32e7eSjoerg     }
318106f32e7eSjoerg     case VisitorJob::TypeLocVisitKind: {
318206f32e7eSjoerg       // Perform default visitation for TypeLocs.
318306f32e7eSjoerg       if (Visit(cast<TypeLocVisit>(&LI)->get()))
318406f32e7eSjoerg         return true;
318506f32e7eSjoerg       continue;
318606f32e7eSjoerg     }
318706f32e7eSjoerg     case VisitorJob::LabelRefVisitKind: {
318806f32e7eSjoerg       const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
318906f32e7eSjoerg       if (LabelStmt *stmt = LS->getStmt()) {
319006f32e7eSjoerg         if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
319106f32e7eSjoerg                                      TU))) {
319206f32e7eSjoerg           return true;
319306f32e7eSjoerg         }
319406f32e7eSjoerg       }
319506f32e7eSjoerg       continue;
319606f32e7eSjoerg     }
319706f32e7eSjoerg 
319806f32e7eSjoerg     case VisitorJob::NestedNameSpecifierLocVisitKind: {
319906f32e7eSjoerg       NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
320006f32e7eSjoerg       if (VisitNestedNameSpecifierLoc(V->get()))
320106f32e7eSjoerg         return true;
320206f32e7eSjoerg       continue;
320306f32e7eSjoerg     }
320406f32e7eSjoerg 
320506f32e7eSjoerg     case VisitorJob::DeclarationNameInfoVisitKind: {
3206*13fbcb42Sjoerg       if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
320706f32e7eSjoerg         return true;
320806f32e7eSjoerg       continue;
320906f32e7eSjoerg     }
321006f32e7eSjoerg     case VisitorJob::MemberRefVisitKind: {
321106f32e7eSjoerg       MemberRefVisit *V = cast<MemberRefVisit>(&LI);
321206f32e7eSjoerg       if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
321306f32e7eSjoerg         return true;
321406f32e7eSjoerg       continue;
321506f32e7eSjoerg     }
321606f32e7eSjoerg     case VisitorJob::StmtVisitKind: {
321706f32e7eSjoerg       const Stmt *S = cast<StmtVisit>(&LI)->get();
321806f32e7eSjoerg       if (!S)
321906f32e7eSjoerg         continue;
322006f32e7eSjoerg 
322106f32e7eSjoerg       // Update the current cursor.
322206f32e7eSjoerg       CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
322306f32e7eSjoerg       if (!IsInRegionOfInterest(Cursor))
322406f32e7eSjoerg         continue;
322506f32e7eSjoerg       switch (Visitor(Cursor, Parent, ClientData)) {
3226*13fbcb42Sjoerg       case CXChildVisit_Break:
3227*13fbcb42Sjoerg         return true;
3228*13fbcb42Sjoerg       case CXChildVisit_Continue:
3229*13fbcb42Sjoerg         break;
323006f32e7eSjoerg       case CXChildVisit_Recurse:
323106f32e7eSjoerg         if (PostChildrenVisitor)
323206f32e7eSjoerg           WL.push_back(PostChildrenVisit(nullptr, Cursor));
323306f32e7eSjoerg         EnqueueWorkList(WL, S);
323406f32e7eSjoerg         break;
323506f32e7eSjoerg       }
323606f32e7eSjoerg       continue;
323706f32e7eSjoerg     }
323806f32e7eSjoerg     case VisitorJob::MemberExprPartsKind: {
323906f32e7eSjoerg       // Handle the other pieces in the MemberExpr besides the base.
324006f32e7eSjoerg       const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
324106f32e7eSjoerg 
324206f32e7eSjoerg       // Visit the nested-name-specifier
324306f32e7eSjoerg       if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
324406f32e7eSjoerg         if (VisitNestedNameSpecifierLoc(QualifierLoc))
324506f32e7eSjoerg           return true;
324606f32e7eSjoerg 
324706f32e7eSjoerg       // Visit the declaration name.
324806f32e7eSjoerg       if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
324906f32e7eSjoerg         return true;
325006f32e7eSjoerg 
325106f32e7eSjoerg       // Visit the explicitly-specified template arguments, if any.
325206f32e7eSjoerg       if (M->hasExplicitTemplateArgs()) {
325306f32e7eSjoerg         for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
325406f32e7eSjoerg                                        *ArgEnd = Arg + M->getNumTemplateArgs();
325506f32e7eSjoerg              Arg != ArgEnd; ++Arg) {
325606f32e7eSjoerg           if (VisitTemplateArgumentLoc(*Arg))
325706f32e7eSjoerg             return true;
325806f32e7eSjoerg         }
325906f32e7eSjoerg       }
326006f32e7eSjoerg       continue;
326106f32e7eSjoerg     }
326206f32e7eSjoerg     case VisitorJob::DeclRefExprPartsKind: {
326306f32e7eSjoerg       const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
326406f32e7eSjoerg       // Visit nested-name-specifier, if present.
326506f32e7eSjoerg       if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
326606f32e7eSjoerg         if (VisitNestedNameSpecifierLoc(QualifierLoc))
326706f32e7eSjoerg           return true;
326806f32e7eSjoerg       // Visit declaration name.
326906f32e7eSjoerg       if (VisitDeclarationNameInfo(DR->getNameInfo()))
327006f32e7eSjoerg         return true;
327106f32e7eSjoerg       continue;
327206f32e7eSjoerg     }
327306f32e7eSjoerg     case VisitorJob::OverloadExprPartsKind: {
327406f32e7eSjoerg       const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
327506f32e7eSjoerg       // Visit the nested-name-specifier.
327606f32e7eSjoerg       if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
327706f32e7eSjoerg         if (VisitNestedNameSpecifierLoc(QualifierLoc))
327806f32e7eSjoerg           return true;
327906f32e7eSjoerg       // Visit the declaration name.
328006f32e7eSjoerg       if (VisitDeclarationNameInfo(O->getNameInfo()))
328106f32e7eSjoerg         return true;
328206f32e7eSjoerg       // Visit the overloaded declaration reference.
328306f32e7eSjoerg       if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
328406f32e7eSjoerg         return true;
328506f32e7eSjoerg       continue;
328606f32e7eSjoerg     }
328706f32e7eSjoerg     case VisitorJob::SizeOfPackExprPartsKind: {
328806f32e7eSjoerg       const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
328906f32e7eSjoerg       NamedDecl *Pack = E->getPack();
329006f32e7eSjoerg       if (isa<TemplateTypeParmDecl>(Pack)) {
329106f32e7eSjoerg         if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
329206f32e7eSjoerg                                     E->getPackLoc(), TU)))
329306f32e7eSjoerg           return true;
329406f32e7eSjoerg 
329506f32e7eSjoerg         continue;
329606f32e7eSjoerg       }
329706f32e7eSjoerg 
329806f32e7eSjoerg       if (isa<TemplateTemplateParmDecl>(Pack)) {
329906f32e7eSjoerg         if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
330006f32e7eSjoerg                                         E->getPackLoc(), TU)))
330106f32e7eSjoerg           return true;
330206f32e7eSjoerg 
330306f32e7eSjoerg         continue;
330406f32e7eSjoerg       }
330506f32e7eSjoerg 
330606f32e7eSjoerg       // Non-type template parameter packs and function parameter packs are
330706f32e7eSjoerg       // treated like DeclRefExpr cursors.
330806f32e7eSjoerg       continue;
330906f32e7eSjoerg     }
331006f32e7eSjoerg 
331106f32e7eSjoerg     case VisitorJob::LambdaExprPartsKind: {
331206f32e7eSjoerg       // Visit non-init captures.
331306f32e7eSjoerg       const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
331406f32e7eSjoerg       for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
331506f32e7eSjoerg                                         CEnd = E->explicit_capture_end();
331606f32e7eSjoerg            C != CEnd; ++C) {
331706f32e7eSjoerg         if (!C->capturesVariable())
331806f32e7eSjoerg           continue;
331906f32e7eSjoerg 
3320*13fbcb42Sjoerg         if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
332106f32e7eSjoerg                                         TU)))
332206f32e7eSjoerg           return true;
332306f32e7eSjoerg       }
332406f32e7eSjoerg       // Visit init captures
332506f32e7eSjoerg       for (auto InitExpr : E->capture_inits()) {
3326*13fbcb42Sjoerg         if (InitExpr && Visit(InitExpr))
332706f32e7eSjoerg           return true;
332806f32e7eSjoerg       }
332906f32e7eSjoerg 
333006f32e7eSjoerg       TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
333106f32e7eSjoerg       // Visit parameters and return type, if present.
333206f32e7eSjoerg       if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
333306f32e7eSjoerg         if (E->hasExplicitParameters()) {
333406f32e7eSjoerg           // Visit parameters.
333506f32e7eSjoerg           for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
333606f32e7eSjoerg             if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
333706f32e7eSjoerg               return true;
333806f32e7eSjoerg         }
333906f32e7eSjoerg         if (E->hasExplicitResultType()) {
334006f32e7eSjoerg           // Visit result type.
334106f32e7eSjoerg           if (Visit(Proto.getReturnLoc()))
334206f32e7eSjoerg             return true;
334306f32e7eSjoerg         }
334406f32e7eSjoerg       }
334506f32e7eSjoerg       break;
334606f32e7eSjoerg     }
334706f32e7eSjoerg 
334806f32e7eSjoerg     case VisitorJob::PostChildrenVisitKind:
334906f32e7eSjoerg       if (PostChildrenVisitor(Parent, ClientData))
335006f32e7eSjoerg         return true;
335106f32e7eSjoerg       break;
335206f32e7eSjoerg     }
335306f32e7eSjoerg   }
335406f32e7eSjoerg   return false;
335506f32e7eSjoerg }
335606f32e7eSjoerg 
Visit(const Stmt * S)335706f32e7eSjoerg bool CursorVisitor::Visit(const Stmt *S) {
335806f32e7eSjoerg   VisitorWorkList *WL = nullptr;
335906f32e7eSjoerg   if (!WorkListFreeList.empty()) {
336006f32e7eSjoerg     WL = WorkListFreeList.back();
336106f32e7eSjoerg     WL->clear();
336206f32e7eSjoerg     WorkListFreeList.pop_back();
3363*13fbcb42Sjoerg   } else {
336406f32e7eSjoerg     WL = new VisitorWorkList();
336506f32e7eSjoerg     WorkListCache.push_back(WL);
336606f32e7eSjoerg   }
336706f32e7eSjoerg   EnqueueWorkList(*WL, S);
336806f32e7eSjoerg   bool result = RunVisitorWorkList(*WL);
336906f32e7eSjoerg   WorkListFreeList.push_back(WL);
337006f32e7eSjoerg   return result;
337106f32e7eSjoerg }
337206f32e7eSjoerg 
337306f32e7eSjoerg namespace {
337406f32e7eSjoerg typedef SmallVector<SourceRange, 4> RefNamePieces;
buildPieces(unsigned NameFlags,bool IsMemberRefExpr,const DeclarationNameInfo & NI,SourceRange QLoc,const SourceRange * TemplateArgsLoc=nullptr)337506f32e7eSjoerg RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
337606f32e7eSjoerg                           const DeclarationNameInfo &NI, SourceRange QLoc,
337706f32e7eSjoerg                           const SourceRange *TemplateArgsLoc = nullptr) {
337806f32e7eSjoerg   const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
337906f32e7eSjoerg   const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
338006f32e7eSjoerg   const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
338106f32e7eSjoerg 
338206f32e7eSjoerg   const DeclarationName::NameKind Kind = NI.getName().getNameKind();
338306f32e7eSjoerg 
338406f32e7eSjoerg   RefNamePieces Pieces;
338506f32e7eSjoerg 
338606f32e7eSjoerg   if (WantQualifier && QLoc.isValid())
338706f32e7eSjoerg     Pieces.push_back(QLoc);
338806f32e7eSjoerg 
338906f32e7eSjoerg   if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
339006f32e7eSjoerg     Pieces.push_back(NI.getLoc());
339106f32e7eSjoerg 
339206f32e7eSjoerg   if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
339306f32e7eSjoerg     Pieces.push_back(*TemplateArgsLoc);
339406f32e7eSjoerg 
339506f32e7eSjoerg   if (Kind == DeclarationName::CXXOperatorName) {
3396*13fbcb42Sjoerg     Pieces.push_back(NI.getInfo().getCXXOperatorNameBeginLoc());
3397*13fbcb42Sjoerg     Pieces.push_back(NI.getInfo().getCXXOperatorNameEndLoc());
339806f32e7eSjoerg   }
339906f32e7eSjoerg 
340006f32e7eSjoerg   if (WantSinglePiece) {
340106f32e7eSjoerg     SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
340206f32e7eSjoerg     Pieces.clear();
340306f32e7eSjoerg     Pieces.push_back(R);
340406f32e7eSjoerg   }
340506f32e7eSjoerg 
340606f32e7eSjoerg   return Pieces;
340706f32e7eSjoerg }
3408*13fbcb42Sjoerg } // namespace
340906f32e7eSjoerg 
341006f32e7eSjoerg //===----------------------------------------------------------------------===//
341106f32e7eSjoerg // Misc. API hooks.
341206f32e7eSjoerg //===----------------------------------------------------------------------===//
341306f32e7eSjoerg 
341406f32e7eSjoerg namespace {
341506f32e7eSjoerg struct RegisterFatalErrorHandler {
RegisterFatalErrorHandler__anondcfcb7bb0511::RegisterFatalErrorHandler341606f32e7eSjoerg   RegisterFatalErrorHandler() {
341706f32e7eSjoerg     clang_install_aborting_llvm_fatal_error_handler();
341806f32e7eSjoerg   }
341906f32e7eSjoerg };
3420*13fbcb42Sjoerg } // namespace
342106f32e7eSjoerg 
3422*13fbcb42Sjoerg static llvm::ManagedStatic<RegisterFatalErrorHandler>
3423*13fbcb42Sjoerg     RegisterFatalErrorHandlerOnce;
342406f32e7eSjoerg 
clang_createIndex(int excludeDeclarationsFromPCH,int displayDiagnostics)342506f32e7eSjoerg CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
342606f32e7eSjoerg                           int displayDiagnostics) {
342706f32e7eSjoerg   // We use crash recovery to make some of our APIs more reliable, implicitly
342806f32e7eSjoerg   // enable it.
342906f32e7eSjoerg   if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
343006f32e7eSjoerg     llvm::CrashRecoveryContext::Enable();
343106f32e7eSjoerg 
343206f32e7eSjoerg   // Look through the managed static to trigger construction of the managed
343306f32e7eSjoerg   // static which registers our fatal error handler. This ensures it is only
343406f32e7eSjoerg   // registered once.
343506f32e7eSjoerg   (void)*RegisterFatalErrorHandlerOnce;
343606f32e7eSjoerg 
343706f32e7eSjoerg   // Initialize targets for clang module support.
343806f32e7eSjoerg   llvm::InitializeAllTargets();
343906f32e7eSjoerg   llvm::InitializeAllTargetMCs();
344006f32e7eSjoerg   llvm::InitializeAllAsmPrinters();
344106f32e7eSjoerg   llvm::InitializeAllAsmParsers();
344206f32e7eSjoerg 
344306f32e7eSjoerg   CIndexer *CIdxr = new CIndexer();
344406f32e7eSjoerg 
344506f32e7eSjoerg   if (excludeDeclarationsFromPCH)
344606f32e7eSjoerg     CIdxr->setOnlyLocalDecls();
344706f32e7eSjoerg   if (displayDiagnostics)
344806f32e7eSjoerg     CIdxr->setDisplayDiagnostics();
344906f32e7eSjoerg 
345006f32e7eSjoerg   if (getenv("LIBCLANG_BGPRIO_INDEX"))
345106f32e7eSjoerg     CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
345206f32e7eSjoerg                                CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
345306f32e7eSjoerg   if (getenv("LIBCLANG_BGPRIO_EDIT"))
345406f32e7eSjoerg     CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
345506f32e7eSjoerg                                CXGlobalOpt_ThreadBackgroundPriorityForEditing);
345606f32e7eSjoerg 
345706f32e7eSjoerg   return CIdxr;
345806f32e7eSjoerg }
345906f32e7eSjoerg 
clang_disposeIndex(CXIndex CIdx)346006f32e7eSjoerg void clang_disposeIndex(CXIndex CIdx) {
346106f32e7eSjoerg   if (CIdx)
346206f32e7eSjoerg     delete static_cast<CIndexer *>(CIdx);
346306f32e7eSjoerg }
346406f32e7eSjoerg 
clang_CXIndex_setGlobalOptions(CXIndex CIdx,unsigned options)346506f32e7eSjoerg void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
346606f32e7eSjoerg   if (CIdx)
346706f32e7eSjoerg     static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
346806f32e7eSjoerg }
346906f32e7eSjoerg 
clang_CXIndex_getGlobalOptions(CXIndex CIdx)347006f32e7eSjoerg unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
347106f32e7eSjoerg   if (CIdx)
347206f32e7eSjoerg     return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
347306f32e7eSjoerg   return 0;
347406f32e7eSjoerg }
347506f32e7eSjoerg 
clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,const char * Path)347606f32e7eSjoerg void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
347706f32e7eSjoerg                                                    const char *Path) {
347806f32e7eSjoerg   if (CIdx)
347906f32e7eSjoerg     static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
348006f32e7eSjoerg }
348106f32e7eSjoerg 
clang_toggleCrashRecovery(unsigned isEnabled)348206f32e7eSjoerg void clang_toggleCrashRecovery(unsigned isEnabled) {
348306f32e7eSjoerg   if (isEnabled)
348406f32e7eSjoerg     llvm::CrashRecoveryContext::Enable();
348506f32e7eSjoerg   else
348606f32e7eSjoerg     llvm::CrashRecoveryContext::Disable();
348706f32e7eSjoerg }
348806f32e7eSjoerg 
clang_createTranslationUnit(CXIndex CIdx,const char * ast_filename)348906f32e7eSjoerg CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
349006f32e7eSjoerg                                               const char *ast_filename) {
349106f32e7eSjoerg   CXTranslationUnit TU;
349206f32e7eSjoerg   enum CXErrorCode Result =
349306f32e7eSjoerg       clang_createTranslationUnit2(CIdx, ast_filename, &TU);
349406f32e7eSjoerg   (void)Result;
349506f32e7eSjoerg   assert((TU && Result == CXError_Success) ||
349606f32e7eSjoerg          (!TU && Result != CXError_Success));
349706f32e7eSjoerg   return TU;
349806f32e7eSjoerg }
349906f32e7eSjoerg 
clang_createTranslationUnit2(CXIndex CIdx,const char * ast_filename,CXTranslationUnit * out_TU)350006f32e7eSjoerg enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
350106f32e7eSjoerg                                               const char *ast_filename,
350206f32e7eSjoerg                                               CXTranslationUnit *out_TU) {
350306f32e7eSjoerg   if (out_TU)
350406f32e7eSjoerg     *out_TU = nullptr;
350506f32e7eSjoerg 
350606f32e7eSjoerg   if (!CIdx || !ast_filename || !out_TU)
350706f32e7eSjoerg     return CXError_InvalidArguments;
350806f32e7eSjoerg 
3509*13fbcb42Sjoerg   LOG_FUNC_SECTION { *Log << ast_filename; }
351006f32e7eSjoerg 
351106f32e7eSjoerg   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
351206f32e7eSjoerg   FileSystemOptions FileSystemOpts;
351306f32e7eSjoerg 
351406f32e7eSjoerg   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
351506f32e7eSjoerg       CompilerInstance::createDiagnostics(new DiagnosticOptions());
351606f32e7eSjoerg   std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
351706f32e7eSjoerg       ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
3518*13fbcb42Sjoerg       ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3519*13fbcb42Sjoerg       CXXIdx->getOnlyLocalDecls(), CaptureDiagsKind::All,
3520*13fbcb42Sjoerg       /*AllowASTWithCompilerErrors=*/true,
352106f32e7eSjoerg       /*UserFilesAreVolatile=*/true);
352206f32e7eSjoerg   *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
352306f32e7eSjoerg   return *out_TU ? CXError_Success : CXError_Failure;
352406f32e7eSjoerg }
352506f32e7eSjoerg 
clang_defaultEditingTranslationUnitOptions()352606f32e7eSjoerg unsigned clang_defaultEditingTranslationUnitOptions() {
352706f32e7eSjoerg   return CXTranslationUnit_PrecompiledPreamble |
352806f32e7eSjoerg          CXTranslationUnit_CacheCompletionResults;
352906f32e7eSjoerg }
353006f32e7eSjoerg 
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)3531*13fbcb42Sjoerg CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3532*13fbcb42Sjoerg     CXIndex CIdx, const char *source_filename, int num_command_line_args,
3533*13fbcb42Sjoerg     const char *const *command_line_args, unsigned num_unsaved_files,
353406f32e7eSjoerg     struct CXUnsavedFile *unsaved_files) {
353506f32e7eSjoerg   unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3536*13fbcb42Sjoerg   return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3537*13fbcb42Sjoerg                                     num_command_line_args, unsaved_files,
3538*13fbcb42Sjoerg                                     num_unsaved_files, Options);
353906f32e7eSjoerg }
354006f32e7eSjoerg 
354106f32e7eSjoerg 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)354206f32e7eSjoerg clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
354306f32e7eSjoerg                                 const char *const *command_line_args,
354406f32e7eSjoerg                                 int num_command_line_args,
354506f32e7eSjoerg                                 ArrayRef<CXUnsavedFile> unsaved_files,
354606f32e7eSjoerg                                 unsigned options, CXTranslationUnit *out_TU) {
354706f32e7eSjoerg   // Set up the initial return values.
354806f32e7eSjoerg   if (out_TU)
354906f32e7eSjoerg     *out_TU = nullptr;
355006f32e7eSjoerg 
355106f32e7eSjoerg   // Check arguments.
355206f32e7eSjoerg   if (!CIdx || !out_TU)
355306f32e7eSjoerg     return CXError_InvalidArguments;
355406f32e7eSjoerg 
355506f32e7eSjoerg   CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
355606f32e7eSjoerg 
355706f32e7eSjoerg   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
355806f32e7eSjoerg     setThreadBackgroundPriority();
355906f32e7eSjoerg 
356006f32e7eSjoerg   bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
356106f32e7eSjoerg   bool CreatePreambleOnFirstParse =
356206f32e7eSjoerg       options & CXTranslationUnit_CreatePreambleOnFirstParse;
356306f32e7eSjoerg   // FIXME: Add a flag for modules.
3564*13fbcb42Sjoerg   TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3565*13fbcb42Sjoerg                                            CXTranslationUnit_SingleFileParse))
3566*13fbcb42Sjoerg                                    ? TU_Prefix
3567*13fbcb42Sjoerg                                    : TU_Complete;
3568*13fbcb42Sjoerg   bool CacheCodeCompletionResults =
3569*13fbcb42Sjoerg       options & CXTranslationUnit_CacheCompletionResults;
3570*13fbcb42Sjoerg   bool IncludeBriefCommentsInCodeCompletion =
3571*13fbcb42Sjoerg       options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
357206f32e7eSjoerg   bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
357306f32e7eSjoerg   bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3574*13fbcb42Sjoerg   bool RetainExcludedCB =
3575*13fbcb42Sjoerg       options & CXTranslationUnit_RetainExcludedConditionalBlocks;
357606f32e7eSjoerg   SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
357706f32e7eSjoerg   if (options & CXTranslationUnit_SkipFunctionBodies) {
357806f32e7eSjoerg     SkipFunctionBodies =
357906f32e7eSjoerg         (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
358006f32e7eSjoerg             ? SkipFunctionBodiesScope::Preamble
358106f32e7eSjoerg             : SkipFunctionBodiesScope::PreambleAndMainFile;
358206f32e7eSjoerg   }
358306f32e7eSjoerg 
358406f32e7eSjoerg   // Configure the diagnostics.
3585*13fbcb42Sjoerg   IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3586*13fbcb42Sjoerg       CompilerInstance::createDiagnostics(new DiagnosticOptions));
358706f32e7eSjoerg 
358806f32e7eSjoerg   if (options & CXTranslationUnit_KeepGoing)
358906f32e7eSjoerg     Diags->setFatalsAsError(true);
359006f32e7eSjoerg 
359106f32e7eSjoerg   CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
359206f32e7eSjoerg   if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
359306f32e7eSjoerg     CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
359406f32e7eSjoerg 
359506f32e7eSjoerg   // Recover resources if we crash before exiting this function.
3596*13fbcb42Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<
3597*13fbcb42Sjoerg       DiagnosticsEngine,
359806f32e7eSjoerg       llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
359906f32e7eSjoerg       DiagCleanup(Diags.get());
360006f32e7eSjoerg 
360106f32e7eSjoerg   std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
360206f32e7eSjoerg       new std::vector<ASTUnit::RemappedFile>());
360306f32e7eSjoerg 
360406f32e7eSjoerg   // Recover resources if we crash before exiting this function.
3605*13fbcb42Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3606*13fbcb42Sjoerg       RemappedCleanup(RemappedFiles.get());
360706f32e7eSjoerg 
360806f32e7eSjoerg   for (auto &UF : unsaved_files) {
360906f32e7eSjoerg     std::unique_ptr<llvm::MemoryBuffer> MB =
361006f32e7eSjoerg         llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
361106f32e7eSjoerg     RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
361206f32e7eSjoerg   }
361306f32e7eSjoerg 
361406f32e7eSjoerg   std::unique_ptr<std::vector<const char *>> Args(
361506f32e7eSjoerg       new std::vector<const char *>());
361606f32e7eSjoerg 
361706f32e7eSjoerg   // Recover resources if we crash before exiting this method.
361806f32e7eSjoerg   llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
361906f32e7eSjoerg       ArgsCleanup(Args.get());
362006f32e7eSjoerg 
362106f32e7eSjoerg   // Since the Clang C library is primarily used by batch tools dealing with
362206f32e7eSjoerg   // (often very broken) source code, where spell-checking can have a
362306f32e7eSjoerg   // significant negative impact on performance (particularly when
362406f32e7eSjoerg   // precompiled headers are involved), we disable it by default.
362506f32e7eSjoerg   // Only do this if we haven't found a spell-checking-related argument.
362606f32e7eSjoerg   bool FoundSpellCheckingArgument = false;
362706f32e7eSjoerg   for (int I = 0; I != num_command_line_args; ++I) {
362806f32e7eSjoerg     if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
362906f32e7eSjoerg         strcmp(command_line_args[I], "-fspell-checking") == 0) {
363006f32e7eSjoerg       FoundSpellCheckingArgument = true;
363106f32e7eSjoerg       break;
363206f32e7eSjoerg     }
363306f32e7eSjoerg   }
363406f32e7eSjoerg   Args->insert(Args->end(), command_line_args,
363506f32e7eSjoerg                command_line_args + num_command_line_args);
363606f32e7eSjoerg 
363706f32e7eSjoerg   if (!FoundSpellCheckingArgument)
363806f32e7eSjoerg     Args->insert(Args->begin() + 1, "-fno-spell-checking");
363906f32e7eSjoerg 
364006f32e7eSjoerg   // The 'source_filename' argument is optional.  If the caller does not
364106f32e7eSjoerg   // specify it then it is assumed that the source file is specified
364206f32e7eSjoerg   // in the actual argument list.
364306f32e7eSjoerg   // Put the source file after command_line_args otherwise if '-x' flag is
364406f32e7eSjoerg   // present it will be unused.
364506f32e7eSjoerg   if (source_filename)
364606f32e7eSjoerg     Args->push_back(source_filename);
364706f32e7eSjoerg 
364806f32e7eSjoerg   // Do we need the detailed preprocessing record?
364906f32e7eSjoerg   if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
365006f32e7eSjoerg     Args->push_back("-Xclang");
365106f32e7eSjoerg     Args->push_back("-detailed-preprocessing-record");
365206f32e7eSjoerg   }
365306f32e7eSjoerg 
365406f32e7eSjoerg   // Suppress any editor placeholder diagnostics.
365506f32e7eSjoerg   Args->push_back("-fallow-editor-placeholders");
365606f32e7eSjoerg 
365706f32e7eSjoerg   unsigned NumErrors = Diags->getClient()->getNumErrors();
365806f32e7eSjoerg   std::unique_ptr<ASTUnit> ErrUnit;
365906f32e7eSjoerg   // Unless the user specified that they want the preamble on the first parse
366006f32e7eSjoerg   // set it up to be created on the first reparse. This makes the first parse
366106f32e7eSjoerg   // faster, trading for a slower (first) reparse.
366206f32e7eSjoerg   unsigned PrecompilePreambleAfterNParses =
366306f32e7eSjoerg       !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
366406f32e7eSjoerg 
366506f32e7eSjoerg   LibclangInvocationReporter InvocationReporter(
366606f32e7eSjoerg       *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
366706f32e7eSjoerg       options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
366806f32e7eSjoerg       unsaved_files);
366906f32e7eSjoerg   std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
367006f32e7eSjoerg       Args->data(), Args->data() + Args->size(),
367106f32e7eSjoerg       CXXIdx->getPCHContainerOperations(), Diags,
367206f32e7eSjoerg       CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
367306f32e7eSjoerg       CaptureDiagnostics, *RemappedFiles.get(),
367406f32e7eSjoerg       /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
367506f32e7eSjoerg       TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
367606f32e7eSjoerg       /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
367706f32e7eSjoerg       /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
367806f32e7eSjoerg       CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
367906f32e7eSjoerg       &ErrUnit));
368006f32e7eSjoerg 
368106f32e7eSjoerg   // Early failures in LoadFromCommandLine may return with ErrUnit unset.
368206f32e7eSjoerg   if (!Unit && !ErrUnit)
368306f32e7eSjoerg     return CXError_ASTReadError;
368406f32e7eSjoerg 
368506f32e7eSjoerg   if (NumErrors != Diags->getClient()->getNumErrors()) {
368606f32e7eSjoerg     // Make sure to check that 'Unit' is non-NULL.
368706f32e7eSjoerg     if (CXXIdx->getDisplayDiagnostics())
368806f32e7eSjoerg       printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
368906f32e7eSjoerg   }
369006f32e7eSjoerg 
369106f32e7eSjoerg   if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
369206f32e7eSjoerg     return CXError_ASTReadError;
369306f32e7eSjoerg 
369406f32e7eSjoerg   *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
369506f32e7eSjoerg   if (CXTranslationUnitImpl *TU = *out_TU) {
369606f32e7eSjoerg     TU->ParsingOptions = options;
369706f32e7eSjoerg     TU->Arguments.reserve(Args->size());
369806f32e7eSjoerg     for (const char *Arg : *Args)
369906f32e7eSjoerg       TU->Arguments.push_back(Arg);
370006f32e7eSjoerg     return CXError_Success;
370106f32e7eSjoerg   }
370206f32e7eSjoerg   return CXError_Failure;
370306f32e7eSjoerg }
370406f32e7eSjoerg 
370506f32e7eSjoerg 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)3706*13fbcb42Sjoerg clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
370706f32e7eSjoerg                            const char *const *command_line_args,
370806f32e7eSjoerg                            int num_command_line_args,
370906f32e7eSjoerg                            struct CXUnsavedFile *unsaved_files,
3710*13fbcb42Sjoerg                            unsigned num_unsaved_files, unsigned options) {
371106f32e7eSjoerg   CXTranslationUnit TU;
371206f32e7eSjoerg   enum CXErrorCode Result = clang_parseTranslationUnit2(
371306f32e7eSjoerg       CIdx, source_filename, command_line_args, num_command_line_args,
371406f32e7eSjoerg       unsaved_files, num_unsaved_files, options, &TU);
371506f32e7eSjoerg   (void)Result;
371606f32e7eSjoerg   assert((TU && Result == CXError_Success) ||
371706f32e7eSjoerg          (!TU && Result != CXError_Success));
371806f32e7eSjoerg   return TU;
371906f32e7eSjoerg }
372006f32e7eSjoerg 
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)372106f32e7eSjoerg enum CXErrorCode clang_parseTranslationUnit2(
372206f32e7eSjoerg     CXIndex CIdx, const char *source_filename,
372306f32e7eSjoerg     const char *const *command_line_args, int num_command_line_args,
372406f32e7eSjoerg     struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
372506f32e7eSjoerg     unsigned options, CXTranslationUnit *out_TU) {
3726*13fbcb42Sjoerg   noteBottomOfStack();
372706f32e7eSjoerg   SmallVector<const char *, 4> Args;
372806f32e7eSjoerg   Args.push_back("clang");
372906f32e7eSjoerg   Args.append(command_line_args, command_line_args + num_command_line_args);
373006f32e7eSjoerg   return clang_parseTranslationUnit2FullArgv(
373106f32e7eSjoerg       CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
373206f32e7eSjoerg       num_unsaved_files, options, out_TU);
373306f32e7eSjoerg }
373406f32e7eSjoerg 
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)373506f32e7eSjoerg enum CXErrorCode clang_parseTranslationUnit2FullArgv(
373606f32e7eSjoerg     CXIndex CIdx, const char *source_filename,
373706f32e7eSjoerg     const char *const *command_line_args, int num_command_line_args,
373806f32e7eSjoerg     struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
373906f32e7eSjoerg     unsigned options, CXTranslationUnit *out_TU) {
374006f32e7eSjoerg   LOG_FUNC_SECTION {
374106f32e7eSjoerg     *Log << source_filename << ": ";
374206f32e7eSjoerg     for (int i = 0; i != num_command_line_args; ++i)
374306f32e7eSjoerg       *Log << command_line_args[i] << " ";
374406f32e7eSjoerg   }
374506f32e7eSjoerg 
374606f32e7eSjoerg   if (num_unsaved_files && !unsaved_files)
374706f32e7eSjoerg     return CXError_InvalidArguments;
374806f32e7eSjoerg 
374906f32e7eSjoerg   CXErrorCode result = CXError_Failure;
375006f32e7eSjoerg   auto ParseTranslationUnitImpl = [=, &result] {
3751*13fbcb42Sjoerg     noteBottomOfStack();
375206f32e7eSjoerg     result = clang_parseTranslationUnit_Impl(
375306f32e7eSjoerg         CIdx, source_filename, command_line_args, num_command_line_args,
375406f32e7eSjoerg         llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
375506f32e7eSjoerg   };
375606f32e7eSjoerg 
375706f32e7eSjoerg   llvm::CrashRecoveryContext CRC;
375806f32e7eSjoerg 
375906f32e7eSjoerg   if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
376006f32e7eSjoerg     fprintf(stderr, "libclang: crash detected during parsing: {\n");
376106f32e7eSjoerg     fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
376206f32e7eSjoerg     fprintf(stderr, "  'command_line_args' : [");
376306f32e7eSjoerg     for (int i = 0; i != num_command_line_args; ++i) {
376406f32e7eSjoerg       if (i)
376506f32e7eSjoerg         fprintf(stderr, ", ");
376606f32e7eSjoerg       fprintf(stderr, "'%s'", command_line_args[i]);
376706f32e7eSjoerg     }
376806f32e7eSjoerg     fprintf(stderr, "],\n");
376906f32e7eSjoerg     fprintf(stderr, "  'unsaved_files' : [");
377006f32e7eSjoerg     for (unsigned i = 0; i != num_unsaved_files; ++i) {
377106f32e7eSjoerg       if (i)
377206f32e7eSjoerg         fprintf(stderr, ", ");
377306f32e7eSjoerg       fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
377406f32e7eSjoerg               unsaved_files[i].Length);
377506f32e7eSjoerg     }
377606f32e7eSjoerg     fprintf(stderr, "],\n");
377706f32e7eSjoerg     fprintf(stderr, "  'options' : %d,\n", options);
377806f32e7eSjoerg     fprintf(stderr, "}\n");
377906f32e7eSjoerg 
378006f32e7eSjoerg     return CXError_Crashed;
378106f32e7eSjoerg   } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
378206f32e7eSjoerg     if (CXTranslationUnit *TU = out_TU)
378306f32e7eSjoerg       PrintLibclangResourceUsage(*TU);
378406f32e7eSjoerg   }
378506f32e7eSjoerg 
378606f32e7eSjoerg   return result;
378706f32e7eSjoerg }
378806f32e7eSjoerg 
clang_Type_getObjCEncoding(CXType CT)378906f32e7eSjoerg CXString clang_Type_getObjCEncoding(CXType CT) {
379006f32e7eSjoerg   CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
379106f32e7eSjoerg   ASTContext &Ctx = getASTUnit(tu)->getASTContext();
379206f32e7eSjoerg   std::string encoding;
3793*13fbcb42Sjoerg   Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
379406f32e7eSjoerg 
379506f32e7eSjoerg   return cxstring::createDup(encoding);
379606f32e7eSjoerg }
379706f32e7eSjoerg 
getMacroIdentifier(CXCursor C)379806f32e7eSjoerg static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
379906f32e7eSjoerg   if (C.kind == CXCursor_MacroDefinition) {
380006f32e7eSjoerg     if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
380106f32e7eSjoerg       return MDR->getName();
380206f32e7eSjoerg   } else if (C.kind == CXCursor_MacroExpansion) {
380306f32e7eSjoerg     MacroExpansionCursor ME = getCursorMacroExpansion(C);
380406f32e7eSjoerg     return ME.getName();
380506f32e7eSjoerg   }
380606f32e7eSjoerg   return nullptr;
380706f32e7eSjoerg }
380806f32e7eSjoerg 
clang_Cursor_isMacroFunctionLike(CXCursor C)380906f32e7eSjoerg unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
381006f32e7eSjoerg   const IdentifierInfo *II = getMacroIdentifier(C);
381106f32e7eSjoerg   if (!II) {
381206f32e7eSjoerg     return false;
381306f32e7eSjoerg   }
381406f32e7eSjoerg   ASTUnit *ASTU = getCursorASTUnit(C);
381506f32e7eSjoerg   Preprocessor &PP = ASTU->getPreprocessor();
381606f32e7eSjoerg   if (const MacroInfo *MI = PP.getMacroInfo(II))
381706f32e7eSjoerg     return MI->isFunctionLike();
381806f32e7eSjoerg   return false;
381906f32e7eSjoerg }
382006f32e7eSjoerg 
clang_Cursor_isMacroBuiltin(CXCursor C)382106f32e7eSjoerg unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
382206f32e7eSjoerg   const IdentifierInfo *II = getMacroIdentifier(C);
382306f32e7eSjoerg   if (!II) {
382406f32e7eSjoerg     return false;
382506f32e7eSjoerg   }
382606f32e7eSjoerg   ASTUnit *ASTU = getCursorASTUnit(C);
382706f32e7eSjoerg   Preprocessor &PP = ASTU->getPreprocessor();
382806f32e7eSjoerg   if (const MacroInfo *MI = PP.getMacroInfo(II))
382906f32e7eSjoerg     return MI->isBuiltinMacro();
383006f32e7eSjoerg   return false;
383106f32e7eSjoerg }
383206f32e7eSjoerg 
clang_Cursor_isFunctionInlined(CXCursor C)383306f32e7eSjoerg unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
383406f32e7eSjoerg   const Decl *D = getCursorDecl(C);
383506f32e7eSjoerg   const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
383606f32e7eSjoerg   if (!FD) {
383706f32e7eSjoerg     return false;
383806f32e7eSjoerg   }
383906f32e7eSjoerg   return FD->isInlined();
384006f32e7eSjoerg }
384106f32e7eSjoerg 
getCFSTR_value(CallExpr * callExpr)384206f32e7eSjoerg static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
384306f32e7eSjoerg   if (callExpr->getNumArgs() != 1) {
384406f32e7eSjoerg     return nullptr;
384506f32e7eSjoerg   }
384606f32e7eSjoerg 
384706f32e7eSjoerg   StringLiteral *S = nullptr;
384806f32e7eSjoerg   auto *arg = callExpr->getArg(0);
384906f32e7eSjoerg   if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
385006f32e7eSjoerg     ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
385106f32e7eSjoerg     auto *subExpr = I->getSubExprAsWritten();
385206f32e7eSjoerg 
385306f32e7eSjoerg     if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
385406f32e7eSjoerg       return nullptr;
385506f32e7eSjoerg     }
385606f32e7eSjoerg 
385706f32e7eSjoerg     S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
385806f32e7eSjoerg   } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
385906f32e7eSjoerg     S = static_cast<StringLiteral *>(callExpr->getArg(0));
386006f32e7eSjoerg   } else {
386106f32e7eSjoerg     return nullptr;
386206f32e7eSjoerg   }
386306f32e7eSjoerg   return S;
386406f32e7eSjoerg }
386506f32e7eSjoerg 
386606f32e7eSjoerg struct ExprEvalResult {
386706f32e7eSjoerg   CXEvalResultKind EvalType;
386806f32e7eSjoerg   union {
386906f32e7eSjoerg     unsigned long long unsignedVal;
387006f32e7eSjoerg     long long intVal;
387106f32e7eSjoerg     double floatVal;
387206f32e7eSjoerg     char *stringVal;
387306f32e7eSjoerg   } EvalData;
387406f32e7eSjoerg   bool IsUnsignedInt;
~ExprEvalResultExprEvalResult387506f32e7eSjoerg   ~ExprEvalResult() {
387606f32e7eSjoerg     if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
387706f32e7eSjoerg         EvalType != CXEval_Int) {
387806f32e7eSjoerg       delete[] EvalData.stringVal;
387906f32e7eSjoerg     }
388006f32e7eSjoerg   }
388106f32e7eSjoerg };
388206f32e7eSjoerg 
clang_EvalResult_dispose(CXEvalResult E)388306f32e7eSjoerg void clang_EvalResult_dispose(CXEvalResult E) {
388406f32e7eSjoerg   delete static_cast<ExprEvalResult *>(E);
388506f32e7eSjoerg }
388606f32e7eSjoerg 
clang_EvalResult_getKind(CXEvalResult E)388706f32e7eSjoerg CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
388806f32e7eSjoerg   if (!E) {
388906f32e7eSjoerg     return CXEval_UnExposed;
389006f32e7eSjoerg   }
389106f32e7eSjoerg   return ((ExprEvalResult *)E)->EvalType;
389206f32e7eSjoerg }
389306f32e7eSjoerg 
clang_EvalResult_getAsInt(CXEvalResult E)389406f32e7eSjoerg int clang_EvalResult_getAsInt(CXEvalResult E) {
389506f32e7eSjoerg   return clang_EvalResult_getAsLongLong(E);
389606f32e7eSjoerg }
389706f32e7eSjoerg 
clang_EvalResult_getAsLongLong(CXEvalResult E)389806f32e7eSjoerg long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
389906f32e7eSjoerg   if (!E) {
390006f32e7eSjoerg     return 0;
390106f32e7eSjoerg   }
390206f32e7eSjoerg   ExprEvalResult *Result = (ExprEvalResult *)E;
390306f32e7eSjoerg   if (Result->IsUnsignedInt)
390406f32e7eSjoerg     return Result->EvalData.unsignedVal;
390506f32e7eSjoerg   return Result->EvalData.intVal;
390606f32e7eSjoerg }
390706f32e7eSjoerg 
clang_EvalResult_isUnsignedInt(CXEvalResult E)390806f32e7eSjoerg unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
390906f32e7eSjoerg   return ((ExprEvalResult *)E)->IsUnsignedInt;
391006f32e7eSjoerg }
391106f32e7eSjoerg 
clang_EvalResult_getAsUnsigned(CXEvalResult E)391206f32e7eSjoerg unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
391306f32e7eSjoerg   if (!E) {
391406f32e7eSjoerg     return 0;
391506f32e7eSjoerg   }
391606f32e7eSjoerg 
391706f32e7eSjoerg   ExprEvalResult *Result = (ExprEvalResult *)E;
391806f32e7eSjoerg   if (Result->IsUnsignedInt)
391906f32e7eSjoerg     return Result->EvalData.unsignedVal;
392006f32e7eSjoerg   return Result->EvalData.intVal;
392106f32e7eSjoerg }
392206f32e7eSjoerg 
clang_EvalResult_getAsDouble(CXEvalResult E)392306f32e7eSjoerg double clang_EvalResult_getAsDouble(CXEvalResult E) {
392406f32e7eSjoerg   if (!E) {
392506f32e7eSjoerg     return 0;
392606f32e7eSjoerg   }
392706f32e7eSjoerg   return ((ExprEvalResult *)E)->EvalData.floatVal;
392806f32e7eSjoerg }
392906f32e7eSjoerg 
clang_EvalResult_getAsStr(CXEvalResult E)393006f32e7eSjoerg const char *clang_EvalResult_getAsStr(CXEvalResult E) {
393106f32e7eSjoerg   if (!E) {
393206f32e7eSjoerg     return nullptr;
393306f32e7eSjoerg   }
393406f32e7eSjoerg   return ((ExprEvalResult *)E)->EvalData.stringVal;
393506f32e7eSjoerg }
393606f32e7eSjoerg 
evaluateExpr(Expr * expr,CXCursor C)393706f32e7eSjoerg static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
393806f32e7eSjoerg   Expr::EvalResult ER;
393906f32e7eSjoerg   ASTContext &ctx = getCursorContext(C);
394006f32e7eSjoerg   if (!expr)
394106f32e7eSjoerg     return nullptr;
394206f32e7eSjoerg 
394306f32e7eSjoerg   expr = expr->IgnoreParens();
394406f32e7eSjoerg   if (expr->isValueDependent())
394506f32e7eSjoerg     return nullptr;
394606f32e7eSjoerg   if (!expr->EvaluateAsRValue(ER, ctx))
394706f32e7eSjoerg     return nullptr;
394806f32e7eSjoerg 
394906f32e7eSjoerg   QualType rettype;
395006f32e7eSjoerg   CallExpr *callExpr;
395106f32e7eSjoerg   auto result = std::make_unique<ExprEvalResult>();
395206f32e7eSjoerg   result->EvalType = CXEval_UnExposed;
395306f32e7eSjoerg   result->IsUnsignedInt = false;
395406f32e7eSjoerg 
395506f32e7eSjoerg   if (ER.Val.isInt()) {
395606f32e7eSjoerg     result->EvalType = CXEval_Int;
395706f32e7eSjoerg 
395806f32e7eSjoerg     auto &val = ER.Val.getInt();
395906f32e7eSjoerg     if (val.isUnsigned()) {
396006f32e7eSjoerg       result->IsUnsignedInt = true;
396106f32e7eSjoerg       result->EvalData.unsignedVal = val.getZExtValue();
396206f32e7eSjoerg     } else {
396306f32e7eSjoerg       result->EvalData.intVal = val.getExtValue();
396406f32e7eSjoerg     }
396506f32e7eSjoerg 
396606f32e7eSjoerg     return result.release();
396706f32e7eSjoerg   }
396806f32e7eSjoerg 
396906f32e7eSjoerg   if (ER.Val.isFloat()) {
397006f32e7eSjoerg     llvm::SmallVector<char, 100> Buffer;
397106f32e7eSjoerg     ER.Val.getFloat().toString(Buffer);
397206f32e7eSjoerg     std::string floatStr(Buffer.data(), Buffer.size());
397306f32e7eSjoerg     result->EvalType = CXEval_Float;
397406f32e7eSjoerg     bool ignored;
397506f32e7eSjoerg     llvm::APFloat apFloat = ER.Val.getFloat();
397606f32e7eSjoerg     apFloat.convert(llvm::APFloat::IEEEdouble(),
397706f32e7eSjoerg                     llvm::APFloat::rmNearestTiesToEven, &ignored);
397806f32e7eSjoerg     result->EvalData.floatVal = apFloat.convertToDouble();
397906f32e7eSjoerg     return result.release();
398006f32e7eSjoerg   }
398106f32e7eSjoerg 
398206f32e7eSjoerg   if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
398306f32e7eSjoerg     const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
398406f32e7eSjoerg     auto *subExpr = I->getSubExprAsWritten();
398506f32e7eSjoerg     if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
398606f32e7eSjoerg         subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
398706f32e7eSjoerg       const StringLiteral *StrE = nullptr;
398806f32e7eSjoerg       const ObjCStringLiteral *ObjCExpr;
398906f32e7eSjoerg       ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
399006f32e7eSjoerg 
399106f32e7eSjoerg       if (ObjCExpr) {
399206f32e7eSjoerg         StrE = ObjCExpr->getString();
399306f32e7eSjoerg         result->EvalType = CXEval_ObjCStrLiteral;
399406f32e7eSjoerg       } else {
399506f32e7eSjoerg         StrE = cast<StringLiteral>(I->getSubExprAsWritten());
399606f32e7eSjoerg         result->EvalType = CXEval_StrLiteral;
399706f32e7eSjoerg       }
399806f32e7eSjoerg 
399906f32e7eSjoerg       std::string strRef(StrE->getString().str());
400006f32e7eSjoerg       result->EvalData.stringVal = new char[strRef.size() + 1];
400106f32e7eSjoerg       strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
400206f32e7eSjoerg               strRef.size());
400306f32e7eSjoerg       result->EvalData.stringVal[strRef.size()] = '\0';
400406f32e7eSjoerg       return result.release();
400506f32e7eSjoerg     }
400606f32e7eSjoerg   } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
400706f32e7eSjoerg              expr->getStmtClass() == Stmt::StringLiteralClass) {
400806f32e7eSjoerg     const StringLiteral *StrE = nullptr;
400906f32e7eSjoerg     const ObjCStringLiteral *ObjCExpr;
401006f32e7eSjoerg     ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
401106f32e7eSjoerg 
401206f32e7eSjoerg     if (ObjCExpr) {
401306f32e7eSjoerg       StrE = ObjCExpr->getString();
401406f32e7eSjoerg       result->EvalType = CXEval_ObjCStrLiteral;
401506f32e7eSjoerg     } else {
401606f32e7eSjoerg       StrE = cast<StringLiteral>(expr);
401706f32e7eSjoerg       result->EvalType = CXEval_StrLiteral;
401806f32e7eSjoerg     }
401906f32e7eSjoerg 
402006f32e7eSjoerg     std::string strRef(StrE->getString().str());
402106f32e7eSjoerg     result->EvalData.stringVal = new char[strRef.size() + 1];
402206f32e7eSjoerg     strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
402306f32e7eSjoerg     result->EvalData.stringVal[strRef.size()] = '\0';
402406f32e7eSjoerg     return result.release();
402506f32e7eSjoerg   }
402606f32e7eSjoerg 
402706f32e7eSjoerg   if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
402806f32e7eSjoerg     CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
402906f32e7eSjoerg 
403006f32e7eSjoerg     rettype = CC->getType();
403106f32e7eSjoerg     if (rettype.getAsString() == "CFStringRef" &&
403206f32e7eSjoerg         CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
403306f32e7eSjoerg 
403406f32e7eSjoerg       callExpr = static_cast<CallExpr *>(CC->getSubExpr());
403506f32e7eSjoerg       StringLiteral *S = getCFSTR_value(callExpr);
403606f32e7eSjoerg       if (S) {
403706f32e7eSjoerg         std::string strLiteral(S->getString().str());
403806f32e7eSjoerg         result->EvalType = CXEval_CFStr;
403906f32e7eSjoerg 
404006f32e7eSjoerg         result->EvalData.stringVal = new char[strLiteral.size() + 1];
404106f32e7eSjoerg         strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
404206f32e7eSjoerg                 strLiteral.size());
404306f32e7eSjoerg         result->EvalData.stringVal[strLiteral.size()] = '\0';
404406f32e7eSjoerg         return result.release();
404506f32e7eSjoerg       }
404606f32e7eSjoerg     }
404706f32e7eSjoerg 
404806f32e7eSjoerg   } else if (expr->getStmtClass() == Stmt::CallExprClass) {
404906f32e7eSjoerg     callExpr = static_cast<CallExpr *>(expr);
405006f32e7eSjoerg     rettype = callExpr->getCallReturnType(ctx);
405106f32e7eSjoerg 
405206f32e7eSjoerg     if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
405306f32e7eSjoerg       return nullptr;
405406f32e7eSjoerg 
405506f32e7eSjoerg     if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
405606f32e7eSjoerg       if (callExpr->getNumArgs() == 1 &&
405706f32e7eSjoerg           !callExpr->getArg(0)->getType()->isIntegralType(ctx))
405806f32e7eSjoerg         return nullptr;
405906f32e7eSjoerg     } else if (rettype.getAsString() == "CFStringRef") {
406006f32e7eSjoerg 
406106f32e7eSjoerg       StringLiteral *S = getCFSTR_value(callExpr);
406206f32e7eSjoerg       if (S) {
406306f32e7eSjoerg         std::string strLiteral(S->getString().str());
406406f32e7eSjoerg         result->EvalType = CXEval_CFStr;
406506f32e7eSjoerg         result->EvalData.stringVal = new char[strLiteral.size() + 1];
406606f32e7eSjoerg         strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
406706f32e7eSjoerg                 strLiteral.size());
406806f32e7eSjoerg         result->EvalData.stringVal[strLiteral.size()] = '\0';
406906f32e7eSjoerg         return result.release();
407006f32e7eSjoerg       }
407106f32e7eSjoerg     }
407206f32e7eSjoerg   } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
407306f32e7eSjoerg     DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
407406f32e7eSjoerg     ValueDecl *V = D->getDecl();
407506f32e7eSjoerg     if (V->getKind() == Decl::Function) {
407606f32e7eSjoerg       std::string strName = V->getNameAsString();
407706f32e7eSjoerg       result->EvalType = CXEval_Other;
407806f32e7eSjoerg       result->EvalData.stringVal = new char[strName.size() + 1];
407906f32e7eSjoerg       strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
408006f32e7eSjoerg       result->EvalData.stringVal[strName.size()] = '\0';
408106f32e7eSjoerg       return result.release();
408206f32e7eSjoerg     }
408306f32e7eSjoerg   }
408406f32e7eSjoerg 
408506f32e7eSjoerg   return nullptr;
408606f32e7eSjoerg }
408706f32e7eSjoerg 
evaluateDeclExpr(const Decl * D)408806f32e7eSjoerg static const Expr *evaluateDeclExpr(const Decl *D) {
408906f32e7eSjoerg   if (!D)
409006f32e7eSjoerg     return nullptr;
409106f32e7eSjoerg   if (auto *Var = dyn_cast<VarDecl>(D))
409206f32e7eSjoerg     return Var->getInit();
409306f32e7eSjoerg   else if (auto *Field = dyn_cast<FieldDecl>(D))
409406f32e7eSjoerg     return Field->getInClassInitializer();
409506f32e7eSjoerg   return nullptr;
409606f32e7eSjoerg }
409706f32e7eSjoerg 
evaluateCompoundStmtExpr(const CompoundStmt * CS)409806f32e7eSjoerg static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
409906f32e7eSjoerg   assert(CS && "invalid compound statement");
410006f32e7eSjoerg   for (auto *bodyIterator : CS->body()) {
410106f32e7eSjoerg     if (const auto *E = dyn_cast<Expr>(bodyIterator))
410206f32e7eSjoerg       return E;
410306f32e7eSjoerg   }
410406f32e7eSjoerg   return nullptr;
410506f32e7eSjoerg }
410606f32e7eSjoerg 
clang_Cursor_Evaluate(CXCursor C)410706f32e7eSjoerg CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
4108*13fbcb42Sjoerg   const Expr *E = nullptr;
4109*13fbcb42Sjoerg   if (clang_getCursorKind(C) == CXCursor_CompoundStmt)
4110*13fbcb42Sjoerg     E = evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)));
4111*13fbcb42Sjoerg   else if (clang_isDeclaration(C.kind))
4112*13fbcb42Sjoerg     E = evaluateDeclExpr(getCursorDecl(C));
4113*13fbcb42Sjoerg   else if (clang_isExpression(C.kind))
4114*13fbcb42Sjoerg     E = getCursorExpr(C);
4115*13fbcb42Sjoerg   if (E)
411606f32e7eSjoerg     return const_cast<CXEvalResult>(
411706f32e7eSjoerg         reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
411806f32e7eSjoerg   return nullptr;
411906f32e7eSjoerg }
412006f32e7eSjoerg 
clang_Cursor_hasAttrs(CXCursor C)412106f32e7eSjoerg unsigned clang_Cursor_hasAttrs(CXCursor C) {
412206f32e7eSjoerg   const Decl *D = getCursorDecl(C);
412306f32e7eSjoerg   if (!D) {
412406f32e7eSjoerg     return 0;
412506f32e7eSjoerg   }
412606f32e7eSjoerg 
412706f32e7eSjoerg   if (D->hasAttrs()) {
412806f32e7eSjoerg     return 1;
412906f32e7eSjoerg   }
413006f32e7eSjoerg 
413106f32e7eSjoerg   return 0;
413206f32e7eSjoerg }
clang_defaultSaveOptions(CXTranslationUnit TU)413306f32e7eSjoerg unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
413406f32e7eSjoerg   return CXSaveTranslationUnit_None;
413506f32e7eSjoerg }
413606f32e7eSjoerg 
clang_saveTranslationUnit_Impl(CXTranslationUnit TU,const char * FileName,unsigned options)413706f32e7eSjoerg static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
413806f32e7eSjoerg                                                   const char *FileName,
413906f32e7eSjoerg                                                   unsigned options) {
414006f32e7eSjoerg   CIndexer *CXXIdx = TU->CIdx;
414106f32e7eSjoerg   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
414206f32e7eSjoerg     setThreadBackgroundPriority();
414306f32e7eSjoerg 
414406f32e7eSjoerg   bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
414506f32e7eSjoerg   return hadError ? CXSaveError_Unknown : CXSaveError_None;
414606f32e7eSjoerg }
414706f32e7eSjoerg 
clang_saveTranslationUnit(CXTranslationUnit TU,const char * FileName,unsigned options)414806f32e7eSjoerg int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
414906f32e7eSjoerg                               unsigned options) {
4150*13fbcb42Sjoerg   LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
415106f32e7eSjoerg 
415206f32e7eSjoerg   if (isNotUsableTU(TU)) {
415306f32e7eSjoerg     LOG_BAD_TU(TU);
415406f32e7eSjoerg     return CXSaveError_InvalidTU;
415506f32e7eSjoerg   }
415606f32e7eSjoerg 
415706f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
415806f32e7eSjoerg   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
415906f32e7eSjoerg   if (!CXXUnit->hasSema())
416006f32e7eSjoerg     return CXSaveError_InvalidTU;
416106f32e7eSjoerg 
416206f32e7eSjoerg   CXSaveError result;
416306f32e7eSjoerg   auto SaveTranslationUnitImpl = [=, &result]() {
416406f32e7eSjoerg     result = clang_saveTranslationUnit_Impl(TU, FileName, options);
416506f32e7eSjoerg   };
416606f32e7eSjoerg 
416706f32e7eSjoerg   if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
416806f32e7eSjoerg     SaveTranslationUnitImpl();
416906f32e7eSjoerg 
417006f32e7eSjoerg     if (getenv("LIBCLANG_RESOURCE_USAGE"))
417106f32e7eSjoerg       PrintLibclangResourceUsage(TU);
417206f32e7eSjoerg 
417306f32e7eSjoerg     return result;
417406f32e7eSjoerg   }
417506f32e7eSjoerg 
417606f32e7eSjoerg   // We have an AST that has invalid nodes due to compiler errors.
417706f32e7eSjoerg   // Use a crash recovery thread for protection.
417806f32e7eSjoerg 
417906f32e7eSjoerg   llvm::CrashRecoveryContext CRC;
418006f32e7eSjoerg 
418106f32e7eSjoerg   if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
418206f32e7eSjoerg     fprintf(stderr, "libclang: crash detected during AST saving: {\n");
418306f32e7eSjoerg     fprintf(stderr, "  'filename' : '%s'\n", FileName);
418406f32e7eSjoerg     fprintf(stderr, "  'options' : %d,\n", options);
418506f32e7eSjoerg     fprintf(stderr, "}\n");
418606f32e7eSjoerg 
418706f32e7eSjoerg     return CXSaveError_Unknown;
418806f32e7eSjoerg 
418906f32e7eSjoerg   } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
419006f32e7eSjoerg     PrintLibclangResourceUsage(TU);
419106f32e7eSjoerg   }
419206f32e7eSjoerg 
419306f32e7eSjoerg   return result;
419406f32e7eSjoerg }
419506f32e7eSjoerg 
clang_disposeTranslationUnit(CXTranslationUnit CTUnit)419606f32e7eSjoerg void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
419706f32e7eSjoerg   if (CTUnit) {
419806f32e7eSjoerg     // If the translation unit has been marked as unsafe to free, just discard
419906f32e7eSjoerg     // it.
420006f32e7eSjoerg     ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
420106f32e7eSjoerg     if (Unit && Unit->isUnsafeToFree())
420206f32e7eSjoerg       return;
420306f32e7eSjoerg 
420406f32e7eSjoerg     delete cxtu::getASTUnit(CTUnit);
420506f32e7eSjoerg     delete CTUnit->StringPool;
420606f32e7eSjoerg     delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
420706f32e7eSjoerg     disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
420806f32e7eSjoerg     delete CTUnit->CommentToXML;
420906f32e7eSjoerg     delete CTUnit;
421006f32e7eSjoerg   }
421106f32e7eSjoerg }
421206f32e7eSjoerg 
clang_suspendTranslationUnit(CXTranslationUnit CTUnit)421306f32e7eSjoerg unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
421406f32e7eSjoerg   if (CTUnit) {
421506f32e7eSjoerg     ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
421606f32e7eSjoerg 
421706f32e7eSjoerg     if (Unit && Unit->isUnsafeToFree())
421806f32e7eSjoerg       return false;
421906f32e7eSjoerg 
422006f32e7eSjoerg     Unit->ResetForParse();
422106f32e7eSjoerg     return true;
422206f32e7eSjoerg   }
422306f32e7eSjoerg 
422406f32e7eSjoerg   return false;
422506f32e7eSjoerg }
422606f32e7eSjoerg 
clang_defaultReparseOptions(CXTranslationUnit TU)422706f32e7eSjoerg unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
422806f32e7eSjoerg   return CXReparse_None;
422906f32e7eSjoerg }
423006f32e7eSjoerg 
423106f32e7eSjoerg static CXErrorCode
clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,ArrayRef<CXUnsavedFile> unsaved_files,unsigned options)423206f32e7eSjoerg clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
423306f32e7eSjoerg                                   ArrayRef<CXUnsavedFile> unsaved_files,
423406f32e7eSjoerg                                   unsigned options) {
423506f32e7eSjoerg   // Check arguments.
423606f32e7eSjoerg   if (isNotUsableTU(TU)) {
423706f32e7eSjoerg     LOG_BAD_TU(TU);
423806f32e7eSjoerg     return CXError_InvalidArguments;
423906f32e7eSjoerg   }
424006f32e7eSjoerg 
424106f32e7eSjoerg   // Reset the associated diagnostics.
424206f32e7eSjoerg   delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
424306f32e7eSjoerg   TU->Diagnostics = nullptr;
424406f32e7eSjoerg 
424506f32e7eSjoerg   CIndexer *CXXIdx = TU->CIdx;
424606f32e7eSjoerg   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
424706f32e7eSjoerg     setThreadBackgroundPriority();
424806f32e7eSjoerg 
424906f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
425006f32e7eSjoerg   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
425106f32e7eSjoerg 
425206f32e7eSjoerg   std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
425306f32e7eSjoerg       new std::vector<ASTUnit::RemappedFile>());
425406f32e7eSjoerg 
425506f32e7eSjoerg   // Recover resources if we crash before exiting this function.
4256*13fbcb42Sjoerg   llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4257*13fbcb42Sjoerg       RemappedCleanup(RemappedFiles.get());
425806f32e7eSjoerg 
425906f32e7eSjoerg   for (auto &UF : unsaved_files) {
426006f32e7eSjoerg     std::unique_ptr<llvm::MemoryBuffer> MB =
426106f32e7eSjoerg         llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
426206f32e7eSjoerg     RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
426306f32e7eSjoerg   }
426406f32e7eSjoerg 
426506f32e7eSjoerg   if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
426606f32e7eSjoerg                         *RemappedFiles.get()))
426706f32e7eSjoerg     return CXError_Success;
426806f32e7eSjoerg   if (isASTReadError(CXXUnit))
426906f32e7eSjoerg     return CXError_ASTReadError;
427006f32e7eSjoerg   return CXError_Failure;
427106f32e7eSjoerg }
427206f32e7eSjoerg 
clang_reparseTranslationUnit(CXTranslationUnit TU,unsigned num_unsaved_files,struct CXUnsavedFile * unsaved_files,unsigned options)427306f32e7eSjoerg int clang_reparseTranslationUnit(CXTranslationUnit TU,
427406f32e7eSjoerg                                  unsigned num_unsaved_files,
427506f32e7eSjoerg                                  struct CXUnsavedFile *unsaved_files,
427606f32e7eSjoerg                                  unsigned options) {
4277*13fbcb42Sjoerg   LOG_FUNC_SECTION { *Log << TU; }
427806f32e7eSjoerg 
427906f32e7eSjoerg   if (num_unsaved_files && !unsaved_files)
428006f32e7eSjoerg     return CXError_InvalidArguments;
428106f32e7eSjoerg 
428206f32e7eSjoerg   CXErrorCode result;
428306f32e7eSjoerg   auto ReparseTranslationUnitImpl = [=, &result]() {
428406f32e7eSjoerg     result = clang_reparseTranslationUnit_Impl(
428506f32e7eSjoerg         TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
428606f32e7eSjoerg   };
428706f32e7eSjoerg 
428806f32e7eSjoerg   llvm::CrashRecoveryContext CRC;
428906f32e7eSjoerg 
429006f32e7eSjoerg   if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
429106f32e7eSjoerg     fprintf(stderr, "libclang: crash detected during reparsing\n");
429206f32e7eSjoerg     cxtu::getASTUnit(TU)->setUnsafeToFree(true);
429306f32e7eSjoerg     return CXError_Crashed;
429406f32e7eSjoerg   } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
429506f32e7eSjoerg     PrintLibclangResourceUsage(TU);
429606f32e7eSjoerg 
429706f32e7eSjoerg   return result;
429806f32e7eSjoerg }
429906f32e7eSjoerg 
clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit)430006f32e7eSjoerg CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
430106f32e7eSjoerg   if (isNotUsableTU(CTUnit)) {
430206f32e7eSjoerg     LOG_BAD_TU(CTUnit);
430306f32e7eSjoerg     return cxstring::createEmpty();
430406f32e7eSjoerg   }
430506f32e7eSjoerg 
430606f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
430706f32e7eSjoerg   return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
430806f32e7eSjoerg }
430906f32e7eSjoerg 
clang_getTranslationUnitCursor(CXTranslationUnit TU)431006f32e7eSjoerg CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
431106f32e7eSjoerg   if (isNotUsableTU(TU)) {
431206f32e7eSjoerg     LOG_BAD_TU(TU);
431306f32e7eSjoerg     return clang_getNullCursor();
431406f32e7eSjoerg   }
431506f32e7eSjoerg 
431606f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
431706f32e7eSjoerg   return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
431806f32e7eSjoerg }
431906f32e7eSjoerg 
clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit)432006f32e7eSjoerg CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
432106f32e7eSjoerg   if (isNotUsableTU(CTUnit)) {
432206f32e7eSjoerg     LOG_BAD_TU(CTUnit);
432306f32e7eSjoerg     return nullptr;
432406f32e7eSjoerg   }
432506f32e7eSjoerg 
432606f32e7eSjoerg   CXTargetInfoImpl *impl = new CXTargetInfoImpl();
432706f32e7eSjoerg   impl->TranslationUnit = CTUnit;
432806f32e7eSjoerg   return impl;
432906f32e7eSjoerg }
433006f32e7eSjoerg 
clang_TargetInfo_getTriple(CXTargetInfo TargetInfo)433106f32e7eSjoerg CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
433206f32e7eSjoerg   if (!TargetInfo)
433306f32e7eSjoerg     return cxstring::createEmpty();
433406f32e7eSjoerg 
433506f32e7eSjoerg   CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
433606f32e7eSjoerg   assert(!isNotUsableTU(CTUnit) &&
433706f32e7eSjoerg          "Unexpected unusable translation unit in TargetInfo");
433806f32e7eSjoerg 
433906f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
434006f32e7eSjoerg   std::string Triple =
434106f32e7eSjoerg       CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
434206f32e7eSjoerg   return cxstring::createDup(Triple);
434306f32e7eSjoerg }
434406f32e7eSjoerg 
clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo)434506f32e7eSjoerg int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
434606f32e7eSjoerg   if (!TargetInfo)
434706f32e7eSjoerg     return -1;
434806f32e7eSjoerg 
434906f32e7eSjoerg   CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
435006f32e7eSjoerg   assert(!isNotUsableTU(CTUnit) &&
435106f32e7eSjoerg          "Unexpected unusable translation unit in TargetInfo");
435206f32e7eSjoerg 
435306f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
435406f32e7eSjoerg   return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
435506f32e7eSjoerg }
435606f32e7eSjoerg 
clang_TargetInfo_dispose(CXTargetInfo TargetInfo)435706f32e7eSjoerg void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
435806f32e7eSjoerg   if (!TargetInfo)
435906f32e7eSjoerg     return;
436006f32e7eSjoerg 
436106f32e7eSjoerg   delete TargetInfo;
436206f32e7eSjoerg }
436306f32e7eSjoerg 
436406f32e7eSjoerg //===----------------------------------------------------------------------===//
436506f32e7eSjoerg // CXFile Operations.
436606f32e7eSjoerg //===----------------------------------------------------------------------===//
436706f32e7eSjoerg 
clang_getFileName(CXFile SFile)436806f32e7eSjoerg CXString clang_getFileName(CXFile SFile) {
436906f32e7eSjoerg   if (!SFile)
437006f32e7eSjoerg     return cxstring::createNull();
437106f32e7eSjoerg 
437206f32e7eSjoerg   FileEntry *FEnt = static_cast<FileEntry *>(SFile);
437306f32e7eSjoerg   return cxstring::createRef(FEnt->getName());
437406f32e7eSjoerg }
437506f32e7eSjoerg 
clang_getFileTime(CXFile SFile)437606f32e7eSjoerg time_t clang_getFileTime(CXFile SFile) {
437706f32e7eSjoerg   if (!SFile)
437806f32e7eSjoerg     return 0;
437906f32e7eSjoerg 
438006f32e7eSjoerg   FileEntry *FEnt = static_cast<FileEntry *>(SFile);
438106f32e7eSjoerg   return FEnt->getModificationTime();
438206f32e7eSjoerg }
438306f32e7eSjoerg 
clang_getFile(CXTranslationUnit TU,const char * file_name)438406f32e7eSjoerg CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
438506f32e7eSjoerg   if (isNotUsableTU(TU)) {
438606f32e7eSjoerg     LOG_BAD_TU(TU);
438706f32e7eSjoerg     return nullptr;
438806f32e7eSjoerg   }
438906f32e7eSjoerg 
439006f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
439106f32e7eSjoerg 
439206f32e7eSjoerg   FileManager &FMgr = CXXUnit->getFileManager();
439306f32e7eSjoerg   auto File = FMgr.getFile(file_name);
439406f32e7eSjoerg   if (!File)
439506f32e7eSjoerg     return nullptr;
439606f32e7eSjoerg   return const_cast<FileEntry *>(*File);
439706f32e7eSjoerg }
439806f32e7eSjoerg 
clang_getFileContents(CXTranslationUnit TU,CXFile file,size_t * size)439906f32e7eSjoerg const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
440006f32e7eSjoerg                                   size_t *size) {
440106f32e7eSjoerg   if (isNotUsableTU(TU)) {
440206f32e7eSjoerg     LOG_BAD_TU(TU);
440306f32e7eSjoerg     return nullptr;
440406f32e7eSjoerg   }
440506f32e7eSjoerg 
440606f32e7eSjoerg   const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
440706f32e7eSjoerg   FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
4408*13fbcb42Sjoerg   llvm::Optional<llvm::MemoryBufferRef> buf = SM.getBufferOrNone(fid);
4409*13fbcb42Sjoerg   if (!buf) {
441006f32e7eSjoerg     if (size)
441106f32e7eSjoerg       *size = 0;
441206f32e7eSjoerg     return nullptr;
441306f32e7eSjoerg   }
441406f32e7eSjoerg   if (size)
441506f32e7eSjoerg     *size = buf->getBufferSize();
441606f32e7eSjoerg   return buf->getBufferStart();
441706f32e7eSjoerg }
441806f32e7eSjoerg 
clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,CXFile file)4419*13fbcb42Sjoerg unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
442006f32e7eSjoerg   if (isNotUsableTU(TU)) {
442106f32e7eSjoerg     LOG_BAD_TU(TU);
442206f32e7eSjoerg     return 0;
442306f32e7eSjoerg   }
442406f32e7eSjoerg 
442506f32e7eSjoerg   if (!file)
442606f32e7eSjoerg     return 0;
442706f32e7eSjoerg 
442806f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
442906f32e7eSjoerg   FileEntry *FEnt = static_cast<FileEntry *>(file);
4430*13fbcb42Sjoerg   return CXXUnit->getPreprocessor()
4431*13fbcb42Sjoerg       .getHeaderSearchInfo()
443206f32e7eSjoerg       .isFileMultipleIncludeGuarded(FEnt);
443306f32e7eSjoerg }
443406f32e7eSjoerg 
clang_getFileUniqueID(CXFile file,CXFileUniqueID * outID)443506f32e7eSjoerg int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
443606f32e7eSjoerg   if (!file || !outID)
443706f32e7eSjoerg     return 1;
443806f32e7eSjoerg 
443906f32e7eSjoerg   FileEntry *FEnt = static_cast<FileEntry *>(file);
444006f32e7eSjoerg   const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
444106f32e7eSjoerg   outID->data[0] = ID.getDevice();
444206f32e7eSjoerg   outID->data[1] = ID.getFile();
444306f32e7eSjoerg   outID->data[2] = FEnt->getModificationTime();
444406f32e7eSjoerg   return 0;
444506f32e7eSjoerg }
444606f32e7eSjoerg 
clang_File_isEqual(CXFile file1,CXFile file2)444706f32e7eSjoerg int clang_File_isEqual(CXFile file1, CXFile file2) {
444806f32e7eSjoerg   if (file1 == file2)
444906f32e7eSjoerg     return true;
445006f32e7eSjoerg 
445106f32e7eSjoerg   if (!file1 || !file2)
445206f32e7eSjoerg     return false;
445306f32e7eSjoerg 
445406f32e7eSjoerg   FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
445506f32e7eSjoerg   FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
445606f32e7eSjoerg   return FEnt1->getUniqueID() == FEnt2->getUniqueID();
445706f32e7eSjoerg }
445806f32e7eSjoerg 
clang_File_tryGetRealPathName(CXFile SFile)445906f32e7eSjoerg CXString clang_File_tryGetRealPathName(CXFile SFile) {
446006f32e7eSjoerg   if (!SFile)
446106f32e7eSjoerg     return cxstring::createNull();
446206f32e7eSjoerg 
446306f32e7eSjoerg   FileEntry *FEnt = static_cast<FileEntry *>(SFile);
446406f32e7eSjoerg   return cxstring::createRef(FEnt->tryGetRealPathName());
446506f32e7eSjoerg }
446606f32e7eSjoerg 
446706f32e7eSjoerg //===----------------------------------------------------------------------===//
446806f32e7eSjoerg // CXCursor Operations.
446906f32e7eSjoerg //===----------------------------------------------------------------------===//
447006f32e7eSjoerg 
getDeclFromExpr(const Stmt * E)447106f32e7eSjoerg static const Decl *getDeclFromExpr(const Stmt *E) {
447206f32e7eSjoerg   if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
447306f32e7eSjoerg     return getDeclFromExpr(CE->getSubExpr());
447406f32e7eSjoerg 
447506f32e7eSjoerg   if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
447606f32e7eSjoerg     return RefExpr->getDecl();
447706f32e7eSjoerg   if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
447806f32e7eSjoerg     return ME->getMemberDecl();
447906f32e7eSjoerg   if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
448006f32e7eSjoerg     return RE->getDecl();
448106f32e7eSjoerg   if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
448206f32e7eSjoerg     if (PRE->isExplicitProperty())
448306f32e7eSjoerg       return PRE->getExplicitProperty();
448406f32e7eSjoerg     // It could be messaging both getter and setter as in:
448506f32e7eSjoerg     // ++myobj.myprop;
448606f32e7eSjoerg     // in which case prefer to associate the setter since it is less obvious
448706f32e7eSjoerg     // from inspecting the source that the setter is going to get called.
448806f32e7eSjoerg     if (PRE->isMessagingSetter())
448906f32e7eSjoerg       return PRE->getImplicitPropertySetter();
449006f32e7eSjoerg     return PRE->getImplicitPropertyGetter();
449106f32e7eSjoerg   }
449206f32e7eSjoerg   if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
449306f32e7eSjoerg     return getDeclFromExpr(POE->getSyntacticForm());
449406f32e7eSjoerg   if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
449506f32e7eSjoerg     if (Expr *Src = OVE->getSourceExpr())
449606f32e7eSjoerg       return getDeclFromExpr(Src);
449706f32e7eSjoerg 
449806f32e7eSjoerg   if (const CallExpr *CE = dyn_cast<CallExpr>(E))
449906f32e7eSjoerg     return getDeclFromExpr(CE->getCallee());
450006f32e7eSjoerg   if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
450106f32e7eSjoerg     if (!CE->isElidable())
450206f32e7eSjoerg       return CE->getConstructor();
450306f32e7eSjoerg   if (const CXXInheritedCtorInitExpr *CE =
450406f32e7eSjoerg           dyn_cast<CXXInheritedCtorInitExpr>(E))
450506f32e7eSjoerg     return CE->getConstructor();
450606f32e7eSjoerg   if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
450706f32e7eSjoerg     return OME->getMethodDecl();
450806f32e7eSjoerg 
450906f32e7eSjoerg   if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
451006f32e7eSjoerg     return PE->getProtocol();
4511*13fbcb42Sjoerg   if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4512*13fbcb42Sjoerg           dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
451306f32e7eSjoerg     return NTTP->getParameterPack();
451406f32e7eSjoerg   if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
451506f32e7eSjoerg     if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
451606f32e7eSjoerg         isa<ParmVarDecl>(SizeOfPack->getPack()))
451706f32e7eSjoerg       return SizeOfPack->getPack();
451806f32e7eSjoerg 
451906f32e7eSjoerg   return nullptr;
452006f32e7eSjoerg }
452106f32e7eSjoerg 
getLocationFromExpr(const Expr * E)452206f32e7eSjoerg static SourceLocation getLocationFromExpr(const Expr *E) {
452306f32e7eSjoerg   if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
452406f32e7eSjoerg     return getLocationFromExpr(CE->getSubExpr());
452506f32e7eSjoerg 
452606f32e7eSjoerg   if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
452706f32e7eSjoerg     return /*FIXME:*/ Msg->getLeftLoc();
452806f32e7eSjoerg   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
452906f32e7eSjoerg     return DRE->getLocation();
453006f32e7eSjoerg   if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
453106f32e7eSjoerg     return Member->getMemberLoc();
453206f32e7eSjoerg   if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
453306f32e7eSjoerg     return Ivar->getLocation();
453406f32e7eSjoerg   if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
453506f32e7eSjoerg     return SizeOfPack->getPackLoc();
453606f32e7eSjoerg   if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
453706f32e7eSjoerg     return PropRef->getLocation();
453806f32e7eSjoerg 
453906f32e7eSjoerg   return E->getBeginLoc();
454006f32e7eSjoerg }
454106f32e7eSjoerg 
454206f32e7eSjoerg extern "C" {
454306f32e7eSjoerg 
clang_visitChildren(CXCursor parent,CXCursorVisitor visitor,CXClientData client_data)4544*13fbcb42Sjoerg unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
454506f32e7eSjoerg                              CXClientData client_data) {
454606f32e7eSjoerg   CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
454706f32e7eSjoerg                           /*VisitPreprocessorLast=*/false);
454806f32e7eSjoerg   return CursorVis.VisitChildren(parent);
454906f32e7eSjoerg }
455006f32e7eSjoerg 
455106f32e7eSjoerg #ifndef __has_feature
455206f32e7eSjoerg #define __has_feature(x) 0
455306f32e7eSjoerg #endif
455406f32e7eSjoerg #if __has_feature(blocks)
4555*13fbcb42Sjoerg typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4556*13fbcb42Sjoerg                                                         CXCursor parent);
455706f32e7eSjoerg 
455806f32e7eSjoerg static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
455906f32e7eSjoerg                                               CXClientData client_data) {
456006f32e7eSjoerg   CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
456106f32e7eSjoerg   return block(cursor, parent);
456206f32e7eSjoerg }
456306f32e7eSjoerg #else
456406f32e7eSjoerg // If we are compiled with a compiler that doesn't have native blocks support,
456506f32e7eSjoerg // define and call the block manually, so the
4566*13fbcb42Sjoerg typedef struct _CXChildVisitResult {
456706f32e7eSjoerg   void *isa;
456806f32e7eSjoerg   int flags;
456906f32e7eSjoerg   int reserved;
457006f32e7eSjoerg   enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
457106f32e7eSjoerg                                     CXCursor);
457206f32e7eSjoerg } * CXCursorVisitorBlock;
457306f32e7eSjoerg 
457406f32e7eSjoerg static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
457506f32e7eSjoerg                                               CXClientData client_data) {
457606f32e7eSjoerg   CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
457706f32e7eSjoerg   return block->invoke(block, cursor, parent);
457806f32e7eSjoerg }
457906f32e7eSjoerg #endif
458006f32e7eSjoerg 
458106f32e7eSjoerg unsigned clang_visitChildrenWithBlock(CXCursor parent,
458206f32e7eSjoerg                                       CXCursorVisitorBlock block) {
458306f32e7eSjoerg   return clang_visitChildren(parent, visitWithBlock, block);
458406f32e7eSjoerg }
458506f32e7eSjoerg 
458606f32e7eSjoerg static CXString getDeclSpelling(const Decl *D) {
458706f32e7eSjoerg   if (!D)
458806f32e7eSjoerg     return cxstring::createEmpty();
458906f32e7eSjoerg 
459006f32e7eSjoerg   const NamedDecl *ND = dyn_cast<NamedDecl>(D);
459106f32e7eSjoerg   if (!ND) {
459206f32e7eSjoerg     if (const ObjCPropertyImplDecl *PropImpl =
459306f32e7eSjoerg             dyn_cast<ObjCPropertyImplDecl>(D))
459406f32e7eSjoerg       if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
459506f32e7eSjoerg         return cxstring::createDup(Property->getIdentifier()->getName());
459606f32e7eSjoerg 
459706f32e7eSjoerg     if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
459806f32e7eSjoerg       if (Module *Mod = ImportD->getImportedModule())
459906f32e7eSjoerg         return cxstring::createDup(Mod->getFullModuleName());
460006f32e7eSjoerg 
460106f32e7eSjoerg     return cxstring::createEmpty();
460206f32e7eSjoerg   }
460306f32e7eSjoerg 
460406f32e7eSjoerg   if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
460506f32e7eSjoerg     return cxstring::createDup(OMD->getSelector().getAsString());
460606f32e7eSjoerg 
460706f32e7eSjoerg   if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
460806f32e7eSjoerg     // No, this isn't the same as the code below. getIdentifier() is non-virtual
460906f32e7eSjoerg     // and returns different names. NamedDecl returns the class name and
461006f32e7eSjoerg     // ObjCCategoryImplDecl returns the category name.
461106f32e7eSjoerg     return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
461206f32e7eSjoerg 
461306f32e7eSjoerg   if (isa<UsingDirectiveDecl>(D))
461406f32e7eSjoerg     return cxstring::createEmpty();
461506f32e7eSjoerg 
461606f32e7eSjoerg   SmallString<1024> S;
461706f32e7eSjoerg   llvm::raw_svector_ostream os(S);
461806f32e7eSjoerg   ND->printName(os);
461906f32e7eSjoerg 
462006f32e7eSjoerg   return cxstring::createDup(os.str());
462106f32e7eSjoerg }
462206f32e7eSjoerg 
462306f32e7eSjoerg CXString clang_getCursorSpelling(CXCursor C) {
462406f32e7eSjoerg   if (clang_isTranslationUnit(C.kind))
462506f32e7eSjoerg     return clang_getTranslationUnitSpelling(getCursorTU(C));
462606f32e7eSjoerg 
462706f32e7eSjoerg   if (clang_isReference(C.kind)) {
462806f32e7eSjoerg     switch (C.kind) {
462906f32e7eSjoerg     case CXCursor_ObjCSuperClassRef: {
463006f32e7eSjoerg       const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
463106f32e7eSjoerg       return cxstring::createRef(Super->getIdentifier()->getNameStart());
463206f32e7eSjoerg     }
463306f32e7eSjoerg     case CXCursor_ObjCClassRef: {
463406f32e7eSjoerg       const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
463506f32e7eSjoerg       return cxstring::createRef(Class->getIdentifier()->getNameStart());
463606f32e7eSjoerg     }
463706f32e7eSjoerg     case CXCursor_ObjCProtocolRef: {
463806f32e7eSjoerg       const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
463906f32e7eSjoerg       assert(OID && "getCursorSpelling(): Missing protocol decl");
464006f32e7eSjoerg       return cxstring::createRef(OID->getIdentifier()->getNameStart());
464106f32e7eSjoerg     }
464206f32e7eSjoerg     case CXCursor_CXXBaseSpecifier: {
464306f32e7eSjoerg       const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
464406f32e7eSjoerg       return cxstring::createDup(B->getType().getAsString());
464506f32e7eSjoerg     }
464606f32e7eSjoerg     case CXCursor_TypeRef: {
464706f32e7eSjoerg       const TypeDecl *Type = getCursorTypeRef(C).first;
464806f32e7eSjoerg       assert(Type && "Missing type decl");
464906f32e7eSjoerg 
4650*13fbcb42Sjoerg       return cxstring::createDup(
4651*13fbcb42Sjoerg           getCursorContext(C).getTypeDeclType(Type).getAsString());
465206f32e7eSjoerg     }
465306f32e7eSjoerg     case CXCursor_TemplateRef: {
465406f32e7eSjoerg       const TemplateDecl *Template = getCursorTemplateRef(C).first;
465506f32e7eSjoerg       assert(Template && "Missing template decl");
465606f32e7eSjoerg 
465706f32e7eSjoerg       return cxstring::createDup(Template->getNameAsString());
465806f32e7eSjoerg     }
465906f32e7eSjoerg 
466006f32e7eSjoerg     case CXCursor_NamespaceRef: {
466106f32e7eSjoerg       const NamedDecl *NS = getCursorNamespaceRef(C).first;
466206f32e7eSjoerg       assert(NS && "Missing namespace decl");
466306f32e7eSjoerg 
466406f32e7eSjoerg       return cxstring::createDup(NS->getNameAsString());
466506f32e7eSjoerg     }
466606f32e7eSjoerg 
466706f32e7eSjoerg     case CXCursor_MemberRef: {
466806f32e7eSjoerg       const FieldDecl *Field = getCursorMemberRef(C).first;
466906f32e7eSjoerg       assert(Field && "Missing member decl");
467006f32e7eSjoerg 
467106f32e7eSjoerg       return cxstring::createDup(Field->getNameAsString());
467206f32e7eSjoerg     }
467306f32e7eSjoerg 
467406f32e7eSjoerg     case CXCursor_LabelRef: {
467506f32e7eSjoerg       const LabelStmt *Label = getCursorLabelRef(C).first;
467606f32e7eSjoerg       assert(Label && "Missing label");
467706f32e7eSjoerg 
467806f32e7eSjoerg       return cxstring::createRef(Label->getName());
467906f32e7eSjoerg     }
468006f32e7eSjoerg 
468106f32e7eSjoerg     case CXCursor_OverloadedDeclRef: {
468206f32e7eSjoerg       OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
468306f32e7eSjoerg       if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
468406f32e7eSjoerg         if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
468506f32e7eSjoerg           return cxstring::createDup(ND->getNameAsString());
468606f32e7eSjoerg         return cxstring::createEmpty();
468706f32e7eSjoerg       }
468806f32e7eSjoerg       if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
468906f32e7eSjoerg         return cxstring::createDup(E->getName().getAsString());
4690*13fbcb42Sjoerg       OverloadedTemplateStorage *Ovl =
4691*13fbcb42Sjoerg           Storage.get<OverloadedTemplateStorage *>();
469206f32e7eSjoerg       if (Ovl->size() == 0)
469306f32e7eSjoerg         return cxstring::createEmpty();
469406f32e7eSjoerg       return cxstring::createDup((*Ovl->begin())->getNameAsString());
469506f32e7eSjoerg     }
469606f32e7eSjoerg 
469706f32e7eSjoerg     case CXCursor_VariableRef: {
469806f32e7eSjoerg       const VarDecl *Var = getCursorVariableRef(C).first;
469906f32e7eSjoerg       assert(Var && "Missing variable decl");
470006f32e7eSjoerg 
470106f32e7eSjoerg       return cxstring::createDup(Var->getNameAsString());
470206f32e7eSjoerg     }
470306f32e7eSjoerg 
470406f32e7eSjoerg     default:
470506f32e7eSjoerg       return cxstring::createRef("<not implemented>");
470606f32e7eSjoerg     }
470706f32e7eSjoerg   }
470806f32e7eSjoerg 
470906f32e7eSjoerg   if (clang_isExpression(C.kind)) {
471006f32e7eSjoerg     const Expr *E = getCursorExpr(C);
471106f32e7eSjoerg 
471206f32e7eSjoerg     if (C.kind == CXCursor_ObjCStringLiteral ||
471306f32e7eSjoerg         C.kind == CXCursor_StringLiteral) {
471406f32e7eSjoerg       const StringLiteral *SLit;
471506f32e7eSjoerg       if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
471606f32e7eSjoerg         SLit = OSL->getString();
471706f32e7eSjoerg       } else {
471806f32e7eSjoerg         SLit = cast<StringLiteral>(E);
471906f32e7eSjoerg       }
472006f32e7eSjoerg       SmallString<256> Buf;
472106f32e7eSjoerg       llvm::raw_svector_ostream OS(Buf);
472206f32e7eSjoerg       SLit->outputString(OS);
472306f32e7eSjoerg       return cxstring::createDup(OS.str());
472406f32e7eSjoerg     }
472506f32e7eSjoerg 
472606f32e7eSjoerg     const Decl *D = getDeclFromExpr(getCursorExpr(C));
472706f32e7eSjoerg     if (D)
472806f32e7eSjoerg       return getDeclSpelling(D);
472906f32e7eSjoerg     return cxstring::createEmpty();
473006f32e7eSjoerg   }
473106f32e7eSjoerg 
473206f32e7eSjoerg   if (clang_isStatement(C.kind)) {
473306f32e7eSjoerg     const Stmt *S = getCursorStmt(C);
473406f32e7eSjoerg     if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
473506f32e7eSjoerg       return cxstring::createRef(Label->getName());
473606f32e7eSjoerg 
473706f32e7eSjoerg     return cxstring::createEmpty();
473806f32e7eSjoerg   }
473906f32e7eSjoerg 
474006f32e7eSjoerg   if (C.kind == CXCursor_MacroExpansion)
4741*13fbcb42Sjoerg     return cxstring::createRef(
4742*13fbcb42Sjoerg         getCursorMacroExpansion(C).getName()->getNameStart());
474306f32e7eSjoerg 
474406f32e7eSjoerg   if (C.kind == CXCursor_MacroDefinition)
4745*13fbcb42Sjoerg     return cxstring::createRef(
4746*13fbcb42Sjoerg         getCursorMacroDefinition(C)->getName()->getNameStart());
474706f32e7eSjoerg 
474806f32e7eSjoerg   if (C.kind == CXCursor_InclusionDirective)
474906f32e7eSjoerg     return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
475006f32e7eSjoerg 
475106f32e7eSjoerg   if (clang_isDeclaration(C.kind))
475206f32e7eSjoerg     return getDeclSpelling(getCursorDecl(C));
475306f32e7eSjoerg 
475406f32e7eSjoerg   if (C.kind == CXCursor_AnnotateAttr) {
475506f32e7eSjoerg     const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
475606f32e7eSjoerg     return cxstring::createDup(AA->getAnnotation());
475706f32e7eSjoerg   }
475806f32e7eSjoerg 
475906f32e7eSjoerg   if (C.kind == CXCursor_AsmLabelAttr) {
476006f32e7eSjoerg     const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
476106f32e7eSjoerg     return cxstring::createDup(AA->getLabel());
476206f32e7eSjoerg   }
476306f32e7eSjoerg 
476406f32e7eSjoerg   if (C.kind == CXCursor_PackedAttr) {
476506f32e7eSjoerg     return cxstring::createRef("packed");
476606f32e7eSjoerg   }
476706f32e7eSjoerg 
476806f32e7eSjoerg   if (C.kind == CXCursor_VisibilityAttr) {
476906f32e7eSjoerg     const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
477006f32e7eSjoerg     switch (AA->getVisibility()) {
477106f32e7eSjoerg     case VisibilityAttr::VisibilityType::Default:
477206f32e7eSjoerg       return cxstring::createRef("default");
477306f32e7eSjoerg     case VisibilityAttr::VisibilityType::Hidden:
477406f32e7eSjoerg       return cxstring::createRef("hidden");
477506f32e7eSjoerg     case VisibilityAttr::VisibilityType::Protected:
477606f32e7eSjoerg       return cxstring::createRef("protected");
477706f32e7eSjoerg     }
477806f32e7eSjoerg     llvm_unreachable("unknown visibility type");
477906f32e7eSjoerg   }
478006f32e7eSjoerg 
478106f32e7eSjoerg   return cxstring::createEmpty();
478206f32e7eSjoerg }
478306f32e7eSjoerg 
4784*13fbcb42Sjoerg CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
478506f32e7eSjoerg                                                 unsigned options) {
478606f32e7eSjoerg   if (clang_Cursor_isNull(C))
478706f32e7eSjoerg     return clang_getNullRange();
478806f32e7eSjoerg 
478906f32e7eSjoerg   ASTContext &Ctx = getCursorContext(C);
479006f32e7eSjoerg 
479106f32e7eSjoerg   if (clang_isStatement(C.kind)) {
479206f32e7eSjoerg     const Stmt *S = getCursorStmt(C);
479306f32e7eSjoerg     if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
479406f32e7eSjoerg       if (pieceIndex > 0)
479506f32e7eSjoerg         return clang_getNullRange();
479606f32e7eSjoerg       return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
479706f32e7eSjoerg     }
479806f32e7eSjoerg 
479906f32e7eSjoerg     return clang_getNullRange();
480006f32e7eSjoerg   }
480106f32e7eSjoerg 
480206f32e7eSjoerg   if (C.kind == CXCursor_ObjCMessageExpr) {
4803*13fbcb42Sjoerg     if (const ObjCMessageExpr *ME =
4804*13fbcb42Sjoerg             dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
480506f32e7eSjoerg       if (pieceIndex >= ME->getNumSelectorLocs())
480606f32e7eSjoerg         return clang_getNullRange();
480706f32e7eSjoerg       return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
480806f32e7eSjoerg     }
480906f32e7eSjoerg   }
481006f32e7eSjoerg 
481106f32e7eSjoerg   if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
481206f32e7eSjoerg       C.kind == CXCursor_ObjCClassMethodDecl) {
4813*13fbcb42Sjoerg     if (const ObjCMethodDecl *MD =
4814*13fbcb42Sjoerg             dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
481506f32e7eSjoerg       if (pieceIndex >= MD->getNumSelectorLocs())
481606f32e7eSjoerg         return clang_getNullRange();
481706f32e7eSjoerg       return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
481806f32e7eSjoerg     }
481906f32e7eSjoerg   }
482006f32e7eSjoerg 
482106f32e7eSjoerg   if (C.kind == CXCursor_ObjCCategoryDecl ||
482206f32e7eSjoerg       C.kind == CXCursor_ObjCCategoryImplDecl) {
482306f32e7eSjoerg     if (pieceIndex > 0)
482406f32e7eSjoerg       return clang_getNullRange();
4825*13fbcb42Sjoerg     if (const ObjCCategoryDecl *CD =
4826*13fbcb42Sjoerg             dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
482706f32e7eSjoerg       return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
4828*13fbcb42Sjoerg     if (const ObjCCategoryImplDecl *CID =
4829*13fbcb42Sjoerg             dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
483006f32e7eSjoerg       return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
483106f32e7eSjoerg   }
483206f32e7eSjoerg 
483306f32e7eSjoerg   if (C.kind == CXCursor_ModuleImportDecl) {
483406f32e7eSjoerg     if (pieceIndex > 0)
483506f32e7eSjoerg       return clang_getNullRange();
483606f32e7eSjoerg     if (const ImportDecl *ImportD =
483706f32e7eSjoerg             dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
483806f32e7eSjoerg       ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
483906f32e7eSjoerg       if (!Locs.empty())
4840*13fbcb42Sjoerg         return cxloc::translateSourceRange(
4841*13fbcb42Sjoerg             Ctx, SourceRange(Locs.front(), Locs.back()));
484206f32e7eSjoerg     }
484306f32e7eSjoerg     return clang_getNullRange();
484406f32e7eSjoerg   }
484506f32e7eSjoerg 
484606f32e7eSjoerg   if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
484706f32e7eSjoerg       C.kind == CXCursor_ConversionFunction ||
484806f32e7eSjoerg       C.kind == CXCursor_FunctionDecl) {
484906f32e7eSjoerg     if (pieceIndex > 0)
485006f32e7eSjoerg       return clang_getNullRange();
485106f32e7eSjoerg     if (const FunctionDecl *FD =
485206f32e7eSjoerg             dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
485306f32e7eSjoerg       DeclarationNameInfo FunctionName = FD->getNameInfo();
485406f32e7eSjoerg       return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
485506f32e7eSjoerg     }
485606f32e7eSjoerg     return clang_getNullRange();
485706f32e7eSjoerg   }
485806f32e7eSjoerg 
485906f32e7eSjoerg   // FIXME: A CXCursor_InclusionDirective should give the location of the
486006f32e7eSjoerg   // filename, but we don't keep track of this.
486106f32e7eSjoerg 
486206f32e7eSjoerg   // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
486306f32e7eSjoerg   // but we don't keep track of this.
486406f32e7eSjoerg 
486506f32e7eSjoerg   // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
486606f32e7eSjoerg   // but we don't keep track of this.
486706f32e7eSjoerg 
486806f32e7eSjoerg   // Default handling, give the location of the cursor.
486906f32e7eSjoerg 
487006f32e7eSjoerg   if (pieceIndex > 0)
487106f32e7eSjoerg     return clang_getNullRange();
487206f32e7eSjoerg 
487306f32e7eSjoerg   CXSourceLocation CXLoc = clang_getCursorLocation(C);
487406f32e7eSjoerg   SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
487506f32e7eSjoerg   return cxloc::translateSourceRange(Ctx, Loc);
487606f32e7eSjoerg }
487706f32e7eSjoerg 
487806f32e7eSjoerg CXString clang_Cursor_getMangling(CXCursor C) {
487906f32e7eSjoerg   if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
488006f32e7eSjoerg     return cxstring::createEmpty();
488106f32e7eSjoerg 
488206f32e7eSjoerg   // Mangling only works for functions and variables.
488306f32e7eSjoerg   const Decl *D = getCursorDecl(C);
488406f32e7eSjoerg   if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
488506f32e7eSjoerg     return cxstring::createEmpty();
488606f32e7eSjoerg 
488706f32e7eSjoerg   ASTContext &Ctx = D->getASTContext();
488806f32e7eSjoerg   ASTNameGenerator ASTNameGen(Ctx);
488906f32e7eSjoerg   return cxstring::createDup(ASTNameGen.getName(D));
489006f32e7eSjoerg }
489106f32e7eSjoerg 
489206f32e7eSjoerg CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
489306f32e7eSjoerg   if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
489406f32e7eSjoerg     return nullptr;
489506f32e7eSjoerg 
489606f32e7eSjoerg   const Decl *D = getCursorDecl(C);
489706f32e7eSjoerg   if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
489806f32e7eSjoerg     return nullptr;
489906f32e7eSjoerg 
490006f32e7eSjoerg   ASTContext &Ctx = D->getASTContext();
490106f32e7eSjoerg   ASTNameGenerator ASTNameGen(Ctx);
490206f32e7eSjoerg   std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
490306f32e7eSjoerg   return cxstring::createSet(Manglings);
490406f32e7eSjoerg }
490506f32e7eSjoerg 
490606f32e7eSjoerg CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
490706f32e7eSjoerg   if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
490806f32e7eSjoerg     return nullptr;
490906f32e7eSjoerg 
491006f32e7eSjoerg   const Decl *D = getCursorDecl(C);
491106f32e7eSjoerg   if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
491206f32e7eSjoerg     return nullptr;
491306f32e7eSjoerg 
491406f32e7eSjoerg   ASTContext &Ctx = D->getASTContext();
491506f32e7eSjoerg   ASTNameGenerator ASTNameGen(Ctx);
491606f32e7eSjoerg   std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
491706f32e7eSjoerg   return cxstring::createSet(Manglings);
491806f32e7eSjoerg }
491906f32e7eSjoerg 
492006f32e7eSjoerg CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
492106f32e7eSjoerg   if (clang_Cursor_isNull(C))
492206f32e7eSjoerg     return 0;
492306f32e7eSjoerg   return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
492406f32e7eSjoerg }
492506f32e7eSjoerg 
492606f32e7eSjoerg void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
492706f32e7eSjoerg   if (Policy)
492806f32e7eSjoerg     delete static_cast<PrintingPolicy *>(Policy);
492906f32e7eSjoerg }
493006f32e7eSjoerg 
493106f32e7eSjoerg unsigned
493206f32e7eSjoerg clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
493306f32e7eSjoerg                                  enum CXPrintingPolicyProperty Property) {
493406f32e7eSjoerg   if (!Policy)
493506f32e7eSjoerg     return 0;
493606f32e7eSjoerg 
493706f32e7eSjoerg   PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
493806f32e7eSjoerg   switch (Property) {
493906f32e7eSjoerg   case CXPrintingPolicy_Indentation:
494006f32e7eSjoerg     return P->Indentation;
494106f32e7eSjoerg   case CXPrintingPolicy_SuppressSpecifiers:
494206f32e7eSjoerg     return P->SuppressSpecifiers;
494306f32e7eSjoerg   case CXPrintingPolicy_SuppressTagKeyword:
494406f32e7eSjoerg     return P->SuppressTagKeyword;
494506f32e7eSjoerg   case CXPrintingPolicy_IncludeTagDefinition:
494606f32e7eSjoerg     return P->IncludeTagDefinition;
494706f32e7eSjoerg   case CXPrintingPolicy_SuppressScope:
494806f32e7eSjoerg     return P->SuppressScope;
494906f32e7eSjoerg   case CXPrintingPolicy_SuppressUnwrittenScope:
495006f32e7eSjoerg     return P->SuppressUnwrittenScope;
495106f32e7eSjoerg   case CXPrintingPolicy_SuppressInitializers:
495206f32e7eSjoerg     return P->SuppressInitializers;
495306f32e7eSjoerg   case CXPrintingPolicy_ConstantArraySizeAsWritten:
495406f32e7eSjoerg     return P->ConstantArraySizeAsWritten;
495506f32e7eSjoerg   case CXPrintingPolicy_AnonymousTagLocations:
495606f32e7eSjoerg     return P->AnonymousTagLocations;
495706f32e7eSjoerg   case CXPrintingPolicy_SuppressStrongLifetime:
495806f32e7eSjoerg     return P->SuppressStrongLifetime;
495906f32e7eSjoerg   case CXPrintingPolicy_SuppressLifetimeQualifiers:
496006f32e7eSjoerg     return P->SuppressLifetimeQualifiers;
496106f32e7eSjoerg   case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
496206f32e7eSjoerg     return P->SuppressTemplateArgsInCXXConstructors;
496306f32e7eSjoerg   case CXPrintingPolicy_Bool:
496406f32e7eSjoerg     return P->Bool;
496506f32e7eSjoerg   case CXPrintingPolicy_Restrict:
496606f32e7eSjoerg     return P->Restrict;
496706f32e7eSjoerg   case CXPrintingPolicy_Alignof:
496806f32e7eSjoerg     return P->Alignof;
496906f32e7eSjoerg   case CXPrintingPolicy_UnderscoreAlignof:
497006f32e7eSjoerg     return P->UnderscoreAlignof;
497106f32e7eSjoerg   case CXPrintingPolicy_UseVoidForZeroParams:
497206f32e7eSjoerg     return P->UseVoidForZeroParams;
497306f32e7eSjoerg   case CXPrintingPolicy_TerseOutput:
497406f32e7eSjoerg     return P->TerseOutput;
497506f32e7eSjoerg   case CXPrintingPolicy_PolishForDeclaration:
497606f32e7eSjoerg     return P->PolishForDeclaration;
497706f32e7eSjoerg   case CXPrintingPolicy_Half:
497806f32e7eSjoerg     return P->Half;
497906f32e7eSjoerg   case CXPrintingPolicy_MSWChar:
498006f32e7eSjoerg     return P->MSWChar;
498106f32e7eSjoerg   case CXPrintingPolicy_IncludeNewlines:
498206f32e7eSjoerg     return P->IncludeNewlines;
498306f32e7eSjoerg   case CXPrintingPolicy_MSVCFormatting:
498406f32e7eSjoerg     return P->MSVCFormatting;
498506f32e7eSjoerg   case CXPrintingPolicy_ConstantsAsWritten:
498606f32e7eSjoerg     return P->ConstantsAsWritten;
498706f32e7eSjoerg   case CXPrintingPolicy_SuppressImplicitBase:
498806f32e7eSjoerg     return P->SuppressImplicitBase;
498906f32e7eSjoerg   case CXPrintingPolicy_FullyQualifiedName:
499006f32e7eSjoerg     return P->FullyQualifiedName;
499106f32e7eSjoerg   }
499206f32e7eSjoerg 
499306f32e7eSjoerg   assert(false && "Invalid CXPrintingPolicyProperty");
499406f32e7eSjoerg   return 0;
499506f32e7eSjoerg }
499606f32e7eSjoerg 
499706f32e7eSjoerg void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
499806f32e7eSjoerg                                       enum CXPrintingPolicyProperty Property,
499906f32e7eSjoerg                                       unsigned Value) {
500006f32e7eSjoerg   if (!Policy)
500106f32e7eSjoerg     return;
500206f32e7eSjoerg 
500306f32e7eSjoerg   PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
500406f32e7eSjoerg   switch (Property) {
500506f32e7eSjoerg   case CXPrintingPolicy_Indentation:
500606f32e7eSjoerg     P->Indentation = Value;
500706f32e7eSjoerg     return;
500806f32e7eSjoerg   case CXPrintingPolicy_SuppressSpecifiers:
500906f32e7eSjoerg     P->SuppressSpecifiers = Value;
501006f32e7eSjoerg     return;
501106f32e7eSjoerg   case CXPrintingPolicy_SuppressTagKeyword:
501206f32e7eSjoerg     P->SuppressTagKeyword = Value;
501306f32e7eSjoerg     return;
501406f32e7eSjoerg   case CXPrintingPolicy_IncludeTagDefinition:
501506f32e7eSjoerg     P->IncludeTagDefinition = Value;
501606f32e7eSjoerg     return;
501706f32e7eSjoerg   case CXPrintingPolicy_SuppressScope:
501806f32e7eSjoerg     P->SuppressScope = Value;
501906f32e7eSjoerg     return;
502006f32e7eSjoerg   case CXPrintingPolicy_SuppressUnwrittenScope:
502106f32e7eSjoerg     P->SuppressUnwrittenScope = Value;
502206f32e7eSjoerg     return;
502306f32e7eSjoerg   case CXPrintingPolicy_SuppressInitializers:
502406f32e7eSjoerg     P->SuppressInitializers = Value;
502506f32e7eSjoerg     return;
502606f32e7eSjoerg   case CXPrintingPolicy_ConstantArraySizeAsWritten:
502706f32e7eSjoerg     P->ConstantArraySizeAsWritten = Value;
502806f32e7eSjoerg     return;
502906f32e7eSjoerg   case CXPrintingPolicy_AnonymousTagLocations:
503006f32e7eSjoerg     P->AnonymousTagLocations = Value;
503106f32e7eSjoerg     return;
503206f32e7eSjoerg   case CXPrintingPolicy_SuppressStrongLifetime:
503306f32e7eSjoerg     P->SuppressStrongLifetime = Value;
503406f32e7eSjoerg     return;
503506f32e7eSjoerg   case CXPrintingPolicy_SuppressLifetimeQualifiers:
503606f32e7eSjoerg     P->SuppressLifetimeQualifiers = Value;
503706f32e7eSjoerg     return;
503806f32e7eSjoerg   case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
503906f32e7eSjoerg     P->SuppressTemplateArgsInCXXConstructors = Value;
504006f32e7eSjoerg     return;
504106f32e7eSjoerg   case CXPrintingPolicy_Bool:
504206f32e7eSjoerg     P->Bool = Value;
504306f32e7eSjoerg     return;
504406f32e7eSjoerg   case CXPrintingPolicy_Restrict:
504506f32e7eSjoerg     P->Restrict = Value;
504606f32e7eSjoerg     return;
504706f32e7eSjoerg   case CXPrintingPolicy_Alignof:
504806f32e7eSjoerg     P->Alignof = Value;
504906f32e7eSjoerg     return;
505006f32e7eSjoerg   case CXPrintingPolicy_UnderscoreAlignof:
505106f32e7eSjoerg     P->UnderscoreAlignof = Value;
505206f32e7eSjoerg     return;
505306f32e7eSjoerg   case CXPrintingPolicy_UseVoidForZeroParams:
505406f32e7eSjoerg     P->UseVoidForZeroParams = Value;
505506f32e7eSjoerg     return;
505606f32e7eSjoerg   case CXPrintingPolicy_TerseOutput:
505706f32e7eSjoerg     P->TerseOutput = Value;
505806f32e7eSjoerg     return;
505906f32e7eSjoerg   case CXPrintingPolicy_PolishForDeclaration:
506006f32e7eSjoerg     P->PolishForDeclaration = Value;
506106f32e7eSjoerg     return;
506206f32e7eSjoerg   case CXPrintingPolicy_Half:
506306f32e7eSjoerg     P->Half = Value;
506406f32e7eSjoerg     return;
506506f32e7eSjoerg   case CXPrintingPolicy_MSWChar:
506606f32e7eSjoerg     P->MSWChar = Value;
506706f32e7eSjoerg     return;
506806f32e7eSjoerg   case CXPrintingPolicy_IncludeNewlines:
506906f32e7eSjoerg     P->IncludeNewlines = Value;
507006f32e7eSjoerg     return;
507106f32e7eSjoerg   case CXPrintingPolicy_MSVCFormatting:
507206f32e7eSjoerg     P->MSVCFormatting = Value;
507306f32e7eSjoerg     return;
507406f32e7eSjoerg   case CXPrintingPolicy_ConstantsAsWritten:
507506f32e7eSjoerg     P->ConstantsAsWritten = Value;
507606f32e7eSjoerg     return;
507706f32e7eSjoerg   case CXPrintingPolicy_SuppressImplicitBase:
507806f32e7eSjoerg     P->SuppressImplicitBase = Value;
507906f32e7eSjoerg     return;
508006f32e7eSjoerg   case CXPrintingPolicy_FullyQualifiedName:
508106f32e7eSjoerg     P->FullyQualifiedName = Value;
508206f32e7eSjoerg     return;
508306f32e7eSjoerg   }
508406f32e7eSjoerg 
508506f32e7eSjoerg   assert(false && "Invalid CXPrintingPolicyProperty");
508606f32e7eSjoerg }
508706f32e7eSjoerg 
508806f32e7eSjoerg CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
508906f32e7eSjoerg   if (clang_Cursor_isNull(C))
509006f32e7eSjoerg     return cxstring::createEmpty();
509106f32e7eSjoerg 
509206f32e7eSjoerg   if (clang_isDeclaration(C.kind)) {
509306f32e7eSjoerg     const Decl *D = getCursorDecl(C);
509406f32e7eSjoerg     if (!D)
509506f32e7eSjoerg       return cxstring::createEmpty();
509606f32e7eSjoerg 
509706f32e7eSjoerg     SmallString<128> Str;
509806f32e7eSjoerg     llvm::raw_svector_ostream OS(Str);
509906f32e7eSjoerg     PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
510006f32e7eSjoerg     D->print(OS, UserPolicy ? *UserPolicy
510106f32e7eSjoerg                             : getCursorContext(C).getPrintingPolicy());
510206f32e7eSjoerg 
510306f32e7eSjoerg     return cxstring::createDup(OS.str());
510406f32e7eSjoerg   }
510506f32e7eSjoerg 
510606f32e7eSjoerg   return cxstring::createEmpty();
510706f32e7eSjoerg }
510806f32e7eSjoerg 
510906f32e7eSjoerg CXString clang_getCursorDisplayName(CXCursor C) {
511006f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
511106f32e7eSjoerg     return clang_getCursorSpelling(C);
511206f32e7eSjoerg 
511306f32e7eSjoerg   const Decl *D = getCursorDecl(C);
511406f32e7eSjoerg   if (!D)
511506f32e7eSjoerg     return cxstring::createEmpty();
511606f32e7eSjoerg 
511706f32e7eSjoerg   PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
511806f32e7eSjoerg   if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
511906f32e7eSjoerg     D = FunTmpl->getTemplatedDecl();
512006f32e7eSjoerg 
512106f32e7eSjoerg   if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
512206f32e7eSjoerg     SmallString<64> Str;
512306f32e7eSjoerg     llvm::raw_svector_ostream OS(Str);
512406f32e7eSjoerg     OS << *Function;
512506f32e7eSjoerg     if (Function->getPrimaryTemplate())
512606f32e7eSjoerg       OS << "<>";
512706f32e7eSjoerg     OS << "(";
512806f32e7eSjoerg     for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
512906f32e7eSjoerg       if (I)
513006f32e7eSjoerg         OS << ", ";
513106f32e7eSjoerg       OS << Function->getParamDecl(I)->getType().getAsString(Policy);
513206f32e7eSjoerg     }
513306f32e7eSjoerg 
513406f32e7eSjoerg     if (Function->isVariadic()) {
513506f32e7eSjoerg       if (Function->getNumParams())
513606f32e7eSjoerg         OS << ", ";
513706f32e7eSjoerg       OS << "...";
513806f32e7eSjoerg     }
513906f32e7eSjoerg     OS << ")";
514006f32e7eSjoerg     return cxstring::createDup(OS.str());
514106f32e7eSjoerg   }
514206f32e7eSjoerg 
514306f32e7eSjoerg   if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
514406f32e7eSjoerg     SmallString<64> Str;
514506f32e7eSjoerg     llvm::raw_svector_ostream OS(Str);
514606f32e7eSjoerg     OS << *ClassTemplate;
514706f32e7eSjoerg     OS << "<";
514806f32e7eSjoerg     TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
514906f32e7eSjoerg     for (unsigned I = 0, N = Params->size(); I != N; ++I) {
515006f32e7eSjoerg       if (I)
515106f32e7eSjoerg         OS << ", ";
515206f32e7eSjoerg 
515306f32e7eSjoerg       NamedDecl *Param = Params->getParam(I);
515406f32e7eSjoerg       if (Param->getIdentifier()) {
515506f32e7eSjoerg         OS << Param->getIdentifier()->getName();
515606f32e7eSjoerg         continue;
515706f32e7eSjoerg       }
515806f32e7eSjoerg 
515906f32e7eSjoerg       // There is no parameter name, which makes this tricky. Try to come up
516006f32e7eSjoerg       // with something useful that isn't too long.
516106f32e7eSjoerg       if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
5162*13fbcb42Sjoerg         if (const auto *TC = TTP->getTypeConstraint()) {
5163*13fbcb42Sjoerg           TC->getConceptNameInfo().printName(OS, Policy);
5164*13fbcb42Sjoerg           if (TC->hasExplicitTemplateArgs())
5165*13fbcb42Sjoerg             OS << "<...>";
5166*13fbcb42Sjoerg         } else
516706f32e7eSjoerg           OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5168*13fbcb42Sjoerg       else if (NonTypeTemplateParmDecl *NTTP =
5169*13fbcb42Sjoerg                    dyn_cast<NonTypeTemplateParmDecl>(Param))
517006f32e7eSjoerg         OS << NTTP->getType().getAsString(Policy);
517106f32e7eSjoerg       else
517206f32e7eSjoerg         OS << "template<...> class";
517306f32e7eSjoerg     }
517406f32e7eSjoerg 
517506f32e7eSjoerg     OS << ">";
517606f32e7eSjoerg     return cxstring::createDup(OS.str());
517706f32e7eSjoerg   }
517806f32e7eSjoerg 
5179*13fbcb42Sjoerg   if (const ClassTemplateSpecializationDecl *ClassSpec =
5180*13fbcb42Sjoerg           dyn_cast<ClassTemplateSpecializationDecl>(D)) {
518106f32e7eSjoerg     // If the type was explicitly written, use that.
518206f32e7eSjoerg     if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
518306f32e7eSjoerg       return cxstring::createDup(TSInfo->getType().getAsString(Policy));
518406f32e7eSjoerg 
518506f32e7eSjoerg     SmallString<128> Str;
518606f32e7eSjoerg     llvm::raw_svector_ostream OS(Str);
518706f32e7eSjoerg     OS << *ClassSpec;
5188*13fbcb42Sjoerg     printTemplateArgumentList(
5189*13fbcb42Sjoerg         OS, ClassSpec->getTemplateArgs().asArray(), Policy,
5190*13fbcb42Sjoerg         ClassSpec->getSpecializedTemplate()->getTemplateParameters());
519106f32e7eSjoerg     return cxstring::createDup(OS.str());
519206f32e7eSjoerg   }
519306f32e7eSjoerg 
519406f32e7eSjoerg   return clang_getCursorSpelling(C);
519506f32e7eSjoerg }
519606f32e7eSjoerg 
519706f32e7eSjoerg CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
519806f32e7eSjoerg   switch (Kind) {
519906f32e7eSjoerg   case CXCursor_FunctionDecl:
520006f32e7eSjoerg     return cxstring::createRef("FunctionDecl");
520106f32e7eSjoerg   case CXCursor_TypedefDecl:
520206f32e7eSjoerg     return cxstring::createRef("TypedefDecl");
520306f32e7eSjoerg   case CXCursor_EnumDecl:
520406f32e7eSjoerg     return cxstring::createRef("EnumDecl");
520506f32e7eSjoerg   case CXCursor_EnumConstantDecl:
520606f32e7eSjoerg     return cxstring::createRef("EnumConstantDecl");
520706f32e7eSjoerg   case CXCursor_StructDecl:
520806f32e7eSjoerg     return cxstring::createRef("StructDecl");
520906f32e7eSjoerg   case CXCursor_UnionDecl:
521006f32e7eSjoerg     return cxstring::createRef("UnionDecl");
521106f32e7eSjoerg   case CXCursor_ClassDecl:
521206f32e7eSjoerg     return cxstring::createRef("ClassDecl");
521306f32e7eSjoerg   case CXCursor_FieldDecl:
521406f32e7eSjoerg     return cxstring::createRef("FieldDecl");
521506f32e7eSjoerg   case CXCursor_VarDecl:
521606f32e7eSjoerg     return cxstring::createRef("VarDecl");
521706f32e7eSjoerg   case CXCursor_ParmDecl:
521806f32e7eSjoerg     return cxstring::createRef("ParmDecl");
521906f32e7eSjoerg   case CXCursor_ObjCInterfaceDecl:
522006f32e7eSjoerg     return cxstring::createRef("ObjCInterfaceDecl");
522106f32e7eSjoerg   case CXCursor_ObjCCategoryDecl:
522206f32e7eSjoerg     return cxstring::createRef("ObjCCategoryDecl");
522306f32e7eSjoerg   case CXCursor_ObjCProtocolDecl:
522406f32e7eSjoerg     return cxstring::createRef("ObjCProtocolDecl");
522506f32e7eSjoerg   case CXCursor_ObjCPropertyDecl:
522606f32e7eSjoerg     return cxstring::createRef("ObjCPropertyDecl");
522706f32e7eSjoerg   case CXCursor_ObjCIvarDecl:
522806f32e7eSjoerg     return cxstring::createRef("ObjCIvarDecl");
522906f32e7eSjoerg   case CXCursor_ObjCInstanceMethodDecl:
523006f32e7eSjoerg     return cxstring::createRef("ObjCInstanceMethodDecl");
523106f32e7eSjoerg   case CXCursor_ObjCClassMethodDecl:
523206f32e7eSjoerg     return cxstring::createRef("ObjCClassMethodDecl");
523306f32e7eSjoerg   case CXCursor_ObjCImplementationDecl:
523406f32e7eSjoerg     return cxstring::createRef("ObjCImplementationDecl");
523506f32e7eSjoerg   case CXCursor_ObjCCategoryImplDecl:
523606f32e7eSjoerg     return cxstring::createRef("ObjCCategoryImplDecl");
523706f32e7eSjoerg   case CXCursor_CXXMethod:
523806f32e7eSjoerg     return cxstring::createRef("CXXMethod");
523906f32e7eSjoerg   case CXCursor_UnexposedDecl:
524006f32e7eSjoerg     return cxstring::createRef("UnexposedDecl");
524106f32e7eSjoerg   case CXCursor_ObjCSuperClassRef:
524206f32e7eSjoerg     return cxstring::createRef("ObjCSuperClassRef");
524306f32e7eSjoerg   case CXCursor_ObjCProtocolRef:
524406f32e7eSjoerg     return cxstring::createRef("ObjCProtocolRef");
524506f32e7eSjoerg   case CXCursor_ObjCClassRef:
524606f32e7eSjoerg     return cxstring::createRef("ObjCClassRef");
524706f32e7eSjoerg   case CXCursor_TypeRef:
524806f32e7eSjoerg     return cxstring::createRef("TypeRef");
524906f32e7eSjoerg   case CXCursor_TemplateRef:
525006f32e7eSjoerg     return cxstring::createRef("TemplateRef");
525106f32e7eSjoerg   case CXCursor_NamespaceRef:
525206f32e7eSjoerg     return cxstring::createRef("NamespaceRef");
525306f32e7eSjoerg   case CXCursor_MemberRef:
525406f32e7eSjoerg     return cxstring::createRef("MemberRef");
525506f32e7eSjoerg   case CXCursor_LabelRef:
525606f32e7eSjoerg     return cxstring::createRef("LabelRef");
525706f32e7eSjoerg   case CXCursor_OverloadedDeclRef:
525806f32e7eSjoerg     return cxstring::createRef("OverloadedDeclRef");
525906f32e7eSjoerg   case CXCursor_VariableRef:
526006f32e7eSjoerg     return cxstring::createRef("VariableRef");
526106f32e7eSjoerg   case CXCursor_IntegerLiteral:
526206f32e7eSjoerg     return cxstring::createRef("IntegerLiteral");
526306f32e7eSjoerg   case CXCursor_FixedPointLiteral:
526406f32e7eSjoerg     return cxstring::createRef("FixedPointLiteral");
526506f32e7eSjoerg   case CXCursor_FloatingLiteral:
526606f32e7eSjoerg     return cxstring::createRef("FloatingLiteral");
526706f32e7eSjoerg   case CXCursor_ImaginaryLiteral:
526806f32e7eSjoerg     return cxstring::createRef("ImaginaryLiteral");
526906f32e7eSjoerg   case CXCursor_StringLiteral:
527006f32e7eSjoerg     return cxstring::createRef("StringLiteral");
527106f32e7eSjoerg   case CXCursor_CharacterLiteral:
527206f32e7eSjoerg     return cxstring::createRef("CharacterLiteral");
527306f32e7eSjoerg   case CXCursor_ParenExpr:
527406f32e7eSjoerg     return cxstring::createRef("ParenExpr");
527506f32e7eSjoerg   case CXCursor_UnaryOperator:
527606f32e7eSjoerg     return cxstring::createRef("UnaryOperator");
527706f32e7eSjoerg   case CXCursor_ArraySubscriptExpr:
527806f32e7eSjoerg     return cxstring::createRef("ArraySubscriptExpr");
527906f32e7eSjoerg   case CXCursor_OMPArraySectionExpr:
528006f32e7eSjoerg     return cxstring::createRef("OMPArraySectionExpr");
5281*13fbcb42Sjoerg   case CXCursor_OMPArrayShapingExpr:
5282*13fbcb42Sjoerg     return cxstring::createRef("OMPArrayShapingExpr");
5283*13fbcb42Sjoerg   case CXCursor_OMPIteratorExpr:
5284*13fbcb42Sjoerg     return cxstring::createRef("OMPIteratorExpr");
528506f32e7eSjoerg   case CXCursor_BinaryOperator:
528606f32e7eSjoerg     return cxstring::createRef("BinaryOperator");
528706f32e7eSjoerg   case CXCursor_CompoundAssignOperator:
528806f32e7eSjoerg     return cxstring::createRef("CompoundAssignOperator");
528906f32e7eSjoerg   case CXCursor_ConditionalOperator:
529006f32e7eSjoerg     return cxstring::createRef("ConditionalOperator");
529106f32e7eSjoerg   case CXCursor_CStyleCastExpr:
529206f32e7eSjoerg     return cxstring::createRef("CStyleCastExpr");
529306f32e7eSjoerg   case CXCursor_CompoundLiteralExpr:
529406f32e7eSjoerg     return cxstring::createRef("CompoundLiteralExpr");
529506f32e7eSjoerg   case CXCursor_InitListExpr:
529606f32e7eSjoerg     return cxstring::createRef("InitListExpr");
529706f32e7eSjoerg   case CXCursor_AddrLabelExpr:
529806f32e7eSjoerg     return cxstring::createRef("AddrLabelExpr");
529906f32e7eSjoerg   case CXCursor_StmtExpr:
530006f32e7eSjoerg     return cxstring::createRef("StmtExpr");
530106f32e7eSjoerg   case CXCursor_GenericSelectionExpr:
530206f32e7eSjoerg     return cxstring::createRef("GenericSelectionExpr");
530306f32e7eSjoerg   case CXCursor_GNUNullExpr:
530406f32e7eSjoerg     return cxstring::createRef("GNUNullExpr");
530506f32e7eSjoerg   case CXCursor_CXXStaticCastExpr:
530606f32e7eSjoerg     return cxstring::createRef("CXXStaticCastExpr");
530706f32e7eSjoerg   case CXCursor_CXXDynamicCastExpr:
530806f32e7eSjoerg     return cxstring::createRef("CXXDynamicCastExpr");
530906f32e7eSjoerg   case CXCursor_CXXReinterpretCastExpr:
531006f32e7eSjoerg     return cxstring::createRef("CXXReinterpretCastExpr");
531106f32e7eSjoerg   case CXCursor_CXXConstCastExpr:
531206f32e7eSjoerg     return cxstring::createRef("CXXConstCastExpr");
531306f32e7eSjoerg   case CXCursor_CXXFunctionalCastExpr:
531406f32e7eSjoerg     return cxstring::createRef("CXXFunctionalCastExpr");
5315*13fbcb42Sjoerg   case CXCursor_CXXAddrspaceCastExpr:
5316*13fbcb42Sjoerg     return cxstring::createRef("CXXAddrspaceCastExpr");
531706f32e7eSjoerg   case CXCursor_CXXTypeidExpr:
531806f32e7eSjoerg     return cxstring::createRef("CXXTypeidExpr");
531906f32e7eSjoerg   case CXCursor_CXXBoolLiteralExpr:
532006f32e7eSjoerg     return cxstring::createRef("CXXBoolLiteralExpr");
532106f32e7eSjoerg   case CXCursor_CXXNullPtrLiteralExpr:
532206f32e7eSjoerg     return cxstring::createRef("CXXNullPtrLiteralExpr");
532306f32e7eSjoerg   case CXCursor_CXXThisExpr:
532406f32e7eSjoerg     return cxstring::createRef("CXXThisExpr");
532506f32e7eSjoerg   case CXCursor_CXXThrowExpr:
532606f32e7eSjoerg     return cxstring::createRef("CXXThrowExpr");
532706f32e7eSjoerg   case CXCursor_CXXNewExpr:
532806f32e7eSjoerg     return cxstring::createRef("CXXNewExpr");
532906f32e7eSjoerg   case CXCursor_CXXDeleteExpr:
533006f32e7eSjoerg     return cxstring::createRef("CXXDeleteExpr");
533106f32e7eSjoerg   case CXCursor_UnaryExpr:
533206f32e7eSjoerg     return cxstring::createRef("UnaryExpr");
533306f32e7eSjoerg   case CXCursor_ObjCStringLiteral:
533406f32e7eSjoerg     return cxstring::createRef("ObjCStringLiteral");
533506f32e7eSjoerg   case CXCursor_ObjCBoolLiteralExpr:
533606f32e7eSjoerg     return cxstring::createRef("ObjCBoolLiteralExpr");
533706f32e7eSjoerg   case CXCursor_ObjCAvailabilityCheckExpr:
533806f32e7eSjoerg     return cxstring::createRef("ObjCAvailabilityCheckExpr");
533906f32e7eSjoerg   case CXCursor_ObjCSelfExpr:
534006f32e7eSjoerg     return cxstring::createRef("ObjCSelfExpr");
534106f32e7eSjoerg   case CXCursor_ObjCEncodeExpr:
534206f32e7eSjoerg     return cxstring::createRef("ObjCEncodeExpr");
534306f32e7eSjoerg   case CXCursor_ObjCSelectorExpr:
534406f32e7eSjoerg     return cxstring::createRef("ObjCSelectorExpr");
534506f32e7eSjoerg   case CXCursor_ObjCProtocolExpr:
534606f32e7eSjoerg     return cxstring::createRef("ObjCProtocolExpr");
534706f32e7eSjoerg   case CXCursor_ObjCBridgedCastExpr:
534806f32e7eSjoerg     return cxstring::createRef("ObjCBridgedCastExpr");
534906f32e7eSjoerg   case CXCursor_BlockExpr:
535006f32e7eSjoerg     return cxstring::createRef("BlockExpr");
535106f32e7eSjoerg   case CXCursor_PackExpansionExpr:
535206f32e7eSjoerg     return cxstring::createRef("PackExpansionExpr");
535306f32e7eSjoerg   case CXCursor_SizeOfPackExpr:
535406f32e7eSjoerg     return cxstring::createRef("SizeOfPackExpr");
535506f32e7eSjoerg   case CXCursor_LambdaExpr:
535606f32e7eSjoerg     return cxstring::createRef("LambdaExpr");
535706f32e7eSjoerg   case CXCursor_UnexposedExpr:
535806f32e7eSjoerg     return cxstring::createRef("UnexposedExpr");
535906f32e7eSjoerg   case CXCursor_DeclRefExpr:
536006f32e7eSjoerg     return cxstring::createRef("DeclRefExpr");
536106f32e7eSjoerg   case CXCursor_MemberRefExpr:
536206f32e7eSjoerg     return cxstring::createRef("MemberRefExpr");
536306f32e7eSjoerg   case CXCursor_CallExpr:
536406f32e7eSjoerg     return cxstring::createRef("CallExpr");
536506f32e7eSjoerg   case CXCursor_ObjCMessageExpr:
536606f32e7eSjoerg     return cxstring::createRef("ObjCMessageExpr");
536706f32e7eSjoerg   case CXCursor_BuiltinBitCastExpr:
536806f32e7eSjoerg     return cxstring::createRef("BuiltinBitCastExpr");
536906f32e7eSjoerg   case CXCursor_UnexposedStmt:
537006f32e7eSjoerg     return cxstring::createRef("UnexposedStmt");
537106f32e7eSjoerg   case CXCursor_DeclStmt:
537206f32e7eSjoerg     return cxstring::createRef("DeclStmt");
537306f32e7eSjoerg   case CXCursor_LabelStmt:
537406f32e7eSjoerg     return cxstring::createRef("LabelStmt");
537506f32e7eSjoerg   case CXCursor_CompoundStmt:
537606f32e7eSjoerg     return cxstring::createRef("CompoundStmt");
537706f32e7eSjoerg   case CXCursor_CaseStmt:
537806f32e7eSjoerg     return cxstring::createRef("CaseStmt");
537906f32e7eSjoerg   case CXCursor_DefaultStmt:
538006f32e7eSjoerg     return cxstring::createRef("DefaultStmt");
538106f32e7eSjoerg   case CXCursor_IfStmt:
538206f32e7eSjoerg     return cxstring::createRef("IfStmt");
538306f32e7eSjoerg   case CXCursor_SwitchStmt:
538406f32e7eSjoerg     return cxstring::createRef("SwitchStmt");
538506f32e7eSjoerg   case CXCursor_WhileStmt:
538606f32e7eSjoerg     return cxstring::createRef("WhileStmt");
538706f32e7eSjoerg   case CXCursor_DoStmt:
538806f32e7eSjoerg     return cxstring::createRef("DoStmt");
538906f32e7eSjoerg   case CXCursor_ForStmt:
539006f32e7eSjoerg     return cxstring::createRef("ForStmt");
539106f32e7eSjoerg   case CXCursor_GotoStmt:
539206f32e7eSjoerg     return cxstring::createRef("GotoStmt");
539306f32e7eSjoerg   case CXCursor_IndirectGotoStmt:
539406f32e7eSjoerg     return cxstring::createRef("IndirectGotoStmt");
539506f32e7eSjoerg   case CXCursor_ContinueStmt:
539606f32e7eSjoerg     return cxstring::createRef("ContinueStmt");
539706f32e7eSjoerg   case CXCursor_BreakStmt:
539806f32e7eSjoerg     return cxstring::createRef("BreakStmt");
539906f32e7eSjoerg   case CXCursor_ReturnStmt:
540006f32e7eSjoerg     return cxstring::createRef("ReturnStmt");
540106f32e7eSjoerg   case CXCursor_GCCAsmStmt:
540206f32e7eSjoerg     return cxstring::createRef("GCCAsmStmt");
540306f32e7eSjoerg   case CXCursor_MSAsmStmt:
540406f32e7eSjoerg     return cxstring::createRef("MSAsmStmt");
540506f32e7eSjoerg   case CXCursor_ObjCAtTryStmt:
540606f32e7eSjoerg     return cxstring::createRef("ObjCAtTryStmt");
540706f32e7eSjoerg   case CXCursor_ObjCAtCatchStmt:
540806f32e7eSjoerg     return cxstring::createRef("ObjCAtCatchStmt");
540906f32e7eSjoerg   case CXCursor_ObjCAtFinallyStmt:
541006f32e7eSjoerg     return cxstring::createRef("ObjCAtFinallyStmt");
541106f32e7eSjoerg   case CXCursor_ObjCAtThrowStmt:
541206f32e7eSjoerg     return cxstring::createRef("ObjCAtThrowStmt");
541306f32e7eSjoerg   case CXCursor_ObjCAtSynchronizedStmt:
541406f32e7eSjoerg     return cxstring::createRef("ObjCAtSynchronizedStmt");
541506f32e7eSjoerg   case CXCursor_ObjCAutoreleasePoolStmt:
541606f32e7eSjoerg     return cxstring::createRef("ObjCAutoreleasePoolStmt");
541706f32e7eSjoerg   case CXCursor_ObjCForCollectionStmt:
541806f32e7eSjoerg     return cxstring::createRef("ObjCForCollectionStmt");
541906f32e7eSjoerg   case CXCursor_CXXCatchStmt:
542006f32e7eSjoerg     return cxstring::createRef("CXXCatchStmt");
542106f32e7eSjoerg   case CXCursor_CXXTryStmt:
542206f32e7eSjoerg     return cxstring::createRef("CXXTryStmt");
542306f32e7eSjoerg   case CXCursor_CXXForRangeStmt:
542406f32e7eSjoerg     return cxstring::createRef("CXXForRangeStmt");
542506f32e7eSjoerg   case CXCursor_SEHTryStmt:
542606f32e7eSjoerg     return cxstring::createRef("SEHTryStmt");
542706f32e7eSjoerg   case CXCursor_SEHExceptStmt:
542806f32e7eSjoerg     return cxstring::createRef("SEHExceptStmt");
542906f32e7eSjoerg   case CXCursor_SEHFinallyStmt:
543006f32e7eSjoerg     return cxstring::createRef("SEHFinallyStmt");
543106f32e7eSjoerg   case CXCursor_SEHLeaveStmt:
543206f32e7eSjoerg     return cxstring::createRef("SEHLeaveStmt");
543306f32e7eSjoerg   case CXCursor_NullStmt:
543406f32e7eSjoerg     return cxstring::createRef("NullStmt");
543506f32e7eSjoerg   case CXCursor_InvalidFile:
543606f32e7eSjoerg     return cxstring::createRef("InvalidFile");
543706f32e7eSjoerg   case CXCursor_InvalidCode:
543806f32e7eSjoerg     return cxstring::createRef("InvalidCode");
543906f32e7eSjoerg   case CXCursor_NoDeclFound:
544006f32e7eSjoerg     return cxstring::createRef("NoDeclFound");
544106f32e7eSjoerg   case CXCursor_NotImplemented:
544206f32e7eSjoerg     return cxstring::createRef("NotImplemented");
544306f32e7eSjoerg   case CXCursor_TranslationUnit:
544406f32e7eSjoerg     return cxstring::createRef("TranslationUnit");
544506f32e7eSjoerg   case CXCursor_UnexposedAttr:
544606f32e7eSjoerg     return cxstring::createRef("UnexposedAttr");
544706f32e7eSjoerg   case CXCursor_IBActionAttr:
544806f32e7eSjoerg     return cxstring::createRef("attribute(ibaction)");
544906f32e7eSjoerg   case CXCursor_IBOutletAttr:
545006f32e7eSjoerg     return cxstring::createRef("attribute(iboutlet)");
545106f32e7eSjoerg   case CXCursor_IBOutletCollectionAttr:
545206f32e7eSjoerg     return cxstring::createRef("attribute(iboutletcollection)");
545306f32e7eSjoerg   case CXCursor_CXXFinalAttr:
545406f32e7eSjoerg     return cxstring::createRef("attribute(final)");
545506f32e7eSjoerg   case CXCursor_CXXOverrideAttr:
545606f32e7eSjoerg     return cxstring::createRef("attribute(override)");
545706f32e7eSjoerg   case CXCursor_AnnotateAttr:
545806f32e7eSjoerg     return cxstring::createRef("attribute(annotate)");
545906f32e7eSjoerg   case CXCursor_AsmLabelAttr:
546006f32e7eSjoerg     return cxstring::createRef("asm label");
546106f32e7eSjoerg   case CXCursor_PackedAttr:
546206f32e7eSjoerg     return cxstring::createRef("attribute(packed)");
546306f32e7eSjoerg   case CXCursor_PureAttr:
546406f32e7eSjoerg     return cxstring::createRef("attribute(pure)");
546506f32e7eSjoerg   case CXCursor_ConstAttr:
546606f32e7eSjoerg     return cxstring::createRef("attribute(const)");
546706f32e7eSjoerg   case CXCursor_NoDuplicateAttr:
546806f32e7eSjoerg     return cxstring::createRef("attribute(noduplicate)");
546906f32e7eSjoerg   case CXCursor_CUDAConstantAttr:
547006f32e7eSjoerg     return cxstring::createRef("attribute(constant)");
547106f32e7eSjoerg   case CXCursor_CUDADeviceAttr:
547206f32e7eSjoerg     return cxstring::createRef("attribute(device)");
547306f32e7eSjoerg   case CXCursor_CUDAGlobalAttr:
547406f32e7eSjoerg     return cxstring::createRef("attribute(global)");
547506f32e7eSjoerg   case CXCursor_CUDAHostAttr:
547606f32e7eSjoerg     return cxstring::createRef("attribute(host)");
547706f32e7eSjoerg   case CXCursor_CUDASharedAttr:
547806f32e7eSjoerg     return cxstring::createRef("attribute(shared)");
547906f32e7eSjoerg   case CXCursor_VisibilityAttr:
548006f32e7eSjoerg     return cxstring::createRef("attribute(visibility)");
548106f32e7eSjoerg   case CXCursor_DLLExport:
548206f32e7eSjoerg     return cxstring::createRef("attribute(dllexport)");
548306f32e7eSjoerg   case CXCursor_DLLImport:
548406f32e7eSjoerg     return cxstring::createRef("attribute(dllimport)");
548506f32e7eSjoerg   case CXCursor_NSReturnsRetained:
548606f32e7eSjoerg     return cxstring::createRef("attribute(ns_returns_retained)");
548706f32e7eSjoerg   case CXCursor_NSReturnsNotRetained:
548806f32e7eSjoerg     return cxstring::createRef("attribute(ns_returns_not_retained)");
548906f32e7eSjoerg   case CXCursor_NSReturnsAutoreleased:
549006f32e7eSjoerg     return cxstring::createRef("attribute(ns_returns_autoreleased)");
549106f32e7eSjoerg   case CXCursor_NSConsumesSelf:
549206f32e7eSjoerg     return cxstring::createRef("attribute(ns_consumes_self)");
549306f32e7eSjoerg   case CXCursor_NSConsumed:
549406f32e7eSjoerg     return cxstring::createRef("attribute(ns_consumed)");
549506f32e7eSjoerg   case CXCursor_ObjCException:
549606f32e7eSjoerg     return cxstring::createRef("attribute(objc_exception)");
549706f32e7eSjoerg   case CXCursor_ObjCNSObject:
549806f32e7eSjoerg     return cxstring::createRef("attribute(NSObject)");
549906f32e7eSjoerg   case CXCursor_ObjCIndependentClass:
550006f32e7eSjoerg     return cxstring::createRef("attribute(objc_independent_class)");
550106f32e7eSjoerg   case CXCursor_ObjCPreciseLifetime:
550206f32e7eSjoerg     return cxstring::createRef("attribute(objc_precise_lifetime)");
550306f32e7eSjoerg   case CXCursor_ObjCReturnsInnerPointer:
550406f32e7eSjoerg     return cxstring::createRef("attribute(objc_returns_inner_pointer)");
550506f32e7eSjoerg   case CXCursor_ObjCRequiresSuper:
550606f32e7eSjoerg     return cxstring::createRef("attribute(objc_requires_super)");
550706f32e7eSjoerg   case CXCursor_ObjCRootClass:
550806f32e7eSjoerg     return cxstring::createRef("attribute(objc_root_class)");
550906f32e7eSjoerg   case CXCursor_ObjCSubclassingRestricted:
551006f32e7eSjoerg     return cxstring::createRef("attribute(objc_subclassing_restricted)");
551106f32e7eSjoerg   case CXCursor_ObjCExplicitProtocolImpl:
5512*13fbcb42Sjoerg     return cxstring::createRef(
5513*13fbcb42Sjoerg         "attribute(objc_protocol_requires_explicit_implementation)");
551406f32e7eSjoerg   case CXCursor_ObjCDesignatedInitializer:
551506f32e7eSjoerg     return cxstring::createRef("attribute(objc_designated_initializer)");
551606f32e7eSjoerg   case CXCursor_ObjCRuntimeVisible:
551706f32e7eSjoerg     return cxstring::createRef("attribute(objc_runtime_visible)");
551806f32e7eSjoerg   case CXCursor_ObjCBoxable:
551906f32e7eSjoerg     return cxstring::createRef("attribute(objc_boxable)");
552006f32e7eSjoerg   case CXCursor_FlagEnum:
552106f32e7eSjoerg     return cxstring::createRef("attribute(flag_enum)");
552206f32e7eSjoerg   case CXCursor_PreprocessingDirective:
552306f32e7eSjoerg     return cxstring::createRef("preprocessing directive");
552406f32e7eSjoerg   case CXCursor_MacroDefinition:
552506f32e7eSjoerg     return cxstring::createRef("macro definition");
552606f32e7eSjoerg   case CXCursor_MacroExpansion:
552706f32e7eSjoerg     return cxstring::createRef("macro expansion");
552806f32e7eSjoerg   case CXCursor_InclusionDirective:
552906f32e7eSjoerg     return cxstring::createRef("inclusion directive");
553006f32e7eSjoerg   case CXCursor_Namespace:
553106f32e7eSjoerg     return cxstring::createRef("Namespace");
553206f32e7eSjoerg   case CXCursor_LinkageSpec:
553306f32e7eSjoerg     return cxstring::createRef("LinkageSpec");
553406f32e7eSjoerg   case CXCursor_CXXBaseSpecifier:
553506f32e7eSjoerg     return cxstring::createRef("C++ base class specifier");
553606f32e7eSjoerg   case CXCursor_Constructor:
553706f32e7eSjoerg     return cxstring::createRef("CXXConstructor");
553806f32e7eSjoerg   case CXCursor_Destructor:
553906f32e7eSjoerg     return cxstring::createRef("CXXDestructor");
554006f32e7eSjoerg   case CXCursor_ConversionFunction:
554106f32e7eSjoerg     return cxstring::createRef("CXXConversion");
554206f32e7eSjoerg   case CXCursor_TemplateTypeParameter:
554306f32e7eSjoerg     return cxstring::createRef("TemplateTypeParameter");
554406f32e7eSjoerg   case CXCursor_NonTypeTemplateParameter:
554506f32e7eSjoerg     return cxstring::createRef("NonTypeTemplateParameter");
554606f32e7eSjoerg   case CXCursor_TemplateTemplateParameter:
554706f32e7eSjoerg     return cxstring::createRef("TemplateTemplateParameter");
554806f32e7eSjoerg   case CXCursor_FunctionTemplate:
554906f32e7eSjoerg     return cxstring::createRef("FunctionTemplate");
555006f32e7eSjoerg   case CXCursor_ClassTemplate:
555106f32e7eSjoerg     return cxstring::createRef("ClassTemplate");
555206f32e7eSjoerg   case CXCursor_ClassTemplatePartialSpecialization:
555306f32e7eSjoerg     return cxstring::createRef("ClassTemplatePartialSpecialization");
555406f32e7eSjoerg   case CXCursor_NamespaceAlias:
555506f32e7eSjoerg     return cxstring::createRef("NamespaceAlias");
555606f32e7eSjoerg   case CXCursor_UsingDirective:
555706f32e7eSjoerg     return cxstring::createRef("UsingDirective");
555806f32e7eSjoerg   case CXCursor_UsingDeclaration:
555906f32e7eSjoerg     return cxstring::createRef("UsingDeclaration");
556006f32e7eSjoerg   case CXCursor_TypeAliasDecl:
556106f32e7eSjoerg     return cxstring::createRef("TypeAliasDecl");
556206f32e7eSjoerg   case CXCursor_ObjCSynthesizeDecl:
556306f32e7eSjoerg     return cxstring::createRef("ObjCSynthesizeDecl");
556406f32e7eSjoerg   case CXCursor_ObjCDynamicDecl:
556506f32e7eSjoerg     return cxstring::createRef("ObjCDynamicDecl");
556606f32e7eSjoerg   case CXCursor_CXXAccessSpecifier:
556706f32e7eSjoerg     return cxstring::createRef("CXXAccessSpecifier");
556806f32e7eSjoerg   case CXCursor_ModuleImportDecl:
556906f32e7eSjoerg     return cxstring::createRef("ModuleImport");
5570*13fbcb42Sjoerg   case CXCursor_OMPCanonicalLoop:
5571*13fbcb42Sjoerg     return cxstring::createRef("OMPCanonicalLoop");
557206f32e7eSjoerg   case CXCursor_OMPParallelDirective:
557306f32e7eSjoerg     return cxstring::createRef("OMPParallelDirective");
557406f32e7eSjoerg   case CXCursor_OMPSimdDirective:
557506f32e7eSjoerg     return cxstring::createRef("OMPSimdDirective");
5576*13fbcb42Sjoerg   case CXCursor_OMPTileDirective:
5577*13fbcb42Sjoerg     return cxstring::createRef("OMPTileDirective");
557806f32e7eSjoerg   case CXCursor_OMPForDirective:
557906f32e7eSjoerg     return cxstring::createRef("OMPForDirective");
558006f32e7eSjoerg   case CXCursor_OMPForSimdDirective:
558106f32e7eSjoerg     return cxstring::createRef("OMPForSimdDirective");
558206f32e7eSjoerg   case CXCursor_OMPSectionsDirective:
558306f32e7eSjoerg     return cxstring::createRef("OMPSectionsDirective");
558406f32e7eSjoerg   case CXCursor_OMPSectionDirective:
558506f32e7eSjoerg     return cxstring::createRef("OMPSectionDirective");
558606f32e7eSjoerg   case CXCursor_OMPSingleDirective:
558706f32e7eSjoerg     return cxstring::createRef("OMPSingleDirective");
558806f32e7eSjoerg   case CXCursor_OMPMasterDirective:
558906f32e7eSjoerg     return cxstring::createRef("OMPMasterDirective");
559006f32e7eSjoerg   case CXCursor_OMPCriticalDirective:
559106f32e7eSjoerg     return cxstring::createRef("OMPCriticalDirective");
559206f32e7eSjoerg   case CXCursor_OMPParallelForDirective:
559306f32e7eSjoerg     return cxstring::createRef("OMPParallelForDirective");
559406f32e7eSjoerg   case CXCursor_OMPParallelForSimdDirective:
559506f32e7eSjoerg     return cxstring::createRef("OMPParallelForSimdDirective");
5596*13fbcb42Sjoerg   case CXCursor_OMPParallelMasterDirective:
5597*13fbcb42Sjoerg     return cxstring::createRef("OMPParallelMasterDirective");
559806f32e7eSjoerg   case CXCursor_OMPParallelSectionsDirective:
559906f32e7eSjoerg     return cxstring::createRef("OMPParallelSectionsDirective");
560006f32e7eSjoerg   case CXCursor_OMPTaskDirective:
560106f32e7eSjoerg     return cxstring::createRef("OMPTaskDirective");
560206f32e7eSjoerg   case CXCursor_OMPTaskyieldDirective:
560306f32e7eSjoerg     return cxstring::createRef("OMPTaskyieldDirective");
560406f32e7eSjoerg   case CXCursor_OMPBarrierDirective:
560506f32e7eSjoerg     return cxstring::createRef("OMPBarrierDirective");
560606f32e7eSjoerg   case CXCursor_OMPTaskwaitDirective:
560706f32e7eSjoerg     return cxstring::createRef("OMPTaskwaitDirective");
560806f32e7eSjoerg   case CXCursor_OMPTaskgroupDirective:
560906f32e7eSjoerg     return cxstring::createRef("OMPTaskgroupDirective");
561006f32e7eSjoerg   case CXCursor_OMPFlushDirective:
561106f32e7eSjoerg     return cxstring::createRef("OMPFlushDirective");
5612*13fbcb42Sjoerg   case CXCursor_OMPDepobjDirective:
5613*13fbcb42Sjoerg     return cxstring::createRef("OMPDepobjDirective");
5614*13fbcb42Sjoerg   case CXCursor_OMPScanDirective:
5615*13fbcb42Sjoerg     return cxstring::createRef("OMPScanDirective");
561606f32e7eSjoerg   case CXCursor_OMPOrderedDirective:
561706f32e7eSjoerg     return cxstring::createRef("OMPOrderedDirective");
561806f32e7eSjoerg   case CXCursor_OMPAtomicDirective:
561906f32e7eSjoerg     return cxstring::createRef("OMPAtomicDirective");
562006f32e7eSjoerg   case CXCursor_OMPTargetDirective:
562106f32e7eSjoerg     return cxstring::createRef("OMPTargetDirective");
562206f32e7eSjoerg   case CXCursor_OMPTargetDataDirective:
562306f32e7eSjoerg     return cxstring::createRef("OMPTargetDataDirective");
562406f32e7eSjoerg   case CXCursor_OMPTargetEnterDataDirective:
562506f32e7eSjoerg     return cxstring::createRef("OMPTargetEnterDataDirective");
562606f32e7eSjoerg   case CXCursor_OMPTargetExitDataDirective:
562706f32e7eSjoerg     return cxstring::createRef("OMPTargetExitDataDirective");
562806f32e7eSjoerg   case CXCursor_OMPTargetParallelDirective:
562906f32e7eSjoerg     return cxstring::createRef("OMPTargetParallelDirective");
563006f32e7eSjoerg   case CXCursor_OMPTargetParallelForDirective:
563106f32e7eSjoerg     return cxstring::createRef("OMPTargetParallelForDirective");
563206f32e7eSjoerg   case CXCursor_OMPTargetUpdateDirective:
563306f32e7eSjoerg     return cxstring::createRef("OMPTargetUpdateDirective");
563406f32e7eSjoerg   case CXCursor_OMPTeamsDirective:
563506f32e7eSjoerg     return cxstring::createRef("OMPTeamsDirective");
563606f32e7eSjoerg   case CXCursor_OMPCancellationPointDirective:
563706f32e7eSjoerg     return cxstring::createRef("OMPCancellationPointDirective");
563806f32e7eSjoerg   case CXCursor_OMPCancelDirective:
563906f32e7eSjoerg     return cxstring::createRef("OMPCancelDirective");
564006f32e7eSjoerg   case CXCursor_OMPTaskLoopDirective:
564106f32e7eSjoerg     return cxstring::createRef("OMPTaskLoopDirective");
564206f32e7eSjoerg   case CXCursor_OMPTaskLoopSimdDirective:
564306f32e7eSjoerg     return cxstring::createRef("OMPTaskLoopSimdDirective");
564406f32e7eSjoerg   case CXCursor_OMPMasterTaskLoopDirective:
564506f32e7eSjoerg     return cxstring::createRef("OMPMasterTaskLoopDirective");
564606f32e7eSjoerg   case CXCursor_OMPMasterTaskLoopSimdDirective:
564706f32e7eSjoerg     return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
564806f32e7eSjoerg   case CXCursor_OMPParallelMasterTaskLoopDirective:
564906f32e7eSjoerg     return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
5650*13fbcb42Sjoerg   case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5651*13fbcb42Sjoerg     return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
565206f32e7eSjoerg   case CXCursor_OMPDistributeDirective:
565306f32e7eSjoerg     return cxstring::createRef("OMPDistributeDirective");
565406f32e7eSjoerg   case CXCursor_OMPDistributeParallelForDirective:
565506f32e7eSjoerg     return cxstring::createRef("OMPDistributeParallelForDirective");
565606f32e7eSjoerg   case CXCursor_OMPDistributeParallelForSimdDirective:
565706f32e7eSjoerg     return cxstring::createRef("OMPDistributeParallelForSimdDirective");
565806f32e7eSjoerg   case CXCursor_OMPDistributeSimdDirective:
565906f32e7eSjoerg     return cxstring::createRef("OMPDistributeSimdDirective");
566006f32e7eSjoerg   case CXCursor_OMPTargetParallelForSimdDirective:
566106f32e7eSjoerg     return cxstring::createRef("OMPTargetParallelForSimdDirective");
566206f32e7eSjoerg   case CXCursor_OMPTargetSimdDirective:
566306f32e7eSjoerg     return cxstring::createRef("OMPTargetSimdDirective");
566406f32e7eSjoerg   case CXCursor_OMPTeamsDistributeDirective:
566506f32e7eSjoerg     return cxstring::createRef("OMPTeamsDistributeDirective");
566606f32e7eSjoerg   case CXCursor_OMPTeamsDistributeSimdDirective:
566706f32e7eSjoerg     return cxstring::createRef("OMPTeamsDistributeSimdDirective");
566806f32e7eSjoerg   case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
566906f32e7eSjoerg     return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
567006f32e7eSjoerg   case CXCursor_OMPTeamsDistributeParallelForDirective:
567106f32e7eSjoerg     return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
567206f32e7eSjoerg   case CXCursor_OMPTargetTeamsDirective:
567306f32e7eSjoerg     return cxstring::createRef("OMPTargetTeamsDirective");
567406f32e7eSjoerg   case CXCursor_OMPTargetTeamsDistributeDirective:
567506f32e7eSjoerg     return cxstring::createRef("OMPTargetTeamsDistributeDirective");
567606f32e7eSjoerg   case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
567706f32e7eSjoerg     return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
567806f32e7eSjoerg   case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
567906f32e7eSjoerg     return cxstring::createRef(
568006f32e7eSjoerg         "OMPTargetTeamsDistributeParallelForSimdDirective");
568106f32e7eSjoerg   case CXCursor_OMPTargetTeamsDistributeSimdDirective:
568206f32e7eSjoerg     return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
5683*13fbcb42Sjoerg   case CXCursor_OMPInteropDirective:
5684*13fbcb42Sjoerg     return cxstring::createRef("OMPInteropDirective");
5685*13fbcb42Sjoerg   case CXCursor_OMPDispatchDirective:
5686*13fbcb42Sjoerg     return cxstring::createRef("OMPDispatchDirective");
5687*13fbcb42Sjoerg   case CXCursor_OMPMaskedDirective:
5688*13fbcb42Sjoerg     return cxstring::createRef("OMPMaskedDirective");
568906f32e7eSjoerg   case CXCursor_OverloadCandidate:
569006f32e7eSjoerg     return cxstring::createRef("OverloadCandidate");
569106f32e7eSjoerg   case CXCursor_TypeAliasTemplateDecl:
569206f32e7eSjoerg     return cxstring::createRef("TypeAliasTemplateDecl");
569306f32e7eSjoerg   case CXCursor_StaticAssert:
569406f32e7eSjoerg     return cxstring::createRef("StaticAssert");
569506f32e7eSjoerg   case CXCursor_FriendDecl:
569606f32e7eSjoerg     return cxstring::createRef("FriendDecl");
569706f32e7eSjoerg   case CXCursor_ConvergentAttr:
569806f32e7eSjoerg     return cxstring::createRef("attribute(convergent)");
569906f32e7eSjoerg   case CXCursor_WarnUnusedAttr:
570006f32e7eSjoerg     return cxstring::createRef("attribute(warn_unused)");
570106f32e7eSjoerg   case CXCursor_WarnUnusedResultAttr:
570206f32e7eSjoerg     return cxstring::createRef("attribute(warn_unused_result)");
570306f32e7eSjoerg   case CXCursor_AlignedAttr:
570406f32e7eSjoerg     return cxstring::createRef("attribute(aligned)");
570506f32e7eSjoerg   }
570606f32e7eSjoerg 
570706f32e7eSjoerg   llvm_unreachable("Unhandled CXCursorKind");
570806f32e7eSjoerg }
570906f32e7eSjoerg 
571006f32e7eSjoerg struct GetCursorData {
571106f32e7eSjoerg   SourceLocation TokenBeginLoc;
571206f32e7eSjoerg   bool PointsAtMacroArgExpansion;
571306f32e7eSjoerg   bool VisitedObjCPropertyImplDecl;
571406f32e7eSjoerg   SourceLocation VisitedDeclaratorDeclStartLoc;
571506f32e7eSjoerg   CXCursor &BestCursor;
571606f32e7eSjoerg 
5717*13fbcb42Sjoerg   GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5718*13fbcb42Sjoerg                 CXCursor &outputCursor)
571906f32e7eSjoerg       : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
572006f32e7eSjoerg     PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
572106f32e7eSjoerg     VisitedObjCPropertyImplDecl = false;
572206f32e7eSjoerg   }
572306f32e7eSjoerg };
572406f32e7eSjoerg 
5725*13fbcb42Sjoerg static enum CXChildVisitResult
GetCursorVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)5726*13fbcb42Sjoerg GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
572706f32e7eSjoerg   GetCursorData *Data = static_cast<GetCursorData *>(client_data);
572806f32e7eSjoerg   CXCursor *BestCursor = &Data->BestCursor;
572906f32e7eSjoerg 
573006f32e7eSjoerg   // If we point inside a macro argument we should provide info of what the
573106f32e7eSjoerg   // token is so use the actual cursor, don't replace it with a macro expansion
573206f32e7eSjoerg   // cursor.
573306f32e7eSjoerg   if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
573406f32e7eSjoerg     return CXChildVisit_Recurse;
573506f32e7eSjoerg 
573606f32e7eSjoerg   if (clang_isDeclaration(cursor.kind)) {
573706f32e7eSjoerg     // Avoid having the implicit methods override the property decls.
5738*13fbcb42Sjoerg     if (const ObjCMethodDecl *MD =
5739*13fbcb42Sjoerg             dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
574006f32e7eSjoerg       if (MD->isImplicit())
574106f32e7eSjoerg         return CXChildVisit_Break;
574206f32e7eSjoerg 
5743*13fbcb42Sjoerg     } else if (const ObjCInterfaceDecl *ID =
5744*13fbcb42Sjoerg                    dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
574506f32e7eSjoerg       // Check that when we have multiple @class references in the same line,
574606f32e7eSjoerg       // that later ones do not override the previous ones.
574706f32e7eSjoerg       // If we have:
574806f32e7eSjoerg       // @class Foo, Bar;
574906f32e7eSjoerg       // source ranges for both start at '@', so 'Bar' will end up overriding
575006f32e7eSjoerg       // 'Foo' even though the cursor location was at 'Foo'.
575106f32e7eSjoerg       if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
575206f32e7eSjoerg           BestCursor->kind == CXCursor_ObjCClassRef)
5753*13fbcb42Sjoerg         if (const ObjCInterfaceDecl *PrevID =
5754*13fbcb42Sjoerg                 dyn_cast_or_null<ObjCInterfaceDecl>(
5755*13fbcb42Sjoerg                     getCursorDecl(*BestCursor))) {
5756*13fbcb42Sjoerg           if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
575706f32e7eSjoerg               !ID->isThisDeclarationADefinition())
575806f32e7eSjoerg             return CXChildVisit_Break;
575906f32e7eSjoerg         }
576006f32e7eSjoerg 
5761*13fbcb42Sjoerg     } else if (const DeclaratorDecl *DD =
5762*13fbcb42Sjoerg                    dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
576306f32e7eSjoerg       SourceLocation StartLoc = DD->getSourceRange().getBegin();
576406f32e7eSjoerg       // Check that when we have multiple declarators in the same line,
576506f32e7eSjoerg       // that later ones do not override the previous ones.
576606f32e7eSjoerg       // If we have:
576706f32e7eSjoerg       // int Foo, Bar;
576806f32e7eSjoerg       // source ranges for both start at 'int', so 'Bar' will end up overriding
576906f32e7eSjoerg       // 'Foo' even though the cursor location was at 'Foo'.
577006f32e7eSjoerg       if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
577106f32e7eSjoerg         return CXChildVisit_Break;
577206f32e7eSjoerg       Data->VisitedDeclaratorDeclStartLoc = StartLoc;
577306f32e7eSjoerg 
5774*13fbcb42Sjoerg     } else if (const ObjCPropertyImplDecl *PropImp =
5775*13fbcb42Sjoerg                    dyn_cast_or_null<ObjCPropertyImplDecl>(
5776*13fbcb42Sjoerg                        getCursorDecl(cursor))) {
577706f32e7eSjoerg       (void)PropImp;
577806f32e7eSjoerg       // Check that when we have multiple @synthesize in the same line,
577906f32e7eSjoerg       // that later ones do not override the previous ones.
578006f32e7eSjoerg       // If we have:
578106f32e7eSjoerg       // @synthesize Foo, Bar;
578206f32e7eSjoerg       // source ranges for both start at '@', so 'Bar' will end up overriding
578306f32e7eSjoerg       // 'Foo' even though the cursor location was at 'Foo'.
578406f32e7eSjoerg       if (Data->VisitedObjCPropertyImplDecl)
578506f32e7eSjoerg         return CXChildVisit_Break;
578606f32e7eSjoerg       Data->VisitedObjCPropertyImplDecl = true;
578706f32e7eSjoerg     }
578806f32e7eSjoerg   }
578906f32e7eSjoerg 
579006f32e7eSjoerg   if (clang_isExpression(cursor.kind) &&
579106f32e7eSjoerg       clang_isDeclaration(BestCursor->kind)) {
579206f32e7eSjoerg     if (const Decl *D = getCursorDecl(*BestCursor)) {
579306f32e7eSjoerg       // Avoid having the cursor of an expression replace the declaration cursor
579406f32e7eSjoerg       // when the expression source range overlaps the declaration range.
579506f32e7eSjoerg       // This can happen for C++ constructor expressions whose range generally
579606f32e7eSjoerg       // include the variable declaration, e.g.:
5797*13fbcb42Sjoerg       //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5798*13fbcb42Sjoerg       //  cursor.
579906f32e7eSjoerg       if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
580006f32e7eSjoerg           D->getLocation() == Data->TokenBeginLoc)
580106f32e7eSjoerg         return CXChildVisit_Break;
580206f32e7eSjoerg     }
580306f32e7eSjoerg   }
580406f32e7eSjoerg 
580506f32e7eSjoerg   // If our current best cursor is the construction of a temporary object,
580606f32e7eSjoerg   // don't replace that cursor with a type reference, because we want
580706f32e7eSjoerg   // clang_getCursor() to point at the constructor.
580806f32e7eSjoerg   if (clang_isExpression(BestCursor->kind) &&
580906f32e7eSjoerg       isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
581006f32e7eSjoerg       cursor.kind == CXCursor_TypeRef) {
581106f32e7eSjoerg     // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
581206f32e7eSjoerg     // as having the actual point on the type reference.
581306f32e7eSjoerg     *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
581406f32e7eSjoerg     return CXChildVisit_Recurse;
581506f32e7eSjoerg   }
581606f32e7eSjoerg 
581706f32e7eSjoerg   // If we already have an Objective-C superclass reference, don't
581806f32e7eSjoerg   // update it further.
581906f32e7eSjoerg   if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
582006f32e7eSjoerg     return CXChildVisit_Break;
582106f32e7eSjoerg 
582206f32e7eSjoerg   *BestCursor = cursor;
582306f32e7eSjoerg   return CXChildVisit_Recurse;
582406f32e7eSjoerg }
582506f32e7eSjoerg 
clang_getCursor(CXTranslationUnit TU,CXSourceLocation Loc)582606f32e7eSjoerg CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
582706f32e7eSjoerg   if (isNotUsableTU(TU)) {
582806f32e7eSjoerg     LOG_BAD_TU(TU);
582906f32e7eSjoerg     return clang_getNullCursor();
583006f32e7eSjoerg   }
583106f32e7eSjoerg 
583206f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
583306f32e7eSjoerg   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
583406f32e7eSjoerg 
583506f32e7eSjoerg   SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
583606f32e7eSjoerg   CXCursor Result = cxcursor::getCursor(TU, SLoc);
583706f32e7eSjoerg 
583806f32e7eSjoerg   LOG_FUNC_SECTION {
583906f32e7eSjoerg     CXFile SearchFile;
584006f32e7eSjoerg     unsigned SearchLine, SearchColumn;
584106f32e7eSjoerg     CXFile ResultFile;
584206f32e7eSjoerg     unsigned ResultLine, ResultColumn;
584306f32e7eSjoerg     CXString SearchFileName, ResultFileName, KindSpelling, USR;
584406f32e7eSjoerg     const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
584506f32e7eSjoerg     CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
584606f32e7eSjoerg 
584706f32e7eSjoerg     clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
584806f32e7eSjoerg                           nullptr);
5849*13fbcb42Sjoerg     clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5850*13fbcb42Sjoerg                           nullptr);
585106f32e7eSjoerg     SearchFileName = clang_getFileName(SearchFile);
585206f32e7eSjoerg     ResultFileName = clang_getFileName(ResultFile);
585306f32e7eSjoerg     KindSpelling = clang_getCursorKindSpelling(Result.kind);
585406f32e7eSjoerg     USR = clang_getCursorUSR(Result);
5855*13fbcb42Sjoerg     *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5856*13fbcb42Sjoerg                          SearchLine, SearchColumn,
585706f32e7eSjoerg                          clang_getCString(KindSpelling))
5858*13fbcb42Sjoerg          << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5859*13fbcb42Sjoerg                          ResultLine, ResultColumn, clang_getCString(USR),
5860*13fbcb42Sjoerg                          IsDef);
586106f32e7eSjoerg     clang_disposeString(SearchFileName);
586206f32e7eSjoerg     clang_disposeString(ResultFileName);
586306f32e7eSjoerg     clang_disposeString(KindSpelling);
586406f32e7eSjoerg     clang_disposeString(USR);
586506f32e7eSjoerg 
586606f32e7eSjoerg     CXCursor Definition = clang_getCursorDefinition(Result);
586706f32e7eSjoerg     if (!clang_equalCursors(Definition, clang_getNullCursor())) {
586806f32e7eSjoerg       CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
5869*13fbcb42Sjoerg       CXString DefinitionKindSpelling =
5870*13fbcb42Sjoerg           clang_getCursorKindSpelling(Definition.kind);
587106f32e7eSjoerg       CXFile DefinitionFile;
587206f32e7eSjoerg       unsigned DefinitionLine, DefinitionColumn;
5873*13fbcb42Sjoerg       clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5874*13fbcb42Sjoerg                             &DefinitionColumn, nullptr);
587506f32e7eSjoerg       CXString DefinitionFileName = clang_getFileName(DefinitionFile);
587606f32e7eSjoerg       *Log << llvm::format("  -> %s(%s:%d:%d)",
587706f32e7eSjoerg                            clang_getCString(DefinitionKindSpelling),
5878*13fbcb42Sjoerg                            clang_getCString(DefinitionFileName), DefinitionLine,
5879*13fbcb42Sjoerg                            DefinitionColumn);
588006f32e7eSjoerg       clang_disposeString(DefinitionFileName);
588106f32e7eSjoerg       clang_disposeString(DefinitionKindSpelling);
588206f32e7eSjoerg     }
588306f32e7eSjoerg   }
588406f32e7eSjoerg 
588506f32e7eSjoerg   return Result;
588606f32e7eSjoerg }
588706f32e7eSjoerg 
clang_getNullCursor(void)588806f32e7eSjoerg CXCursor clang_getNullCursor(void) {
588906f32e7eSjoerg   return MakeCXCursorInvalid(CXCursor_InvalidFile);
589006f32e7eSjoerg }
589106f32e7eSjoerg 
clang_equalCursors(CXCursor X,CXCursor Y)589206f32e7eSjoerg unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
589306f32e7eSjoerg   // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
589406f32e7eSjoerg   // can't set consistently. For example, when visiting a DeclStmt we will set
589506f32e7eSjoerg   // it but we don't set it on the result of clang_getCursorDefinition for
589606f32e7eSjoerg   // a reference of the same declaration.
589706f32e7eSjoerg   // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
589806f32e7eSjoerg   // when visiting a DeclStmt currently, the AST should be enhanced to be able
589906f32e7eSjoerg   // to provide that kind of info.
590006f32e7eSjoerg   if (clang_isDeclaration(X.kind))
590106f32e7eSjoerg     X.data[1] = nullptr;
590206f32e7eSjoerg   if (clang_isDeclaration(Y.kind))
590306f32e7eSjoerg     Y.data[1] = nullptr;
590406f32e7eSjoerg 
590506f32e7eSjoerg   return X == Y;
590606f32e7eSjoerg }
590706f32e7eSjoerg 
clang_hashCursor(CXCursor C)590806f32e7eSjoerg unsigned clang_hashCursor(CXCursor C) {
590906f32e7eSjoerg   unsigned Index = 0;
591006f32e7eSjoerg   if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
591106f32e7eSjoerg     Index = 1;
591206f32e7eSjoerg 
591306f32e7eSjoerg   return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
591406f32e7eSjoerg       std::make_pair(C.kind, C.data[Index]));
591506f32e7eSjoerg }
591606f32e7eSjoerg 
clang_isInvalid(enum CXCursorKind K)591706f32e7eSjoerg unsigned clang_isInvalid(enum CXCursorKind K) {
591806f32e7eSjoerg   return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
591906f32e7eSjoerg }
592006f32e7eSjoerg 
clang_isDeclaration(enum CXCursorKind K)592106f32e7eSjoerg unsigned clang_isDeclaration(enum CXCursorKind K) {
592206f32e7eSjoerg   return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
592306f32e7eSjoerg          (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
592406f32e7eSjoerg }
592506f32e7eSjoerg 
clang_isInvalidDeclaration(CXCursor C)592606f32e7eSjoerg unsigned clang_isInvalidDeclaration(CXCursor C) {
592706f32e7eSjoerg   if (clang_isDeclaration(C.kind)) {
592806f32e7eSjoerg     if (const Decl *D = getCursorDecl(C))
592906f32e7eSjoerg       return D->isInvalidDecl();
593006f32e7eSjoerg   }
593106f32e7eSjoerg 
593206f32e7eSjoerg   return 0;
593306f32e7eSjoerg }
593406f32e7eSjoerg 
clang_isReference(enum CXCursorKind K)593506f32e7eSjoerg unsigned clang_isReference(enum CXCursorKind K) {
593606f32e7eSjoerg   return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
593706f32e7eSjoerg }
593806f32e7eSjoerg 
clang_isExpression(enum CXCursorKind K)593906f32e7eSjoerg unsigned clang_isExpression(enum CXCursorKind K) {
594006f32e7eSjoerg   return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
594106f32e7eSjoerg }
594206f32e7eSjoerg 
clang_isStatement(enum CXCursorKind K)594306f32e7eSjoerg unsigned clang_isStatement(enum CXCursorKind K) {
594406f32e7eSjoerg   return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
594506f32e7eSjoerg }
594606f32e7eSjoerg 
clang_isAttribute(enum CXCursorKind K)594706f32e7eSjoerg unsigned clang_isAttribute(enum CXCursorKind K) {
594806f32e7eSjoerg   return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
594906f32e7eSjoerg }
595006f32e7eSjoerg 
clang_isTranslationUnit(enum CXCursorKind K)595106f32e7eSjoerg unsigned clang_isTranslationUnit(enum CXCursorKind K) {
595206f32e7eSjoerg   return K == CXCursor_TranslationUnit;
595306f32e7eSjoerg }
595406f32e7eSjoerg 
clang_isPreprocessing(enum CXCursorKind K)595506f32e7eSjoerg unsigned clang_isPreprocessing(enum CXCursorKind K) {
595606f32e7eSjoerg   return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
595706f32e7eSjoerg }
595806f32e7eSjoerg 
clang_isUnexposed(enum CXCursorKind K)595906f32e7eSjoerg unsigned clang_isUnexposed(enum CXCursorKind K) {
596006f32e7eSjoerg   switch (K) {
596106f32e7eSjoerg   case CXCursor_UnexposedDecl:
596206f32e7eSjoerg   case CXCursor_UnexposedExpr:
596306f32e7eSjoerg   case CXCursor_UnexposedStmt:
596406f32e7eSjoerg   case CXCursor_UnexposedAttr:
596506f32e7eSjoerg     return true;
596606f32e7eSjoerg   default:
596706f32e7eSjoerg     return false;
596806f32e7eSjoerg   }
596906f32e7eSjoerg }
597006f32e7eSjoerg 
clang_getCursorKind(CXCursor C)5971*13fbcb42Sjoerg CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
597206f32e7eSjoerg 
clang_getCursorLocation(CXCursor C)597306f32e7eSjoerg CXSourceLocation clang_getCursorLocation(CXCursor C) {
597406f32e7eSjoerg   if (clang_isReference(C.kind)) {
597506f32e7eSjoerg     switch (C.kind) {
597606f32e7eSjoerg     case CXCursor_ObjCSuperClassRef: {
5977*13fbcb42Sjoerg       std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5978*13fbcb42Sjoerg           getCursorObjCSuperClassRef(C);
597906f32e7eSjoerg       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
598006f32e7eSjoerg     }
598106f32e7eSjoerg 
598206f32e7eSjoerg     case CXCursor_ObjCProtocolRef: {
5983*13fbcb42Sjoerg       std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5984*13fbcb42Sjoerg           getCursorObjCProtocolRef(C);
598506f32e7eSjoerg       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
598606f32e7eSjoerg     }
598706f32e7eSjoerg 
598806f32e7eSjoerg     case CXCursor_ObjCClassRef: {
5989*13fbcb42Sjoerg       std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5990*13fbcb42Sjoerg           getCursorObjCClassRef(C);
599106f32e7eSjoerg       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
599206f32e7eSjoerg     }
599306f32e7eSjoerg 
599406f32e7eSjoerg     case CXCursor_TypeRef: {
599506f32e7eSjoerg       std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
599606f32e7eSjoerg       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
599706f32e7eSjoerg     }
599806f32e7eSjoerg 
599906f32e7eSjoerg     case CXCursor_TemplateRef: {
600006f32e7eSjoerg       std::pair<const TemplateDecl *, SourceLocation> P =
600106f32e7eSjoerg           getCursorTemplateRef(C);
600206f32e7eSjoerg       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
600306f32e7eSjoerg     }
600406f32e7eSjoerg 
600506f32e7eSjoerg     case CXCursor_NamespaceRef: {
600606f32e7eSjoerg       std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
600706f32e7eSjoerg       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
600806f32e7eSjoerg     }
600906f32e7eSjoerg 
601006f32e7eSjoerg     case CXCursor_MemberRef: {
601106f32e7eSjoerg       std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
601206f32e7eSjoerg       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
601306f32e7eSjoerg     }
601406f32e7eSjoerg 
601506f32e7eSjoerg     case CXCursor_VariableRef: {
601606f32e7eSjoerg       std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
601706f32e7eSjoerg       return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
601806f32e7eSjoerg     }
601906f32e7eSjoerg 
602006f32e7eSjoerg     case CXCursor_CXXBaseSpecifier: {
602106f32e7eSjoerg       const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
602206f32e7eSjoerg       if (!BaseSpec)
602306f32e7eSjoerg         return clang_getNullLocation();
602406f32e7eSjoerg 
602506f32e7eSjoerg       if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
6026*13fbcb42Sjoerg         return cxloc::translateSourceLocation(
6027*13fbcb42Sjoerg             getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
602806f32e7eSjoerg 
602906f32e7eSjoerg       return cxloc::translateSourceLocation(getCursorContext(C),
603006f32e7eSjoerg                                             BaseSpec->getBeginLoc());
603106f32e7eSjoerg     }
603206f32e7eSjoerg 
603306f32e7eSjoerg     case CXCursor_LabelRef: {
603406f32e7eSjoerg       std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
603506f32e7eSjoerg       return cxloc::translateSourceLocation(getCursorContext(C), P.second);
603606f32e7eSjoerg     }
603706f32e7eSjoerg 
603806f32e7eSjoerg     case CXCursor_OverloadedDeclRef:
6039*13fbcb42Sjoerg       return cxloc::translateSourceLocation(
6040*13fbcb42Sjoerg           getCursorContext(C), getCursorOverloadedDeclRef(C).second);
604106f32e7eSjoerg 
604206f32e7eSjoerg     default:
604306f32e7eSjoerg       // FIXME: Need a way to enumerate all non-reference cases.
604406f32e7eSjoerg       llvm_unreachable("Missed a reference kind");
604506f32e7eSjoerg     }
604606f32e7eSjoerg   }
604706f32e7eSjoerg 
604806f32e7eSjoerg   if (clang_isExpression(C.kind))
6049*13fbcb42Sjoerg     return cxloc::translateSourceLocation(
6050*13fbcb42Sjoerg         getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
605106f32e7eSjoerg 
605206f32e7eSjoerg   if (clang_isStatement(C.kind))
605306f32e7eSjoerg     return cxloc::translateSourceLocation(getCursorContext(C),
605406f32e7eSjoerg                                           getCursorStmt(C)->getBeginLoc());
605506f32e7eSjoerg 
605606f32e7eSjoerg   if (C.kind == CXCursor_PreprocessingDirective) {
605706f32e7eSjoerg     SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
605806f32e7eSjoerg     return cxloc::translateSourceLocation(getCursorContext(C), L);
605906f32e7eSjoerg   }
606006f32e7eSjoerg 
606106f32e7eSjoerg   if (C.kind == CXCursor_MacroExpansion) {
6062*13fbcb42Sjoerg     SourceLocation L =
6063*13fbcb42Sjoerg         cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
606406f32e7eSjoerg     return cxloc::translateSourceLocation(getCursorContext(C), L);
606506f32e7eSjoerg   }
606606f32e7eSjoerg 
606706f32e7eSjoerg   if (C.kind == CXCursor_MacroDefinition) {
606806f32e7eSjoerg     SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
606906f32e7eSjoerg     return cxloc::translateSourceLocation(getCursorContext(C), L);
607006f32e7eSjoerg   }
607106f32e7eSjoerg 
607206f32e7eSjoerg   if (C.kind == CXCursor_InclusionDirective) {
6073*13fbcb42Sjoerg     SourceLocation L =
6074*13fbcb42Sjoerg         cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
607506f32e7eSjoerg     return cxloc::translateSourceLocation(getCursorContext(C), L);
607606f32e7eSjoerg   }
607706f32e7eSjoerg 
607806f32e7eSjoerg   if (clang_isAttribute(C.kind)) {
6079*13fbcb42Sjoerg     SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
608006f32e7eSjoerg     return cxloc::translateSourceLocation(getCursorContext(C), L);
608106f32e7eSjoerg   }
608206f32e7eSjoerg 
608306f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
608406f32e7eSjoerg     return clang_getNullLocation();
608506f32e7eSjoerg 
608606f32e7eSjoerg   const Decl *D = getCursorDecl(C);
608706f32e7eSjoerg   if (!D)
608806f32e7eSjoerg     return clang_getNullLocation();
608906f32e7eSjoerg 
609006f32e7eSjoerg   SourceLocation Loc = D->getLocation();
609106f32e7eSjoerg   // FIXME: Multiple variables declared in a single declaration
609206f32e7eSjoerg   // currently lack the information needed to correctly determine their
609306f32e7eSjoerg   // ranges when accounting for the type-specifier.  We use context
609406f32e7eSjoerg   // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
609506f32e7eSjoerg   // and if so, whether it is the first decl.
609606f32e7eSjoerg   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
609706f32e7eSjoerg     if (!cxcursor::isFirstInDeclGroup(C))
609806f32e7eSjoerg       Loc = VD->getLocation();
609906f32e7eSjoerg   }
610006f32e7eSjoerg 
610106f32e7eSjoerg   // For ObjC methods, give the start location of the method name.
610206f32e7eSjoerg   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
610306f32e7eSjoerg     Loc = MD->getSelectorStartLoc();
610406f32e7eSjoerg 
610506f32e7eSjoerg   return cxloc::translateSourceLocation(getCursorContext(C), Loc);
610606f32e7eSjoerg }
610706f32e7eSjoerg 
610806f32e7eSjoerg } // end extern "C"
610906f32e7eSjoerg 
getCursor(CXTranslationUnit TU,SourceLocation SLoc)611006f32e7eSjoerg CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
611106f32e7eSjoerg   assert(TU);
611206f32e7eSjoerg 
611306f32e7eSjoerg   // Guard against an invalid SourceLocation, or we may assert in one
611406f32e7eSjoerg   // of the following calls.
611506f32e7eSjoerg   if (SLoc.isInvalid())
611606f32e7eSjoerg     return clang_getNullCursor();
611706f32e7eSjoerg 
611806f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
611906f32e7eSjoerg 
612006f32e7eSjoerg   // Translate the given source location to make it point at the beginning of
612106f32e7eSjoerg   // the token under the cursor.
612206f32e7eSjoerg   SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
612306f32e7eSjoerg                                     CXXUnit->getASTContext().getLangOpts());
612406f32e7eSjoerg 
612506f32e7eSjoerg   CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
612606f32e7eSjoerg   if (SLoc.isValid()) {
612706f32e7eSjoerg     GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
612806f32e7eSjoerg     CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
612906f32e7eSjoerg                             /*VisitPreprocessorLast=*/true,
613006f32e7eSjoerg                             /*VisitIncludedEntities=*/false,
613106f32e7eSjoerg                             SourceLocation(SLoc));
613206f32e7eSjoerg     CursorVis.visitFileRegion();
613306f32e7eSjoerg   }
613406f32e7eSjoerg 
613506f32e7eSjoerg   return Result;
613606f32e7eSjoerg }
613706f32e7eSjoerg 
getRawCursorExtent(CXCursor C)613806f32e7eSjoerg static SourceRange getRawCursorExtent(CXCursor C) {
613906f32e7eSjoerg   if (clang_isReference(C.kind)) {
614006f32e7eSjoerg     switch (C.kind) {
614106f32e7eSjoerg     case CXCursor_ObjCSuperClassRef:
614206f32e7eSjoerg       return getCursorObjCSuperClassRef(C).second;
614306f32e7eSjoerg 
614406f32e7eSjoerg     case CXCursor_ObjCProtocolRef:
614506f32e7eSjoerg       return getCursorObjCProtocolRef(C).second;
614606f32e7eSjoerg 
614706f32e7eSjoerg     case CXCursor_ObjCClassRef:
614806f32e7eSjoerg       return getCursorObjCClassRef(C).second;
614906f32e7eSjoerg 
615006f32e7eSjoerg     case CXCursor_TypeRef:
615106f32e7eSjoerg       return getCursorTypeRef(C).second;
615206f32e7eSjoerg 
615306f32e7eSjoerg     case CXCursor_TemplateRef:
615406f32e7eSjoerg       return getCursorTemplateRef(C).second;
615506f32e7eSjoerg 
615606f32e7eSjoerg     case CXCursor_NamespaceRef:
615706f32e7eSjoerg       return getCursorNamespaceRef(C).second;
615806f32e7eSjoerg 
615906f32e7eSjoerg     case CXCursor_MemberRef:
616006f32e7eSjoerg       return getCursorMemberRef(C).second;
616106f32e7eSjoerg 
616206f32e7eSjoerg     case CXCursor_CXXBaseSpecifier:
616306f32e7eSjoerg       return getCursorCXXBaseSpecifier(C)->getSourceRange();
616406f32e7eSjoerg 
616506f32e7eSjoerg     case CXCursor_LabelRef:
616606f32e7eSjoerg       return getCursorLabelRef(C).second;
616706f32e7eSjoerg 
616806f32e7eSjoerg     case CXCursor_OverloadedDeclRef:
616906f32e7eSjoerg       return getCursorOverloadedDeclRef(C).second;
617006f32e7eSjoerg 
617106f32e7eSjoerg     case CXCursor_VariableRef:
617206f32e7eSjoerg       return getCursorVariableRef(C).second;
617306f32e7eSjoerg 
617406f32e7eSjoerg     default:
617506f32e7eSjoerg       // FIXME: Need a way to enumerate all non-reference cases.
617606f32e7eSjoerg       llvm_unreachable("Missed a reference kind");
617706f32e7eSjoerg     }
617806f32e7eSjoerg   }
617906f32e7eSjoerg 
618006f32e7eSjoerg   if (clang_isExpression(C.kind))
618106f32e7eSjoerg     return getCursorExpr(C)->getSourceRange();
618206f32e7eSjoerg 
618306f32e7eSjoerg   if (clang_isStatement(C.kind))
618406f32e7eSjoerg     return getCursorStmt(C)->getSourceRange();
618506f32e7eSjoerg 
618606f32e7eSjoerg   if (clang_isAttribute(C.kind))
618706f32e7eSjoerg     return getCursorAttr(C)->getRange();
618806f32e7eSjoerg 
618906f32e7eSjoerg   if (C.kind == CXCursor_PreprocessingDirective)
619006f32e7eSjoerg     return cxcursor::getCursorPreprocessingDirective(C);
619106f32e7eSjoerg 
619206f32e7eSjoerg   if (C.kind == CXCursor_MacroExpansion) {
619306f32e7eSjoerg     ASTUnit *TU = getCursorASTUnit(C);
619406f32e7eSjoerg     SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
619506f32e7eSjoerg     return TU->mapRangeFromPreamble(Range);
619606f32e7eSjoerg   }
619706f32e7eSjoerg 
619806f32e7eSjoerg   if (C.kind == CXCursor_MacroDefinition) {
619906f32e7eSjoerg     ASTUnit *TU = getCursorASTUnit(C);
620006f32e7eSjoerg     SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
620106f32e7eSjoerg     return TU->mapRangeFromPreamble(Range);
620206f32e7eSjoerg   }
620306f32e7eSjoerg 
620406f32e7eSjoerg   if (C.kind == CXCursor_InclusionDirective) {
620506f32e7eSjoerg     ASTUnit *TU = getCursorASTUnit(C);
6206*13fbcb42Sjoerg     SourceRange Range =
6207*13fbcb42Sjoerg         cxcursor::getCursorInclusionDirective(C)->getSourceRange();
620806f32e7eSjoerg     return TU->mapRangeFromPreamble(Range);
620906f32e7eSjoerg   }
621006f32e7eSjoerg 
621106f32e7eSjoerg   if (C.kind == CXCursor_TranslationUnit) {
621206f32e7eSjoerg     ASTUnit *TU = getCursorASTUnit(C);
621306f32e7eSjoerg     FileID MainID = TU->getSourceManager().getMainFileID();
621406f32e7eSjoerg     SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
621506f32e7eSjoerg     SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
621606f32e7eSjoerg     return SourceRange(Start, End);
621706f32e7eSjoerg   }
621806f32e7eSjoerg 
621906f32e7eSjoerg   if (clang_isDeclaration(C.kind)) {
622006f32e7eSjoerg     const Decl *D = cxcursor::getCursorDecl(C);
622106f32e7eSjoerg     if (!D)
622206f32e7eSjoerg       return SourceRange();
622306f32e7eSjoerg 
622406f32e7eSjoerg     SourceRange R = D->getSourceRange();
622506f32e7eSjoerg     // FIXME: Multiple variables declared in a single declaration
622606f32e7eSjoerg     // currently lack the information needed to correctly determine their
622706f32e7eSjoerg     // ranges when accounting for the type-specifier.  We use context
622806f32e7eSjoerg     // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
622906f32e7eSjoerg     // and if so, whether it is the first decl.
623006f32e7eSjoerg     if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
623106f32e7eSjoerg       if (!cxcursor::isFirstInDeclGroup(C))
623206f32e7eSjoerg         R.setBegin(VD->getLocation());
623306f32e7eSjoerg     }
623406f32e7eSjoerg     return R;
623506f32e7eSjoerg   }
623606f32e7eSjoerg   return SourceRange();
623706f32e7eSjoerg }
623806f32e7eSjoerg 
623906f32e7eSjoerg /// Retrieves the "raw" cursor extent, which is then extended to include
624006f32e7eSjoerg /// the decl-specifier-seq for declarations.
getFullCursorExtent(CXCursor C,SourceManager & SrcMgr)624106f32e7eSjoerg static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
624206f32e7eSjoerg   if (clang_isDeclaration(C.kind)) {
624306f32e7eSjoerg     const Decl *D = cxcursor::getCursorDecl(C);
624406f32e7eSjoerg     if (!D)
624506f32e7eSjoerg       return SourceRange();
624606f32e7eSjoerg 
624706f32e7eSjoerg     SourceRange R = D->getSourceRange();
624806f32e7eSjoerg 
624906f32e7eSjoerg     // Adjust the start of the location for declarations preceded by
625006f32e7eSjoerg     // declaration specifiers.
625106f32e7eSjoerg     SourceLocation StartLoc;
625206f32e7eSjoerg     if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
625306f32e7eSjoerg       if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
625406f32e7eSjoerg         StartLoc = TI->getTypeLoc().getBeginLoc();
625506f32e7eSjoerg     } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
625606f32e7eSjoerg       if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
625706f32e7eSjoerg         StartLoc = TI->getTypeLoc().getBeginLoc();
625806f32e7eSjoerg     }
625906f32e7eSjoerg 
626006f32e7eSjoerg     if (StartLoc.isValid() && R.getBegin().isValid() &&
626106f32e7eSjoerg         SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
626206f32e7eSjoerg       R.setBegin(StartLoc);
626306f32e7eSjoerg 
626406f32e7eSjoerg     // FIXME: Multiple variables declared in a single declaration
626506f32e7eSjoerg     // currently lack the information needed to correctly determine their
626606f32e7eSjoerg     // ranges when accounting for the type-specifier.  We use context
626706f32e7eSjoerg     // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
626806f32e7eSjoerg     // and if so, whether it is the first decl.
626906f32e7eSjoerg     if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
627006f32e7eSjoerg       if (!cxcursor::isFirstInDeclGroup(C))
627106f32e7eSjoerg         R.setBegin(VD->getLocation());
627206f32e7eSjoerg     }
627306f32e7eSjoerg 
627406f32e7eSjoerg     return R;
627506f32e7eSjoerg   }
627606f32e7eSjoerg 
627706f32e7eSjoerg   return getRawCursorExtent(C);
627806f32e7eSjoerg }
627906f32e7eSjoerg 
clang_getCursorExtent(CXCursor C)628006f32e7eSjoerg CXSourceRange clang_getCursorExtent(CXCursor C) {
628106f32e7eSjoerg   SourceRange R = getRawCursorExtent(C);
628206f32e7eSjoerg   if (R.isInvalid())
628306f32e7eSjoerg     return clang_getNullRange();
628406f32e7eSjoerg 
628506f32e7eSjoerg   return cxloc::translateSourceRange(getCursorContext(C), R);
628606f32e7eSjoerg }
628706f32e7eSjoerg 
clang_getCursorReferenced(CXCursor C)628806f32e7eSjoerg CXCursor clang_getCursorReferenced(CXCursor C) {
628906f32e7eSjoerg   if (clang_isInvalid(C.kind))
629006f32e7eSjoerg     return clang_getNullCursor();
629106f32e7eSjoerg 
629206f32e7eSjoerg   CXTranslationUnit tu = getCursorTU(C);
629306f32e7eSjoerg   if (clang_isDeclaration(C.kind)) {
629406f32e7eSjoerg     const Decl *D = getCursorDecl(C);
629506f32e7eSjoerg     if (!D)
629606f32e7eSjoerg       return clang_getNullCursor();
629706f32e7eSjoerg     if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
629806f32e7eSjoerg       return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
629906f32e7eSjoerg     if (const ObjCPropertyImplDecl *PropImpl =
630006f32e7eSjoerg             dyn_cast<ObjCPropertyImplDecl>(D))
630106f32e7eSjoerg       if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
630206f32e7eSjoerg         return MakeCXCursor(Property, tu);
630306f32e7eSjoerg 
630406f32e7eSjoerg     return C;
630506f32e7eSjoerg   }
630606f32e7eSjoerg 
630706f32e7eSjoerg   if (clang_isExpression(C.kind)) {
630806f32e7eSjoerg     const Expr *E = getCursorExpr(C);
630906f32e7eSjoerg     const Decl *D = getDeclFromExpr(E);
631006f32e7eSjoerg     if (D) {
631106f32e7eSjoerg       CXCursor declCursor = MakeCXCursor(D, tu);
631206f32e7eSjoerg       declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
631306f32e7eSjoerg                                                declCursor);
631406f32e7eSjoerg       return declCursor;
631506f32e7eSjoerg     }
631606f32e7eSjoerg 
631706f32e7eSjoerg     if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
631806f32e7eSjoerg       return MakeCursorOverloadedDeclRef(Ovl, tu);
631906f32e7eSjoerg 
632006f32e7eSjoerg     return clang_getNullCursor();
632106f32e7eSjoerg   }
632206f32e7eSjoerg 
632306f32e7eSjoerg   if (clang_isStatement(C.kind)) {
632406f32e7eSjoerg     const Stmt *S = getCursorStmt(C);
632506f32e7eSjoerg     if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
632606f32e7eSjoerg       if (LabelDecl *label = Goto->getLabel())
632706f32e7eSjoerg         if (LabelStmt *labelS = label->getStmt())
632806f32e7eSjoerg           return MakeCXCursor(labelS, getCursorDecl(C), tu);
632906f32e7eSjoerg 
633006f32e7eSjoerg     return clang_getNullCursor();
633106f32e7eSjoerg   }
633206f32e7eSjoerg 
633306f32e7eSjoerg   if (C.kind == CXCursor_MacroExpansion) {
633406f32e7eSjoerg     if (const MacroDefinitionRecord *Def =
633506f32e7eSjoerg             getCursorMacroExpansion(C).getDefinition())
633606f32e7eSjoerg       return MakeMacroDefinitionCursor(Def, tu);
633706f32e7eSjoerg   }
633806f32e7eSjoerg 
633906f32e7eSjoerg   if (!clang_isReference(C.kind))
634006f32e7eSjoerg     return clang_getNullCursor();
634106f32e7eSjoerg 
634206f32e7eSjoerg   switch (C.kind) {
634306f32e7eSjoerg   case CXCursor_ObjCSuperClassRef:
634406f32e7eSjoerg     return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
634506f32e7eSjoerg 
634606f32e7eSjoerg   case CXCursor_ObjCProtocolRef: {
634706f32e7eSjoerg     const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
634806f32e7eSjoerg     if (const ObjCProtocolDecl *Def = Prot->getDefinition())
634906f32e7eSjoerg       return MakeCXCursor(Def, tu);
635006f32e7eSjoerg 
635106f32e7eSjoerg     return MakeCXCursor(Prot, tu);
635206f32e7eSjoerg   }
635306f32e7eSjoerg 
635406f32e7eSjoerg   case CXCursor_ObjCClassRef: {
635506f32e7eSjoerg     const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
635606f32e7eSjoerg     if (const ObjCInterfaceDecl *Def = Class->getDefinition())
635706f32e7eSjoerg       return MakeCXCursor(Def, tu);
635806f32e7eSjoerg 
635906f32e7eSjoerg     return MakeCXCursor(Class, tu);
636006f32e7eSjoerg   }
636106f32e7eSjoerg 
636206f32e7eSjoerg   case CXCursor_TypeRef:
636306f32e7eSjoerg     return MakeCXCursor(getCursorTypeRef(C).first, tu);
636406f32e7eSjoerg 
636506f32e7eSjoerg   case CXCursor_TemplateRef:
636606f32e7eSjoerg     return MakeCXCursor(getCursorTemplateRef(C).first, tu);
636706f32e7eSjoerg 
636806f32e7eSjoerg   case CXCursor_NamespaceRef:
636906f32e7eSjoerg     return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
637006f32e7eSjoerg 
637106f32e7eSjoerg   case CXCursor_MemberRef:
637206f32e7eSjoerg     return MakeCXCursor(getCursorMemberRef(C).first, tu);
637306f32e7eSjoerg 
637406f32e7eSjoerg   case CXCursor_CXXBaseSpecifier: {
637506f32e7eSjoerg     const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6376*13fbcb42Sjoerg     return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
637706f32e7eSjoerg   }
637806f32e7eSjoerg 
637906f32e7eSjoerg   case CXCursor_LabelRef:
638006f32e7eSjoerg     // FIXME: We end up faking the "parent" declaration here because we
638106f32e7eSjoerg     // don't want to make CXCursor larger.
6382*13fbcb42Sjoerg     return MakeCXCursor(
6383*13fbcb42Sjoerg         getCursorLabelRef(C).first,
6384*13fbcb42Sjoerg         cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
638506f32e7eSjoerg 
638606f32e7eSjoerg   case CXCursor_OverloadedDeclRef:
638706f32e7eSjoerg     return C;
638806f32e7eSjoerg 
638906f32e7eSjoerg   case CXCursor_VariableRef:
639006f32e7eSjoerg     return MakeCXCursor(getCursorVariableRef(C).first, tu);
639106f32e7eSjoerg 
639206f32e7eSjoerg   default:
639306f32e7eSjoerg     // We would prefer to enumerate all non-reference cursor kinds here.
639406f32e7eSjoerg     llvm_unreachable("Unhandled reference cursor kind");
639506f32e7eSjoerg   }
639606f32e7eSjoerg }
639706f32e7eSjoerg 
clang_getCursorDefinition(CXCursor C)639806f32e7eSjoerg CXCursor clang_getCursorDefinition(CXCursor C) {
639906f32e7eSjoerg   if (clang_isInvalid(C.kind))
640006f32e7eSjoerg     return clang_getNullCursor();
640106f32e7eSjoerg 
640206f32e7eSjoerg   CXTranslationUnit TU = getCursorTU(C);
640306f32e7eSjoerg 
640406f32e7eSjoerg   bool WasReference = false;
640506f32e7eSjoerg   if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
640606f32e7eSjoerg     C = clang_getCursorReferenced(C);
640706f32e7eSjoerg     WasReference = true;
640806f32e7eSjoerg   }
640906f32e7eSjoerg 
641006f32e7eSjoerg   if (C.kind == CXCursor_MacroExpansion)
641106f32e7eSjoerg     return clang_getCursorReferenced(C);
641206f32e7eSjoerg 
641306f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
641406f32e7eSjoerg     return clang_getNullCursor();
641506f32e7eSjoerg 
641606f32e7eSjoerg   const Decl *D = getCursorDecl(C);
641706f32e7eSjoerg   if (!D)
641806f32e7eSjoerg     return clang_getNullCursor();
641906f32e7eSjoerg 
642006f32e7eSjoerg   switch (D->getKind()) {
642106f32e7eSjoerg   // Declaration kinds that don't really separate the notions of
642206f32e7eSjoerg   // declaration and definition.
642306f32e7eSjoerg   case Decl::Namespace:
642406f32e7eSjoerg   case Decl::Typedef:
642506f32e7eSjoerg   case Decl::TypeAlias:
642606f32e7eSjoerg   case Decl::TypeAliasTemplate:
642706f32e7eSjoerg   case Decl::TemplateTypeParm:
642806f32e7eSjoerg   case Decl::EnumConstant:
642906f32e7eSjoerg   case Decl::Field:
643006f32e7eSjoerg   case Decl::Binding:
643106f32e7eSjoerg   case Decl::MSProperty:
6432*13fbcb42Sjoerg   case Decl::MSGuid:
6433*13fbcb42Sjoerg   case Decl::TemplateParamObject:
643406f32e7eSjoerg   case Decl::IndirectField:
643506f32e7eSjoerg   case Decl::ObjCIvar:
643606f32e7eSjoerg   case Decl::ObjCAtDefsField:
643706f32e7eSjoerg   case Decl::ImplicitParam:
643806f32e7eSjoerg   case Decl::ParmVar:
643906f32e7eSjoerg   case Decl::NonTypeTemplateParm:
644006f32e7eSjoerg   case Decl::TemplateTemplateParm:
644106f32e7eSjoerg   case Decl::ObjCCategoryImpl:
644206f32e7eSjoerg   case Decl::ObjCImplementation:
644306f32e7eSjoerg   case Decl::AccessSpec:
644406f32e7eSjoerg   case Decl::LinkageSpec:
644506f32e7eSjoerg   case Decl::Export:
644606f32e7eSjoerg   case Decl::ObjCPropertyImpl:
644706f32e7eSjoerg   case Decl::FileScopeAsm:
644806f32e7eSjoerg   case Decl::StaticAssert:
644906f32e7eSjoerg   case Decl::Block:
645006f32e7eSjoerg   case Decl::Captured:
645106f32e7eSjoerg   case Decl::OMPCapturedExpr:
645206f32e7eSjoerg   case Decl::Label: // FIXME: Is this right??
645306f32e7eSjoerg   case Decl::ClassScopeFunctionSpecialization:
645406f32e7eSjoerg   case Decl::CXXDeductionGuide:
645506f32e7eSjoerg   case Decl::Import:
645606f32e7eSjoerg   case Decl::OMPThreadPrivate:
645706f32e7eSjoerg   case Decl::OMPAllocate:
645806f32e7eSjoerg   case Decl::OMPDeclareReduction:
645906f32e7eSjoerg   case Decl::OMPDeclareMapper:
646006f32e7eSjoerg   case Decl::OMPRequires:
646106f32e7eSjoerg   case Decl::ObjCTypeParam:
646206f32e7eSjoerg   case Decl::BuiltinTemplate:
646306f32e7eSjoerg   case Decl::PragmaComment:
646406f32e7eSjoerg   case Decl::PragmaDetectMismatch:
646506f32e7eSjoerg   case Decl::UsingPack:
646606f32e7eSjoerg   case Decl::Concept:
6467*13fbcb42Sjoerg   case Decl::LifetimeExtendedTemporary:
6468*13fbcb42Sjoerg   case Decl::RequiresExprBody:
646906f32e7eSjoerg     return C;
647006f32e7eSjoerg 
647106f32e7eSjoerg   // Declaration kinds that don't make any sense here, but are
647206f32e7eSjoerg   // nonetheless harmless.
647306f32e7eSjoerg   case Decl::Empty:
647406f32e7eSjoerg   case Decl::TranslationUnit:
647506f32e7eSjoerg   case Decl::ExternCContext:
647606f32e7eSjoerg     break;
647706f32e7eSjoerg 
647806f32e7eSjoerg   // Declaration kinds for which the definition is not resolvable.
647906f32e7eSjoerg   case Decl::UnresolvedUsingTypename:
648006f32e7eSjoerg   case Decl::UnresolvedUsingValue:
648106f32e7eSjoerg     break;
648206f32e7eSjoerg 
648306f32e7eSjoerg   case Decl::UsingDirective:
648406f32e7eSjoerg     return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
648506f32e7eSjoerg                         TU);
648606f32e7eSjoerg 
648706f32e7eSjoerg   case Decl::NamespaceAlias:
648806f32e7eSjoerg     return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
648906f32e7eSjoerg 
649006f32e7eSjoerg   case Decl::Enum:
649106f32e7eSjoerg   case Decl::Record:
649206f32e7eSjoerg   case Decl::CXXRecord:
649306f32e7eSjoerg   case Decl::ClassTemplateSpecialization:
649406f32e7eSjoerg   case Decl::ClassTemplatePartialSpecialization:
649506f32e7eSjoerg     if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
649606f32e7eSjoerg       return MakeCXCursor(Def, TU);
649706f32e7eSjoerg     return clang_getNullCursor();
649806f32e7eSjoerg 
649906f32e7eSjoerg   case Decl::Function:
650006f32e7eSjoerg   case Decl::CXXMethod:
650106f32e7eSjoerg   case Decl::CXXConstructor:
650206f32e7eSjoerg   case Decl::CXXDestructor:
650306f32e7eSjoerg   case Decl::CXXConversion: {
650406f32e7eSjoerg     const FunctionDecl *Def = nullptr;
650506f32e7eSjoerg     if (cast<FunctionDecl>(D)->getBody(Def))
650606f32e7eSjoerg       return MakeCXCursor(Def, TU);
650706f32e7eSjoerg     return clang_getNullCursor();
650806f32e7eSjoerg   }
650906f32e7eSjoerg 
651006f32e7eSjoerg   case Decl::Var:
651106f32e7eSjoerg   case Decl::VarTemplateSpecialization:
651206f32e7eSjoerg   case Decl::VarTemplatePartialSpecialization:
651306f32e7eSjoerg   case Decl::Decomposition: {
651406f32e7eSjoerg     // Ask the variable if it has a definition.
651506f32e7eSjoerg     if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
651606f32e7eSjoerg       return MakeCXCursor(Def, TU);
651706f32e7eSjoerg     return clang_getNullCursor();
651806f32e7eSjoerg   }
651906f32e7eSjoerg 
652006f32e7eSjoerg   case Decl::FunctionTemplate: {
652106f32e7eSjoerg     const FunctionDecl *Def = nullptr;
652206f32e7eSjoerg     if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
652306f32e7eSjoerg       return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
652406f32e7eSjoerg     return clang_getNullCursor();
652506f32e7eSjoerg   }
652606f32e7eSjoerg 
652706f32e7eSjoerg   case Decl::ClassTemplate: {
6528*13fbcb42Sjoerg     if (RecordDecl *Def =
6529*13fbcb42Sjoerg             cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
653006f32e7eSjoerg       return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
653106f32e7eSjoerg                           TU);
653206f32e7eSjoerg     return clang_getNullCursor();
653306f32e7eSjoerg   }
653406f32e7eSjoerg 
653506f32e7eSjoerg   case Decl::VarTemplate: {
653606f32e7eSjoerg     if (VarDecl *Def =
653706f32e7eSjoerg             cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
653806f32e7eSjoerg       return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
653906f32e7eSjoerg     return clang_getNullCursor();
654006f32e7eSjoerg   }
654106f32e7eSjoerg 
654206f32e7eSjoerg   case Decl::Using:
6543*13fbcb42Sjoerg     return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6544*13fbcb42Sjoerg                                        TU);
654506f32e7eSjoerg 
654606f32e7eSjoerg   case Decl::UsingShadow:
654706f32e7eSjoerg   case Decl::ConstructorUsingShadow:
654806f32e7eSjoerg     return clang_getCursorDefinition(
6549*13fbcb42Sjoerg         MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
655006f32e7eSjoerg 
655106f32e7eSjoerg   case Decl::ObjCMethod: {
655206f32e7eSjoerg     const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
655306f32e7eSjoerg     if (Method->isThisDeclarationADefinition())
655406f32e7eSjoerg       return C;
655506f32e7eSjoerg 
655606f32e7eSjoerg     // Dig out the method definition in the associated
655706f32e7eSjoerg     // @implementation, if we have it.
655806f32e7eSjoerg     // FIXME: The ASTs should make finding the definition easier.
6559*13fbcb42Sjoerg     if (const ObjCInterfaceDecl *Class =
6560*13fbcb42Sjoerg             dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
656106f32e7eSjoerg       if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
6562*13fbcb42Sjoerg         if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6563*13fbcb42Sjoerg                 Method->getSelector(), Method->isInstanceMethod()))
656406f32e7eSjoerg           if (Def->isThisDeclarationADefinition())
656506f32e7eSjoerg             return MakeCXCursor(Def, TU);
656606f32e7eSjoerg 
656706f32e7eSjoerg     return clang_getNullCursor();
656806f32e7eSjoerg   }
656906f32e7eSjoerg 
657006f32e7eSjoerg   case Decl::ObjCCategory:
6571*13fbcb42Sjoerg     if (ObjCCategoryImplDecl *Impl =
6572*13fbcb42Sjoerg             cast<ObjCCategoryDecl>(D)->getImplementation())
657306f32e7eSjoerg       return MakeCXCursor(Impl, TU);
657406f32e7eSjoerg     return clang_getNullCursor();
657506f32e7eSjoerg 
657606f32e7eSjoerg   case Decl::ObjCProtocol:
6577*13fbcb42Sjoerg     if (const ObjCProtocolDecl *Def =
6578*13fbcb42Sjoerg             cast<ObjCProtocolDecl>(D)->getDefinition())
657906f32e7eSjoerg       return MakeCXCursor(Def, TU);
658006f32e7eSjoerg     return clang_getNullCursor();
658106f32e7eSjoerg 
658206f32e7eSjoerg   case Decl::ObjCInterface: {
658306f32e7eSjoerg     // There are two notions of a "definition" for an Objective-C
658406f32e7eSjoerg     // class: the interface and its implementation. When we resolved a
658506f32e7eSjoerg     // reference to an Objective-C class, produce the @interface as
658606f32e7eSjoerg     // the definition; when we were provided with the interface,
658706f32e7eSjoerg     // produce the @implementation as the definition.
658806f32e7eSjoerg     const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
658906f32e7eSjoerg     if (WasReference) {
659006f32e7eSjoerg       if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
659106f32e7eSjoerg         return MakeCXCursor(Def, TU);
659206f32e7eSjoerg     } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
659306f32e7eSjoerg       return MakeCXCursor(Impl, TU);
659406f32e7eSjoerg     return clang_getNullCursor();
659506f32e7eSjoerg   }
659606f32e7eSjoerg 
659706f32e7eSjoerg   case Decl::ObjCProperty:
659806f32e7eSjoerg     // FIXME: We don't really know where to find the
659906f32e7eSjoerg     // ObjCPropertyImplDecls that implement this property.
660006f32e7eSjoerg     return clang_getNullCursor();
660106f32e7eSjoerg 
660206f32e7eSjoerg   case Decl::ObjCCompatibleAlias:
6603*13fbcb42Sjoerg     if (const ObjCInterfaceDecl *Class =
6604*13fbcb42Sjoerg             cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
660506f32e7eSjoerg       if (const ObjCInterfaceDecl *Def = Class->getDefinition())
660606f32e7eSjoerg         return MakeCXCursor(Def, TU);
660706f32e7eSjoerg 
660806f32e7eSjoerg     return clang_getNullCursor();
660906f32e7eSjoerg 
661006f32e7eSjoerg   case Decl::Friend:
661106f32e7eSjoerg     if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
661206f32e7eSjoerg       return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
661306f32e7eSjoerg     return clang_getNullCursor();
661406f32e7eSjoerg 
661506f32e7eSjoerg   case Decl::FriendTemplate:
661606f32e7eSjoerg     if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
661706f32e7eSjoerg       return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
661806f32e7eSjoerg     return clang_getNullCursor();
661906f32e7eSjoerg   }
662006f32e7eSjoerg 
662106f32e7eSjoerg   return clang_getNullCursor();
662206f32e7eSjoerg }
662306f32e7eSjoerg 
clang_isCursorDefinition(CXCursor C)662406f32e7eSjoerg unsigned clang_isCursorDefinition(CXCursor C) {
662506f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
662606f32e7eSjoerg     return 0;
662706f32e7eSjoerg 
662806f32e7eSjoerg   return clang_getCursorDefinition(C) == C;
662906f32e7eSjoerg }
663006f32e7eSjoerg 
clang_getCanonicalCursor(CXCursor C)663106f32e7eSjoerg CXCursor clang_getCanonicalCursor(CXCursor C) {
663206f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
663306f32e7eSjoerg     return C;
663406f32e7eSjoerg 
663506f32e7eSjoerg   if (const Decl *D = getCursorDecl(C)) {
6636*13fbcb42Sjoerg     if (const ObjCCategoryImplDecl *CatImplD =
6637*13fbcb42Sjoerg             dyn_cast<ObjCCategoryImplDecl>(D))
663806f32e7eSjoerg       if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
663906f32e7eSjoerg         return MakeCXCursor(CatD, getCursorTU(C));
664006f32e7eSjoerg 
664106f32e7eSjoerg     if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
664206f32e7eSjoerg       if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
664306f32e7eSjoerg         return MakeCXCursor(IFD, getCursorTU(C));
664406f32e7eSjoerg 
664506f32e7eSjoerg     return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
664606f32e7eSjoerg   }
664706f32e7eSjoerg 
664806f32e7eSjoerg   return C;
664906f32e7eSjoerg }
665006f32e7eSjoerg 
clang_Cursor_getObjCSelectorIndex(CXCursor cursor)665106f32e7eSjoerg int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
665206f32e7eSjoerg   return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
665306f32e7eSjoerg }
665406f32e7eSjoerg 
clang_getNumOverloadedDecls(CXCursor C)665506f32e7eSjoerg unsigned clang_getNumOverloadedDecls(CXCursor C) {
665606f32e7eSjoerg   if (C.kind != CXCursor_OverloadedDeclRef)
665706f32e7eSjoerg     return 0;
665806f32e7eSjoerg 
665906f32e7eSjoerg   OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
666006f32e7eSjoerg   if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
666106f32e7eSjoerg     return E->getNumDecls();
666206f32e7eSjoerg 
6663*13fbcb42Sjoerg   if (OverloadedTemplateStorage *S =
6664*13fbcb42Sjoerg           Storage.dyn_cast<OverloadedTemplateStorage *>())
666506f32e7eSjoerg     return S->size();
666606f32e7eSjoerg 
666706f32e7eSjoerg   const Decl *D = Storage.get<const Decl *>();
666806f32e7eSjoerg   if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
666906f32e7eSjoerg     return Using->shadow_size();
667006f32e7eSjoerg 
667106f32e7eSjoerg   return 0;
667206f32e7eSjoerg }
667306f32e7eSjoerg 
clang_getOverloadedDecl(CXCursor cursor,unsigned index)667406f32e7eSjoerg CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
667506f32e7eSjoerg   if (cursor.kind != CXCursor_OverloadedDeclRef)
667606f32e7eSjoerg     return clang_getNullCursor();
667706f32e7eSjoerg 
667806f32e7eSjoerg   if (index >= clang_getNumOverloadedDecls(cursor))
667906f32e7eSjoerg     return clang_getNullCursor();
668006f32e7eSjoerg 
668106f32e7eSjoerg   CXTranslationUnit TU = getCursorTU(cursor);
668206f32e7eSjoerg   OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
668306f32e7eSjoerg   if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
668406f32e7eSjoerg     return MakeCXCursor(E->decls_begin()[index], TU);
668506f32e7eSjoerg 
6686*13fbcb42Sjoerg   if (OverloadedTemplateStorage *S =
6687*13fbcb42Sjoerg           Storage.dyn_cast<OverloadedTemplateStorage *>())
668806f32e7eSjoerg     return MakeCXCursor(S->begin()[index], TU);
668906f32e7eSjoerg 
669006f32e7eSjoerg   const Decl *D = Storage.get<const Decl *>();
669106f32e7eSjoerg   if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
669206f32e7eSjoerg     // FIXME: This is, unfortunately, linear time.
669306f32e7eSjoerg     UsingDecl::shadow_iterator Pos = Using->shadow_begin();
669406f32e7eSjoerg     std::advance(Pos, index);
669506f32e7eSjoerg     return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
669606f32e7eSjoerg   }
669706f32e7eSjoerg 
669806f32e7eSjoerg   return clang_getNullCursor();
669906f32e7eSjoerg }
670006f32e7eSjoerg 
clang_getDefinitionSpellingAndExtent(CXCursor C,const char ** startBuf,const char ** endBuf,unsigned * startLine,unsigned * startColumn,unsigned * endLine,unsigned * endColumn)6701*13fbcb42Sjoerg void clang_getDefinitionSpellingAndExtent(
6702*13fbcb42Sjoerg     CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6703*13fbcb42Sjoerg     unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
670406f32e7eSjoerg   assert(getCursorDecl(C) && "CXCursor has null decl");
670506f32e7eSjoerg   const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
670606f32e7eSjoerg   CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
670706f32e7eSjoerg 
670806f32e7eSjoerg   SourceManager &SM = FD->getASTContext().getSourceManager();
670906f32e7eSjoerg   *startBuf = SM.getCharacterData(Body->getLBracLoc());
671006f32e7eSjoerg   *endBuf = SM.getCharacterData(Body->getRBracLoc());
671106f32e7eSjoerg   *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
671206f32e7eSjoerg   *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
671306f32e7eSjoerg   *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
671406f32e7eSjoerg   *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
671506f32e7eSjoerg }
671606f32e7eSjoerg 
clang_getCursorReferenceNameRange(CXCursor C,unsigned NameFlags,unsigned PieceIndex)671706f32e7eSjoerg CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
671806f32e7eSjoerg                                                 unsigned PieceIndex) {
671906f32e7eSjoerg   RefNamePieces Pieces;
672006f32e7eSjoerg 
672106f32e7eSjoerg   switch (C.kind) {
672206f32e7eSjoerg   case CXCursor_MemberRefExpr:
672306f32e7eSjoerg     if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
672406f32e7eSjoerg       Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
672506f32e7eSjoerg                            E->getQualifierLoc().getSourceRange());
672606f32e7eSjoerg     break;
672706f32e7eSjoerg 
672806f32e7eSjoerg   case CXCursor_DeclRefExpr:
672906f32e7eSjoerg     if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
673006f32e7eSjoerg       SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
673106f32e7eSjoerg       Pieces =
673206f32e7eSjoerg           buildPieces(NameFlags, false, E->getNameInfo(),
673306f32e7eSjoerg                       E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
673406f32e7eSjoerg     }
673506f32e7eSjoerg     break;
673606f32e7eSjoerg 
673706f32e7eSjoerg   case CXCursor_CallExpr:
673806f32e7eSjoerg     if (const CXXOperatorCallExpr *OCE =
673906f32e7eSjoerg             dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
674006f32e7eSjoerg       const Expr *Callee = OCE->getCallee();
674106f32e7eSjoerg       if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
674206f32e7eSjoerg         Callee = ICE->getSubExpr();
674306f32e7eSjoerg 
674406f32e7eSjoerg       if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
674506f32e7eSjoerg         Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
674606f32e7eSjoerg                              DRE->getQualifierLoc().getSourceRange());
674706f32e7eSjoerg     }
674806f32e7eSjoerg     break;
674906f32e7eSjoerg 
675006f32e7eSjoerg   default:
675106f32e7eSjoerg     break;
675206f32e7eSjoerg   }
675306f32e7eSjoerg 
675406f32e7eSjoerg   if (Pieces.empty()) {
675506f32e7eSjoerg     if (PieceIndex == 0)
675606f32e7eSjoerg       return clang_getCursorExtent(C);
675706f32e7eSjoerg   } else if (PieceIndex < Pieces.size()) {
675806f32e7eSjoerg     SourceRange R = Pieces[PieceIndex];
675906f32e7eSjoerg     if (R.isValid())
676006f32e7eSjoerg       return cxloc::translateSourceRange(getCursorContext(C), R);
676106f32e7eSjoerg   }
676206f32e7eSjoerg 
676306f32e7eSjoerg   return clang_getNullRange();
676406f32e7eSjoerg }
676506f32e7eSjoerg 
clang_enableStackTraces(void)676606f32e7eSjoerg void clang_enableStackTraces(void) {
676706f32e7eSjoerg   // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
676806f32e7eSjoerg   llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
676906f32e7eSjoerg }
677006f32e7eSjoerg 
clang_executeOnThread(void (* fn)(void *),void * user_data,unsigned stack_size)677106f32e7eSjoerg void clang_executeOnThread(void (*fn)(void *), void *user_data,
677206f32e7eSjoerg                            unsigned stack_size) {
6773*13fbcb42Sjoerg   llvm::llvm_execute_on_thread(fn, user_data,
6774*13fbcb42Sjoerg                                stack_size == 0
6775*13fbcb42Sjoerg                                    ? clang::DesiredStackSize
6776*13fbcb42Sjoerg                                    : llvm::Optional<unsigned>(stack_size));
677706f32e7eSjoerg }
677806f32e7eSjoerg 
677906f32e7eSjoerg //===----------------------------------------------------------------------===//
678006f32e7eSjoerg // Token-based Operations.
678106f32e7eSjoerg //===----------------------------------------------------------------------===//
678206f32e7eSjoerg 
678306f32e7eSjoerg /* CXToken layout:
678406f32e7eSjoerg  *   int_data[0]: a CXTokenKind
678506f32e7eSjoerg  *   int_data[1]: starting token location
678606f32e7eSjoerg  *   int_data[2]: token length
678706f32e7eSjoerg  *   int_data[3]: reserved
678806f32e7eSjoerg  *   ptr_data: for identifiers and keywords, an IdentifierInfo*.
678906f32e7eSjoerg  *   otherwise unused.
679006f32e7eSjoerg  */
clang_getTokenKind(CXToken CXTok)679106f32e7eSjoerg CXTokenKind clang_getTokenKind(CXToken CXTok) {
679206f32e7eSjoerg   return static_cast<CXTokenKind>(CXTok.int_data[0]);
679306f32e7eSjoerg }
679406f32e7eSjoerg 
clang_getTokenSpelling(CXTranslationUnit TU,CXToken CXTok)679506f32e7eSjoerg CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
679606f32e7eSjoerg   switch (clang_getTokenKind(CXTok)) {
679706f32e7eSjoerg   case CXToken_Identifier:
679806f32e7eSjoerg   case CXToken_Keyword:
679906f32e7eSjoerg     // We know we have an IdentifierInfo*, so use that.
6800*13fbcb42Sjoerg     return cxstring::createRef(
6801*13fbcb42Sjoerg         static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
680206f32e7eSjoerg 
680306f32e7eSjoerg   case CXToken_Literal: {
680406f32e7eSjoerg     // We have stashed the starting pointer in the ptr_data field. Use it.
680506f32e7eSjoerg     const char *Text = static_cast<const char *>(CXTok.ptr_data);
680606f32e7eSjoerg     return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
680706f32e7eSjoerg   }
680806f32e7eSjoerg 
680906f32e7eSjoerg   case CXToken_Punctuation:
681006f32e7eSjoerg   case CXToken_Comment:
681106f32e7eSjoerg     break;
681206f32e7eSjoerg   }
681306f32e7eSjoerg 
681406f32e7eSjoerg   if (isNotUsableTU(TU)) {
681506f32e7eSjoerg     LOG_BAD_TU(TU);
681606f32e7eSjoerg     return cxstring::createEmpty();
681706f32e7eSjoerg   }
681806f32e7eSjoerg 
681906f32e7eSjoerg   // We have to find the starting buffer pointer the hard way, by
682006f32e7eSjoerg   // deconstructing the source location.
682106f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
682206f32e7eSjoerg   if (!CXXUnit)
682306f32e7eSjoerg     return cxstring::createEmpty();
682406f32e7eSjoerg 
682506f32e7eSjoerg   SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
6826*13fbcb42Sjoerg   std::pair<FileID, unsigned> LocInfo =
6827*13fbcb42Sjoerg       CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
682806f32e7eSjoerg   bool Invalid = false;
6829*13fbcb42Sjoerg   StringRef Buffer =
6830*13fbcb42Sjoerg       CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
683106f32e7eSjoerg   if (Invalid)
683206f32e7eSjoerg     return cxstring::createEmpty();
683306f32e7eSjoerg 
683406f32e7eSjoerg   return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
683506f32e7eSjoerg }
683606f32e7eSjoerg 
clang_getTokenLocation(CXTranslationUnit TU,CXToken CXTok)683706f32e7eSjoerg CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
683806f32e7eSjoerg   if (isNotUsableTU(TU)) {
683906f32e7eSjoerg     LOG_BAD_TU(TU);
684006f32e7eSjoerg     return clang_getNullLocation();
684106f32e7eSjoerg   }
684206f32e7eSjoerg 
684306f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
684406f32e7eSjoerg   if (!CXXUnit)
684506f32e7eSjoerg     return clang_getNullLocation();
684606f32e7eSjoerg 
6847*13fbcb42Sjoerg   return cxloc::translateSourceLocation(
6848*13fbcb42Sjoerg       CXXUnit->getASTContext(),
684906f32e7eSjoerg       SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
685006f32e7eSjoerg }
685106f32e7eSjoerg 
clang_getTokenExtent(CXTranslationUnit TU,CXToken CXTok)685206f32e7eSjoerg CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
685306f32e7eSjoerg   if (isNotUsableTU(TU)) {
685406f32e7eSjoerg     LOG_BAD_TU(TU);
685506f32e7eSjoerg     return clang_getNullRange();
685606f32e7eSjoerg   }
685706f32e7eSjoerg 
685806f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
685906f32e7eSjoerg   if (!CXXUnit)
686006f32e7eSjoerg     return clang_getNullRange();
686106f32e7eSjoerg 
6862*13fbcb42Sjoerg   return cxloc::translateSourceRange(
6863*13fbcb42Sjoerg       CXXUnit->getASTContext(),
686406f32e7eSjoerg       SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
686506f32e7eSjoerg }
686606f32e7eSjoerg 
getTokens(ASTUnit * CXXUnit,SourceRange Range,SmallVectorImpl<CXToken> & CXTokens)686706f32e7eSjoerg static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
686806f32e7eSjoerg                       SmallVectorImpl<CXToken> &CXTokens) {
686906f32e7eSjoerg   SourceManager &SourceMgr = CXXUnit->getSourceManager();
6870*13fbcb42Sjoerg   std::pair<FileID, unsigned> BeginLocInfo =
6871*13fbcb42Sjoerg       SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6872*13fbcb42Sjoerg   std::pair<FileID, unsigned> EndLocInfo =
6873*13fbcb42Sjoerg       SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
687406f32e7eSjoerg 
687506f32e7eSjoerg   // Cannot tokenize across files.
687606f32e7eSjoerg   if (BeginLocInfo.first != EndLocInfo.first)
687706f32e7eSjoerg     return;
687806f32e7eSjoerg 
687906f32e7eSjoerg   // Create a lexer
688006f32e7eSjoerg   bool Invalid = false;
6881*13fbcb42Sjoerg   StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
688206f32e7eSjoerg   if (Invalid)
688306f32e7eSjoerg     return;
688406f32e7eSjoerg 
688506f32e7eSjoerg   Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6886*13fbcb42Sjoerg             CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6887*13fbcb42Sjoerg             Buffer.data() + BeginLocInfo.second, Buffer.end());
688806f32e7eSjoerg   Lex.SetCommentRetentionState(true);
688906f32e7eSjoerg 
689006f32e7eSjoerg   // Lex tokens until we hit the end of the range.
689106f32e7eSjoerg   const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
689206f32e7eSjoerg   Token Tok;
689306f32e7eSjoerg   bool previousWasAt = false;
689406f32e7eSjoerg   do {
689506f32e7eSjoerg     // Lex the next token
689606f32e7eSjoerg     Lex.LexFromRawLexer(Tok);
689706f32e7eSjoerg     if (Tok.is(tok::eof))
689806f32e7eSjoerg       break;
689906f32e7eSjoerg 
690006f32e7eSjoerg     // Initialize the CXToken.
690106f32e7eSjoerg     CXToken CXTok;
690206f32e7eSjoerg 
690306f32e7eSjoerg     //   - Common fields
690406f32e7eSjoerg     CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
690506f32e7eSjoerg     CXTok.int_data[2] = Tok.getLength();
690606f32e7eSjoerg     CXTok.int_data[3] = 0;
690706f32e7eSjoerg 
690806f32e7eSjoerg     //   - Kind-specific fields
690906f32e7eSjoerg     if (Tok.isLiteral()) {
691006f32e7eSjoerg       CXTok.int_data[0] = CXToken_Literal;
691106f32e7eSjoerg       CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
691206f32e7eSjoerg     } else if (Tok.is(tok::raw_identifier)) {
691306f32e7eSjoerg       // Lookup the identifier to determine whether we have a keyword.
6914*13fbcb42Sjoerg       IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
691506f32e7eSjoerg 
691606f32e7eSjoerg       if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
691706f32e7eSjoerg         CXTok.int_data[0] = CXToken_Keyword;
6918*13fbcb42Sjoerg       } else {
6919*13fbcb42Sjoerg         CXTok.int_data[0] =
6920*13fbcb42Sjoerg             Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
692106f32e7eSjoerg       }
692206f32e7eSjoerg       CXTok.ptr_data = II;
692306f32e7eSjoerg     } else if (Tok.is(tok::comment)) {
692406f32e7eSjoerg       CXTok.int_data[0] = CXToken_Comment;
692506f32e7eSjoerg       CXTok.ptr_data = nullptr;
692606f32e7eSjoerg     } else {
692706f32e7eSjoerg       CXTok.int_data[0] = CXToken_Punctuation;
692806f32e7eSjoerg       CXTok.ptr_data = nullptr;
692906f32e7eSjoerg     }
693006f32e7eSjoerg     CXTokens.push_back(CXTok);
693106f32e7eSjoerg     previousWasAt = Tok.is(tok::at);
693206f32e7eSjoerg   } while (Lex.getBufferLocation() < EffectiveBufferEnd);
693306f32e7eSjoerg }
693406f32e7eSjoerg 
clang_getToken(CXTranslationUnit TU,CXSourceLocation Location)693506f32e7eSjoerg CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
6936*13fbcb42Sjoerg   LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
693706f32e7eSjoerg 
693806f32e7eSjoerg   if (isNotUsableTU(TU)) {
693906f32e7eSjoerg     LOG_BAD_TU(TU);
694006f32e7eSjoerg     return NULL;
694106f32e7eSjoerg   }
694206f32e7eSjoerg 
694306f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
694406f32e7eSjoerg   if (!CXXUnit)
694506f32e7eSjoerg     return NULL;
694606f32e7eSjoerg 
694706f32e7eSjoerg   SourceLocation Begin = cxloc::translateSourceLocation(Location);
694806f32e7eSjoerg   if (Begin.isInvalid())
694906f32e7eSjoerg     return NULL;
695006f32e7eSjoerg   SourceManager &SM = CXXUnit->getSourceManager();
695106f32e7eSjoerg   std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
6952*13fbcb42Sjoerg   DecomposedEnd.second +=
6953*13fbcb42Sjoerg       Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
695406f32e7eSjoerg 
6955*13fbcb42Sjoerg   SourceLocation End =
6956*13fbcb42Sjoerg       SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
695706f32e7eSjoerg 
695806f32e7eSjoerg   SmallVector<CXToken, 32> CXTokens;
695906f32e7eSjoerg   getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
696006f32e7eSjoerg 
696106f32e7eSjoerg   if (CXTokens.empty())
696206f32e7eSjoerg     return NULL;
696306f32e7eSjoerg 
696406f32e7eSjoerg   CXTokens.resize(1);
696506f32e7eSjoerg   CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
696606f32e7eSjoerg 
696706f32e7eSjoerg   memmove(Token, CXTokens.data(), sizeof(CXToken));
696806f32e7eSjoerg   return Token;
696906f32e7eSjoerg }
697006f32e7eSjoerg 
clang_tokenize(CXTranslationUnit TU,CXSourceRange Range,CXToken ** Tokens,unsigned * NumTokens)6971*13fbcb42Sjoerg void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6972*13fbcb42Sjoerg                     unsigned *NumTokens) {
6973*13fbcb42Sjoerg   LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
697406f32e7eSjoerg 
697506f32e7eSjoerg   if (Tokens)
697606f32e7eSjoerg     *Tokens = nullptr;
697706f32e7eSjoerg   if (NumTokens)
697806f32e7eSjoerg     *NumTokens = 0;
697906f32e7eSjoerg 
698006f32e7eSjoerg   if (isNotUsableTU(TU)) {
698106f32e7eSjoerg     LOG_BAD_TU(TU);
698206f32e7eSjoerg     return;
698306f32e7eSjoerg   }
698406f32e7eSjoerg 
698506f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
698606f32e7eSjoerg   if (!CXXUnit || !Tokens || !NumTokens)
698706f32e7eSjoerg     return;
698806f32e7eSjoerg 
698906f32e7eSjoerg   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
699006f32e7eSjoerg 
699106f32e7eSjoerg   SourceRange R = cxloc::translateCXSourceRange(Range);
699206f32e7eSjoerg   if (R.isInvalid())
699306f32e7eSjoerg     return;
699406f32e7eSjoerg 
699506f32e7eSjoerg   SmallVector<CXToken, 32> CXTokens;
699606f32e7eSjoerg   getTokens(CXXUnit, R, CXTokens);
699706f32e7eSjoerg 
699806f32e7eSjoerg   if (CXTokens.empty())
699906f32e7eSjoerg     return;
700006f32e7eSjoerg 
700106f32e7eSjoerg   *Tokens = static_cast<CXToken *>(
700206f32e7eSjoerg       llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
700306f32e7eSjoerg   memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
700406f32e7eSjoerg   *NumTokens = CXTokens.size();
700506f32e7eSjoerg }
700606f32e7eSjoerg 
clang_disposeTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens)7007*13fbcb42Sjoerg void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
7008*13fbcb42Sjoerg                          unsigned NumTokens) {
700906f32e7eSjoerg   free(Tokens);
701006f32e7eSjoerg }
701106f32e7eSjoerg 
701206f32e7eSjoerg //===----------------------------------------------------------------------===//
701306f32e7eSjoerg // Token annotation APIs.
701406f32e7eSjoerg //===----------------------------------------------------------------------===//
701506f32e7eSjoerg 
701606f32e7eSjoerg static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
701706f32e7eSjoerg                                                      CXCursor parent,
701806f32e7eSjoerg                                                      CXClientData client_data);
701906f32e7eSjoerg static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
702006f32e7eSjoerg                                               CXClientData client_data);
702106f32e7eSjoerg 
702206f32e7eSjoerg namespace {
702306f32e7eSjoerg class AnnotateTokensWorker {
702406f32e7eSjoerg   CXToken *Tokens;
702506f32e7eSjoerg   CXCursor *Cursors;
702606f32e7eSjoerg   unsigned NumTokens;
702706f32e7eSjoerg   unsigned TokIdx;
702806f32e7eSjoerg   unsigned PreprocessingTokIdx;
702906f32e7eSjoerg   CursorVisitor AnnotateVis;
703006f32e7eSjoerg   SourceManager &SrcMgr;
703106f32e7eSjoerg   bool HasContextSensitiveKeywords;
703206f32e7eSjoerg 
703306f32e7eSjoerg   struct PostChildrenAction {
703406f32e7eSjoerg     CXCursor cursor;
703506f32e7eSjoerg     enum Action { Invalid, Ignore, Postpone } action;
703606f32e7eSjoerg   };
703706f32e7eSjoerg   using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
703806f32e7eSjoerg 
703906f32e7eSjoerg   struct PostChildrenInfo {
704006f32e7eSjoerg     CXCursor Cursor;
704106f32e7eSjoerg     SourceRange CursorRange;
704206f32e7eSjoerg     unsigned BeforeReachingCursorIdx;
704306f32e7eSjoerg     unsigned BeforeChildrenTokenIdx;
704406f32e7eSjoerg     PostChildrenActions ChildActions;
704506f32e7eSjoerg   };
704606f32e7eSjoerg   SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
704706f32e7eSjoerg 
getTok(unsigned Idx)704806f32e7eSjoerg   CXToken &getTok(unsigned Idx) {
704906f32e7eSjoerg     assert(Idx < NumTokens);
705006f32e7eSjoerg     return Tokens[Idx];
705106f32e7eSjoerg   }
getTok(unsigned Idx) const705206f32e7eSjoerg   const CXToken &getTok(unsigned Idx) const {
705306f32e7eSjoerg     assert(Idx < NumTokens);
705406f32e7eSjoerg     return Tokens[Idx];
705506f32e7eSjoerg   }
MoreTokens() const705606f32e7eSjoerg   bool MoreTokens() const { return TokIdx < NumTokens; }
NextToken() const705706f32e7eSjoerg   unsigned NextToken() const { return TokIdx; }
AdvanceToken()705806f32e7eSjoerg   void AdvanceToken() { ++TokIdx; }
GetTokenLoc(unsigned tokI)705906f32e7eSjoerg   SourceLocation GetTokenLoc(unsigned tokI) {
706006f32e7eSjoerg     return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
706106f32e7eSjoerg   }
isFunctionMacroToken(unsigned tokI) const706206f32e7eSjoerg   bool isFunctionMacroToken(unsigned tokI) const {
706306f32e7eSjoerg     return getTok(tokI).int_data[3] != 0;
706406f32e7eSjoerg   }
getFunctionMacroTokenLoc(unsigned tokI) const706506f32e7eSjoerg   SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
706606f32e7eSjoerg     return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
706706f32e7eSjoerg   }
706806f32e7eSjoerg 
706906f32e7eSjoerg   void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
707006f32e7eSjoerg   bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
707106f32e7eSjoerg                                              SourceRange);
707206f32e7eSjoerg 
707306f32e7eSjoerg public:
AnnotateTokensWorker(CXToken * tokens,CXCursor * cursors,unsigned numTokens,CXTranslationUnit TU,SourceRange RegionOfInterest)707406f32e7eSjoerg   AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
707506f32e7eSjoerg                        CXTranslationUnit TU, SourceRange RegionOfInterest)
7076*13fbcb42Sjoerg       : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
7077*13fbcb42Sjoerg         PreprocessingTokIdx(0),
7078*13fbcb42Sjoerg         AnnotateVis(TU, AnnotateTokensVisitor, this,
707906f32e7eSjoerg                     /*VisitPreprocessorLast=*/true,
7080*13fbcb42Sjoerg                     /*VisitIncludedEntities=*/false, RegionOfInterest,
708106f32e7eSjoerg                     /*VisitDeclsOnly=*/false,
708206f32e7eSjoerg                     AnnotateTokensPostChildrenVisitor),
708306f32e7eSjoerg         SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
708406f32e7eSjoerg         HasContextSensitiveKeywords(false) {}
708506f32e7eSjoerg 
VisitChildren(CXCursor C)708606f32e7eSjoerg   void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
708706f32e7eSjoerg   enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
708806f32e7eSjoerg   bool IsIgnoredChildCursor(CXCursor cursor) const;
708906f32e7eSjoerg   PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
709006f32e7eSjoerg 
709106f32e7eSjoerg   bool postVisitChildren(CXCursor cursor);
709206f32e7eSjoerg   void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
709306f32e7eSjoerg   void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
709406f32e7eSjoerg 
709506f32e7eSjoerg   void AnnotateTokens();
709606f32e7eSjoerg 
709706f32e7eSjoerg   /// Determine whether the annotator saw any cursors that have
709806f32e7eSjoerg   /// context-sensitive keywords.
hasContextSensitiveKeywords() const709906f32e7eSjoerg   bool hasContextSensitiveKeywords() const {
710006f32e7eSjoerg     return HasContextSensitiveKeywords;
710106f32e7eSjoerg   }
710206f32e7eSjoerg 
~AnnotateTokensWorker()7103*13fbcb42Sjoerg   ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
710406f32e7eSjoerg };
7105*13fbcb42Sjoerg } // namespace
710606f32e7eSjoerg 
AnnotateTokens()710706f32e7eSjoerg void AnnotateTokensWorker::AnnotateTokens() {
710806f32e7eSjoerg   // Walk the AST within the region of interest, annotating tokens
710906f32e7eSjoerg   // along the way.
711006f32e7eSjoerg   AnnotateVis.visitFileRegion();
711106f32e7eSjoerg }
711206f32e7eSjoerg 
IsIgnoredChildCursor(CXCursor cursor) const711306f32e7eSjoerg bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
711406f32e7eSjoerg   if (PostChildrenInfos.empty())
711506f32e7eSjoerg     return false;
711606f32e7eSjoerg 
711706f32e7eSjoerg   for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
711806f32e7eSjoerg     if (ChildAction.cursor == cursor &&
711906f32e7eSjoerg         ChildAction.action == PostChildrenAction::Ignore) {
712006f32e7eSjoerg       return true;
712106f32e7eSjoerg     }
712206f32e7eSjoerg   }
712306f32e7eSjoerg 
712406f32e7eSjoerg   return false;
712506f32e7eSjoerg }
712606f32e7eSjoerg 
GetSubscriptOrCallOperator(CXCursor Cursor)712706f32e7eSjoerg const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
712806f32e7eSjoerg   if (!clang_isExpression(Cursor.kind))
712906f32e7eSjoerg     return nullptr;
713006f32e7eSjoerg 
713106f32e7eSjoerg   const Expr *E = getCursorExpr(Cursor);
713206f32e7eSjoerg   if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
713306f32e7eSjoerg     const OverloadedOperatorKind Kind = OCE->getOperator();
713406f32e7eSjoerg     if (Kind == OO_Call || Kind == OO_Subscript)
713506f32e7eSjoerg       return OCE;
713606f32e7eSjoerg   }
713706f32e7eSjoerg 
713806f32e7eSjoerg   return nullptr;
713906f32e7eSjoerg }
714006f32e7eSjoerg 
714106f32e7eSjoerg AnnotateTokensWorker::PostChildrenActions
DetermineChildActions(CXCursor Cursor) const714206f32e7eSjoerg AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
714306f32e7eSjoerg   PostChildrenActions actions;
714406f32e7eSjoerg 
714506f32e7eSjoerg   // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
714606f32e7eSjoerg   // visited before the arguments to the operator call. For the Call and
714706f32e7eSjoerg   // Subscript operator the range of this DeclRefExpr includes the whole call
714806f32e7eSjoerg   // expression, so that all tokens in that range would be mapped to the
714906f32e7eSjoerg   // operator function, including the tokens of the arguments. To avoid that,
715006f32e7eSjoerg   // ensure to visit this DeclRefExpr as last node.
715106f32e7eSjoerg   if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
715206f32e7eSjoerg     const Expr *Callee = OCE->getCallee();
715306f32e7eSjoerg     if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
715406f32e7eSjoerg       const Expr *SubExpr = ICE->getSubExpr();
715506f32e7eSjoerg       if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
715606f32e7eSjoerg         const Decl *parentDecl = getCursorDecl(Cursor);
715706f32e7eSjoerg         CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
715806f32e7eSjoerg 
715906f32e7eSjoerg         // Visit the DeclRefExpr as last.
716006f32e7eSjoerg         CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
716106f32e7eSjoerg         actions.push_back({cxChild, PostChildrenAction::Postpone});
716206f32e7eSjoerg 
716306f32e7eSjoerg         // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
716406f32e7eSjoerg         // wide range as the DeclRefExpr. We can skip visiting this entirely.
716506f32e7eSjoerg         cxChild = MakeCXCursor(ICE, parentDecl, TU);
716606f32e7eSjoerg         actions.push_back({cxChild, PostChildrenAction::Ignore});
716706f32e7eSjoerg       }
716806f32e7eSjoerg     }
716906f32e7eSjoerg   }
717006f32e7eSjoerg 
717106f32e7eSjoerg   return actions;
717206f32e7eSjoerg }
717306f32e7eSjoerg 
updateCursorAnnotation(CXCursor & Cursor,const CXCursor & updateC)717406f32e7eSjoerg static inline void updateCursorAnnotation(CXCursor &Cursor,
717506f32e7eSjoerg                                           const CXCursor &updateC) {
717606f32e7eSjoerg   if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
717706f32e7eSjoerg     return;
717806f32e7eSjoerg   Cursor = updateC;
717906f32e7eSjoerg }
718006f32e7eSjoerg 
718106f32e7eSjoerg /// It annotates and advances tokens with a cursor until the comparison
718206f32e7eSjoerg //// between the cursor location and the source range is the same as
718306f32e7eSjoerg /// \arg compResult.
718406f32e7eSjoerg ///
718506f32e7eSjoerg /// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
718606f32e7eSjoerg /// Pass RangeOverlap to annotate tokens inside a range.
annotateAndAdvanceTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)7187*13fbcb42Sjoerg void AnnotateTokensWorker::annotateAndAdvanceTokens(
7188*13fbcb42Sjoerg     CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
718906f32e7eSjoerg   while (MoreTokens()) {
719006f32e7eSjoerg     const unsigned I = NextToken();
719106f32e7eSjoerg     if (isFunctionMacroToken(I))
719206f32e7eSjoerg       if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
719306f32e7eSjoerg         return;
719406f32e7eSjoerg 
719506f32e7eSjoerg     SourceLocation TokLoc = GetTokenLoc(I);
719606f32e7eSjoerg     if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
719706f32e7eSjoerg       updateCursorAnnotation(Cursors[I], updateC);
719806f32e7eSjoerg       AdvanceToken();
719906f32e7eSjoerg       continue;
720006f32e7eSjoerg     }
720106f32e7eSjoerg     break;
720206f32e7eSjoerg   }
720306f32e7eSjoerg }
720406f32e7eSjoerg 
720506f32e7eSjoerg /// Special annotation handling for macro argument tokens.
720606f32e7eSjoerg /// \returns true if it advanced beyond all macro tokens, false otherwise.
annotateAndAdvanceFunctionMacroTokens(CXCursor updateC,RangeComparisonResult compResult,SourceRange range)720706f32e7eSjoerg bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
7208*13fbcb42Sjoerg     CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
720906f32e7eSjoerg   assert(MoreTokens());
721006f32e7eSjoerg   assert(isFunctionMacroToken(NextToken()) &&
721106f32e7eSjoerg          "Should be called only for macro arg tokens");
721206f32e7eSjoerg 
721306f32e7eSjoerg   // This works differently than annotateAndAdvanceTokens; because expanded
721406f32e7eSjoerg   // macro arguments can have arbitrary translation-unit source order, we do not
721506f32e7eSjoerg   // advance the token index one by one until a token fails the range test.
721606f32e7eSjoerg   // We only advance once past all of the macro arg tokens if all of them
721706f32e7eSjoerg   // pass the range test. If one of them fails we keep the token index pointing
721806f32e7eSjoerg   // at the start of the macro arg tokens so that the failing token will be
721906f32e7eSjoerg   // annotated by a subsequent annotation try.
722006f32e7eSjoerg 
722106f32e7eSjoerg   bool atLeastOneCompFail = false;
722206f32e7eSjoerg 
722306f32e7eSjoerg   unsigned I = NextToken();
722406f32e7eSjoerg   for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
722506f32e7eSjoerg     SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
722606f32e7eSjoerg     if (TokLoc.isFileID())
722706f32e7eSjoerg       continue; // not macro arg token, it's parens or comma.
722806f32e7eSjoerg     if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
722906f32e7eSjoerg       if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
723006f32e7eSjoerg         Cursors[I] = updateC;
723106f32e7eSjoerg     } else
723206f32e7eSjoerg       atLeastOneCompFail = true;
723306f32e7eSjoerg   }
723406f32e7eSjoerg 
723506f32e7eSjoerg   if (atLeastOneCompFail)
723606f32e7eSjoerg     return false;
723706f32e7eSjoerg 
723806f32e7eSjoerg   TokIdx = I; // All of the tokens were handled, advance beyond all of them.
723906f32e7eSjoerg   return true;
724006f32e7eSjoerg }
724106f32e7eSjoerg 
Visit(CXCursor cursor,CXCursor parent)7242*13fbcb42Sjoerg enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7243*13fbcb42Sjoerg                                                     CXCursor parent) {
724406f32e7eSjoerg   SourceRange cursorRange = getRawCursorExtent(cursor);
724506f32e7eSjoerg   if (cursorRange.isInvalid())
724606f32e7eSjoerg     return CXChildVisit_Recurse;
724706f32e7eSjoerg 
724806f32e7eSjoerg   if (IsIgnoredChildCursor(cursor))
724906f32e7eSjoerg     return CXChildVisit_Continue;
725006f32e7eSjoerg 
725106f32e7eSjoerg   if (!HasContextSensitiveKeywords) {
725206f32e7eSjoerg     // Objective-C properties can have context-sensitive keywords.
725306f32e7eSjoerg     if (cursor.kind == CXCursor_ObjCPropertyDecl) {
7254*13fbcb42Sjoerg       if (const ObjCPropertyDecl *Property =
7255*13fbcb42Sjoerg               dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7256*13fbcb42Sjoerg         HasContextSensitiveKeywords =
7257*13fbcb42Sjoerg             Property->getPropertyAttributesAsWritten() != 0;
725806f32e7eSjoerg     }
725906f32e7eSjoerg     // Objective-C methods can have context-sensitive keywords.
726006f32e7eSjoerg     else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
726106f32e7eSjoerg              cursor.kind == CXCursor_ObjCClassMethodDecl) {
7262*13fbcb42Sjoerg       if (const ObjCMethodDecl *Method =
7263*13fbcb42Sjoerg               dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
726406f32e7eSjoerg         if (Method->getObjCDeclQualifier())
726506f32e7eSjoerg           HasContextSensitiveKeywords = true;
726606f32e7eSjoerg         else {
726706f32e7eSjoerg           for (const auto *P : Method->parameters()) {
726806f32e7eSjoerg             if (P->getObjCDeclQualifier()) {
726906f32e7eSjoerg               HasContextSensitiveKeywords = true;
727006f32e7eSjoerg               break;
727106f32e7eSjoerg             }
727206f32e7eSjoerg           }
727306f32e7eSjoerg         }
727406f32e7eSjoerg       }
727506f32e7eSjoerg     }
727606f32e7eSjoerg     // C++ methods can have context-sensitive keywords.
727706f32e7eSjoerg     else if (cursor.kind == CXCursor_CXXMethod) {
7278*13fbcb42Sjoerg       if (const CXXMethodDecl *Method =
7279*13fbcb42Sjoerg               dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
728006f32e7eSjoerg         if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
728106f32e7eSjoerg           HasContextSensitiveKeywords = true;
728206f32e7eSjoerg       }
728306f32e7eSjoerg     }
728406f32e7eSjoerg     // C++ classes can have context-sensitive keywords.
728506f32e7eSjoerg     else if (cursor.kind == CXCursor_StructDecl ||
728606f32e7eSjoerg              cursor.kind == CXCursor_ClassDecl ||
728706f32e7eSjoerg              cursor.kind == CXCursor_ClassTemplate ||
728806f32e7eSjoerg              cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
728906f32e7eSjoerg       if (const Decl *D = getCursorDecl(cursor))
729006f32e7eSjoerg         if (D->hasAttr<FinalAttr>())
729106f32e7eSjoerg           HasContextSensitiveKeywords = true;
729206f32e7eSjoerg     }
729306f32e7eSjoerg   }
729406f32e7eSjoerg 
729506f32e7eSjoerg   // Don't override a property annotation with its getter/setter method.
729606f32e7eSjoerg   if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
729706f32e7eSjoerg       parent.kind == CXCursor_ObjCPropertyDecl)
729806f32e7eSjoerg     return CXChildVisit_Continue;
729906f32e7eSjoerg 
730006f32e7eSjoerg   if (clang_isPreprocessing(cursor.kind)) {
730106f32e7eSjoerg     // Items in the preprocessing record are kept separate from items in
730206f32e7eSjoerg     // declarations, so we keep a separate token index.
730306f32e7eSjoerg     unsigned SavedTokIdx = TokIdx;
730406f32e7eSjoerg     TokIdx = PreprocessingTokIdx;
730506f32e7eSjoerg 
730606f32e7eSjoerg     // Skip tokens up until we catch up to the beginning of the preprocessing
730706f32e7eSjoerg     // entry.
730806f32e7eSjoerg     while (MoreTokens()) {
730906f32e7eSjoerg       const unsigned I = NextToken();
731006f32e7eSjoerg       SourceLocation TokLoc = GetTokenLoc(I);
731106f32e7eSjoerg       switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
731206f32e7eSjoerg       case RangeBefore:
731306f32e7eSjoerg         AdvanceToken();
731406f32e7eSjoerg         continue;
731506f32e7eSjoerg       case RangeAfter:
731606f32e7eSjoerg       case RangeOverlap:
731706f32e7eSjoerg         break;
731806f32e7eSjoerg       }
731906f32e7eSjoerg       break;
732006f32e7eSjoerg     }
732106f32e7eSjoerg 
732206f32e7eSjoerg     // Look at all of the tokens within this range.
732306f32e7eSjoerg     while (MoreTokens()) {
732406f32e7eSjoerg       const unsigned I = NextToken();
732506f32e7eSjoerg       SourceLocation TokLoc = GetTokenLoc(I);
732606f32e7eSjoerg       switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
732706f32e7eSjoerg       case RangeBefore:
732806f32e7eSjoerg         llvm_unreachable("Infeasible");
732906f32e7eSjoerg       case RangeAfter:
733006f32e7eSjoerg         break;
733106f32e7eSjoerg       case RangeOverlap:
733206f32e7eSjoerg         // For macro expansions, just note where the beginning of the macro
733306f32e7eSjoerg         // expansion occurs.
733406f32e7eSjoerg         if (cursor.kind == CXCursor_MacroExpansion) {
733506f32e7eSjoerg           if (TokLoc == cursorRange.getBegin())
733606f32e7eSjoerg             Cursors[I] = cursor;
733706f32e7eSjoerg           AdvanceToken();
733806f32e7eSjoerg           break;
733906f32e7eSjoerg         }
734006f32e7eSjoerg         // We may have already annotated macro names inside macro definitions.
734106f32e7eSjoerg         if (Cursors[I].kind != CXCursor_MacroExpansion)
734206f32e7eSjoerg           Cursors[I] = cursor;
734306f32e7eSjoerg         AdvanceToken();
734406f32e7eSjoerg         continue;
734506f32e7eSjoerg       }
734606f32e7eSjoerg       break;
734706f32e7eSjoerg     }
734806f32e7eSjoerg 
734906f32e7eSjoerg     // Save the preprocessing token index; restore the non-preprocessing
735006f32e7eSjoerg     // token index.
735106f32e7eSjoerg     PreprocessingTokIdx = TokIdx;
735206f32e7eSjoerg     TokIdx = SavedTokIdx;
735306f32e7eSjoerg     return CXChildVisit_Recurse;
735406f32e7eSjoerg   }
735506f32e7eSjoerg 
735606f32e7eSjoerg   if (cursorRange.isInvalid())
735706f32e7eSjoerg     return CXChildVisit_Continue;
735806f32e7eSjoerg 
735906f32e7eSjoerg   unsigned BeforeReachingCursorIdx = NextToken();
736006f32e7eSjoerg   const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
736106f32e7eSjoerg   const enum CXCursorKind K = clang_getCursorKind(parent);
736206f32e7eSjoerg   const CXCursor updateC =
736306f32e7eSjoerg       (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
736406f32e7eSjoerg        // Attributes are annotated out-of-order, skip tokens until we reach it.
736506f32e7eSjoerg        clang_isAttribute(cursor.kind))
7366*13fbcb42Sjoerg           ? clang_getNullCursor()
7367*13fbcb42Sjoerg           : parent;
736806f32e7eSjoerg 
736906f32e7eSjoerg   annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
737006f32e7eSjoerg 
737106f32e7eSjoerg   // Avoid having the cursor of an expression "overwrite" the annotation of the
737206f32e7eSjoerg   // variable declaration that it belongs to.
737306f32e7eSjoerg   // This can happen for C++ constructor expressions whose range generally
737406f32e7eSjoerg   // include the variable declaration, e.g.:
737506f32e7eSjoerg   //  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
737606f32e7eSjoerg   if (clang_isExpression(cursorK) && MoreTokens()) {
737706f32e7eSjoerg     const Expr *E = getCursorExpr(cursor);
737806f32e7eSjoerg     if (const Decl *D = getCursorDecl(cursor)) {
737906f32e7eSjoerg       const unsigned I = NextToken();
738006f32e7eSjoerg       if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
738106f32e7eSjoerg           E->getBeginLoc() == D->getLocation() &&
738206f32e7eSjoerg           E->getBeginLoc() == GetTokenLoc(I)) {
738306f32e7eSjoerg         updateCursorAnnotation(Cursors[I], updateC);
738406f32e7eSjoerg         AdvanceToken();
738506f32e7eSjoerg       }
738606f32e7eSjoerg     }
738706f32e7eSjoerg   }
738806f32e7eSjoerg 
738906f32e7eSjoerg   // Before recursing into the children keep some state that we are going
739006f32e7eSjoerg   // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
739106f32e7eSjoerg   // extra work after the child nodes are visited.
739206f32e7eSjoerg   // Note that we don't call VisitChildren here to avoid traversing statements
739306f32e7eSjoerg   // code-recursively which can blow the stack.
739406f32e7eSjoerg 
739506f32e7eSjoerg   PostChildrenInfo Info;
739606f32e7eSjoerg   Info.Cursor = cursor;
739706f32e7eSjoerg   Info.CursorRange = cursorRange;
739806f32e7eSjoerg   Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
739906f32e7eSjoerg   Info.BeforeChildrenTokenIdx = NextToken();
740006f32e7eSjoerg   Info.ChildActions = DetermineChildActions(cursor);
740106f32e7eSjoerg   PostChildrenInfos.push_back(Info);
740206f32e7eSjoerg 
740306f32e7eSjoerg   return CXChildVisit_Recurse;
740406f32e7eSjoerg }
740506f32e7eSjoerg 
postVisitChildren(CXCursor cursor)740606f32e7eSjoerg bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
740706f32e7eSjoerg   if (PostChildrenInfos.empty())
740806f32e7eSjoerg     return false;
740906f32e7eSjoerg   const PostChildrenInfo &Info = PostChildrenInfos.back();
741006f32e7eSjoerg   if (!clang_equalCursors(Info.Cursor, cursor))
741106f32e7eSjoerg     return false;
741206f32e7eSjoerg 
741306f32e7eSjoerg   HandlePostPonedChildCursors(Info);
741406f32e7eSjoerg 
741506f32e7eSjoerg   const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
741606f32e7eSjoerg   const unsigned AfterChildren = NextToken();
741706f32e7eSjoerg   SourceRange cursorRange = Info.CursorRange;
741806f32e7eSjoerg 
741906f32e7eSjoerg   // Scan the tokens that are at the end of the cursor, but are not captured
742006f32e7eSjoerg   // but the child cursors.
742106f32e7eSjoerg   annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
742206f32e7eSjoerg 
742306f32e7eSjoerg   // Scan the tokens that are at the beginning of the cursor, but are not
742406f32e7eSjoerg   // capture by the child cursors.
742506f32e7eSjoerg   for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
742606f32e7eSjoerg     if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
742706f32e7eSjoerg       break;
742806f32e7eSjoerg 
742906f32e7eSjoerg     Cursors[I] = cursor;
743006f32e7eSjoerg   }
743106f32e7eSjoerg 
743206f32e7eSjoerg   // Attributes are annotated out-of-order, rewind TokIdx to when we first
743306f32e7eSjoerg   // encountered the attribute cursor.
743406f32e7eSjoerg   if (clang_isAttribute(cursor.kind))
743506f32e7eSjoerg     TokIdx = Info.BeforeReachingCursorIdx;
743606f32e7eSjoerg 
743706f32e7eSjoerg   PostChildrenInfos.pop_back();
743806f32e7eSjoerg   return false;
743906f32e7eSjoerg }
744006f32e7eSjoerg 
HandlePostPonedChildCursors(const PostChildrenInfo & Info)744106f32e7eSjoerg void AnnotateTokensWorker::HandlePostPonedChildCursors(
744206f32e7eSjoerg     const PostChildrenInfo &Info) {
744306f32e7eSjoerg   for (const auto &ChildAction : Info.ChildActions) {
744406f32e7eSjoerg     if (ChildAction.action == PostChildrenAction::Postpone) {
744506f32e7eSjoerg       HandlePostPonedChildCursor(ChildAction.cursor,
744606f32e7eSjoerg                                  Info.BeforeChildrenTokenIdx);
744706f32e7eSjoerg     }
744806f32e7eSjoerg   }
744906f32e7eSjoerg }
745006f32e7eSjoerg 
HandlePostPonedChildCursor(CXCursor Cursor,unsigned StartTokenIndex)745106f32e7eSjoerg void AnnotateTokensWorker::HandlePostPonedChildCursor(
745206f32e7eSjoerg     CXCursor Cursor, unsigned StartTokenIndex) {
745306f32e7eSjoerg   unsigned I = StartTokenIndex;
745406f32e7eSjoerg 
745506f32e7eSjoerg   // The bracket tokens of a Call or Subscript operator are mapped to
745606f32e7eSjoerg   // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
745706f32e7eSjoerg   // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
745806f32e7eSjoerg   for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
745906f32e7eSjoerg     const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
746006f32e7eSjoerg         Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
746106f32e7eSjoerg     if (clang_Range_isNull(CXRefNameRange))
746206f32e7eSjoerg       break; // All ranges handled.
746306f32e7eSjoerg 
746406f32e7eSjoerg     SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
746506f32e7eSjoerg     while (I < NumTokens) {
746606f32e7eSjoerg       const SourceLocation TokenLocation = GetTokenLoc(I);
746706f32e7eSjoerg       if (!TokenLocation.isValid())
746806f32e7eSjoerg         break;
746906f32e7eSjoerg 
747006f32e7eSjoerg       // Adapt the end range, because LocationCompare() reports
747106f32e7eSjoerg       // RangeOverlap even for the not-inclusive end location.
747206f32e7eSjoerg       const SourceLocation fixedEnd =
747306f32e7eSjoerg           RefNameRange.getEnd().getLocWithOffset(-1);
747406f32e7eSjoerg       RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
747506f32e7eSjoerg 
747606f32e7eSjoerg       const RangeComparisonResult ComparisonResult =
747706f32e7eSjoerg           LocationCompare(SrcMgr, TokenLocation, RefNameRange);
747806f32e7eSjoerg 
747906f32e7eSjoerg       if (ComparisonResult == RangeOverlap) {
748006f32e7eSjoerg         Cursors[I++] = Cursor;
748106f32e7eSjoerg       } else if (ComparisonResult == RangeBefore) {
748206f32e7eSjoerg         ++I; // Not relevant token, check next one.
748306f32e7eSjoerg       } else if (ComparisonResult == RangeAfter) {
748406f32e7eSjoerg         break; // All tokens updated for current range, check next.
748506f32e7eSjoerg       }
748606f32e7eSjoerg     }
748706f32e7eSjoerg   }
748806f32e7eSjoerg }
748906f32e7eSjoerg 
AnnotateTokensVisitor(CXCursor cursor,CXCursor parent,CXClientData client_data)749006f32e7eSjoerg static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
749106f32e7eSjoerg                                                      CXCursor parent,
749206f32e7eSjoerg                                                      CXClientData client_data) {
7493*13fbcb42Sjoerg   return static_cast<AnnotateTokensWorker *>(client_data)
7494*13fbcb42Sjoerg       ->Visit(cursor, parent);
749506f32e7eSjoerg }
749606f32e7eSjoerg 
AnnotateTokensPostChildrenVisitor(CXCursor cursor,CXClientData client_data)749706f32e7eSjoerg static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
749806f32e7eSjoerg                                               CXClientData client_data) {
7499*13fbcb42Sjoerg   return static_cast<AnnotateTokensWorker *>(client_data)
7500*13fbcb42Sjoerg       ->postVisitChildren(cursor);
750106f32e7eSjoerg }
750206f32e7eSjoerg 
750306f32e7eSjoerg namespace {
750406f32e7eSjoerg 
750506f32e7eSjoerg /// Uses the macro expansions in the preprocessing record to find
750606f32e7eSjoerg /// and mark tokens that are macro arguments. This info is used by the
750706f32e7eSjoerg /// AnnotateTokensWorker.
750806f32e7eSjoerg class MarkMacroArgTokensVisitor {
750906f32e7eSjoerg   SourceManager &SM;
751006f32e7eSjoerg   CXToken *Tokens;
751106f32e7eSjoerg   unsigned NumTokens;
751206f32e7eSjoerg   unsigned CurIdx;
751306f32e7eSjoerg 
751406f32e7eSjoerg public:
MarkMacroArgTokensVisitor(SourceManager & SM,CXToken * tokens,unsigned numTokens)7515*13fbcb42Sjoerg   MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7516*13fbcb42Sjoerg                             unsigned numTokens)
751706f32e7eSjoerg       : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
751806f32e7eSjoerg 
visit(CXCursor cursor,CXCursor parent)751906f32e7eSjoerg   CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
752006f32e7eSjoerg     if (cursor.kind != CXCursor_MacroExpansion)
752106f32e7eSjoerg       return CXChildVisit_Continue;
752206f32e7eSjoerg 
752306f32e7eSjoerg     SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
752406f32e7eSjoerg     if (macroRange.getBegin() == macroRange.getEnd())
752506f32e7eSjoerg       return CXChildVisit_Continue; // it's not a function macro.
752606f32e7eSjoerg 
752706f32e7eSjoerg     for (; CurIdx < NumTokens; ++CurIdx) {
752806f32e7eSjoerg       if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
752906f32e7eSjoerg                                         macroRange.getBegin()))
753006f32e7eSjoerg         break;
753106f32e7eSjoerg     }
753206f32e7eSjoerg 
753306f32e7eSjoerg     if (CurIdx == NumTokens)
753406f32e7eSjoerg       return CXChildVisit_Break;
753506f32e7eSjoerg 
753606f32e7eSjoerg     for (; CurIdx < NumTokens; ++CurIdx) {
753706f32e7eSjoerg       SourceLocation tokLoc = getTokenLoc(CurIdx);
753806f32e7eSjoerg       if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
753906f32e7eSjoerg         break;
754006f32e7eSjoerg 
754106f32e7eSjoerg       setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
754206f32e7eSjoerg     }
754306f32e7eSjoerg 
754406f32e7eSjoerg     if (CurIdx == NumTokens)
754506f32e7eSjoerg       return CXChildVisit_Break;
754606f32e7eSjoerg 
754706f32e7eSjoerg     return CXChildVisit_Continue;
754806f32e7eSjoerg   }
754906f32e7eSjoerg 
755006f32e7eSjoerg private:
getTok(unsigned Idx)755106f32e7eSjoerg   CXToken &getTok(unsigned Idx) {
755206f32e7eSjoerg     assert(Idx < NumTokens);
755306f32e7eSjoerg     return Tokens[Idx];
755406f32e7eSjoerg   }
getTok(unsigned Idx) const755506f32e7eSjoerg   const CXToken &getTok(unsigned Idx) const {
755606f32e7eSjoerg     assert(Idx < NumTokens);
755706f32e7eSjoerg     return Tokens[Idx];
755806f32e7eSjoerg   }
755906f32e7eSjoerg 
getTokenLoc(unsigned tokI)756006f32e7eSjoerg   SourceLocation getTokenLoc(unsigned tokI) {
756106f32e7eSjoerg     return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
756206f32e7eSjoerg   }
756306f32e7eSjoerg 
setFunctionMacroTokenLoc(unsigned tokI,SourceLocation loc)756406f32e7eSjoerg   void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
756506f32e7eSjoerg     // The third field is reserved and currently not used. Use it here
756606f32e7eSjoerg     // to mark macro arg expanded tokens with their expanded locations.
756706f32e7eSjoerg     getTok(tokI).int_data[3] = loc.getRawEncoding();
756806f32e7eSjoerg   }
756906f32e7eSjoerg };
757006f32e7eSjoerg 
757106f32e7eSjoerg } // end anonymous namespace
757206f32e7eSjoerg 
757306f32e7eSjoerg static CXChildVisitResult
MarkMacroArgTokensVisitorDelegate(CXCursor cursor,CXCursor parent,CXClientData client_data)757406f32e7eSjoerg MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
757506f32e7eSjoerg                                   CXClientData client_data) {
7576*13fbcb42Sjoerg   return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7577*13fbcb42Sjoerg       ->visit(cursor, parent);
757806f32e7eSjoerg }
757906f32e7eSjoerg 
758006f32e7eSjoerg /// Used by \c annotatePreprocessorTokens.
758106f32e7eSjoerg /// \returns true if lexing was finished, false otherwise.
lexNext(Lexer & Lex,Token & Tok,unsigned & NextIdx,unsigned NumTokens)7582*13fbcb42Sjoerg static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7583*13fbcb42Sjoerg                     unsigned NumTokens) {
758406f32e7eSjoerg   if (NextIdx >= NumTokens)
758506f32e7eSjoerg     return true;
758606f32e7eSjoerg 
758706f32e7eSjoerg   ++NextIdx;
758806f32e7eSjoerg   Lex.LexFromRawLexer(Tok);
758906f32e7eSjoerg   return Tok.is(tok::eof);
759006f32e7eSjoerg }
759106f32e7eSjoerg 
annotatePreprocessorTokens(CXTranslationUnit TU,SourceRange RegionOfInterest,CXCursor * Cursors,CXToken * Tokens,unsigned NumTokens)759206f32e7eSjoerg static void annotatePreprocessorTokens(CXTranslationUnit TU,
759306f32e7eSjoerg                                        SourceRange RegionOfInterest,
7594*13fbcb42Sjoerg                                        CXCursor *Cursors, CXToken *Tokens,
759506f32e7eSjoerg                                        unsigned NumTokens) {
759606f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
759706f32e7eSjoerg 
759806f32e7eSjoerg   Preprocessor &PP = CXXUnit->getPreprocessor();
759906f32e7eSjoerg   SourceManager &SourceMgr = CXXUnit->getSourceManager();
7600*13fbcb42Sjoerg   std::pair<FileID, unsigned> BeginLocInfo =
7601*13fbcb42Sjoerg       SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7602*13fbcb42Sjoerg   std::pair<FileID, unsigned> EndLocInfo =
7603*13fbcb42Sjoerg       SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
760406f32e7eSjoerg 
760506f32e7eSjoerg   if (BeginLocInfo.first != EndLocInfo.first)
760606f32e7eSjoerg     return;
760706f32e7eSjoerg 
760806f32e7eSjoerg   StringRef Buffer;
760906f32e7eSjoerg   bool Invalid = false;
761006f32e7eSjoerg   Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
761106f32e7eSjoerg   if (Buffer.empty() || Invalid)
761206f32e7eSjoerg     return;
761306f32e7eSjoerg 
761406f32e7eSjoerg   Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
7615*13fbcb42Sjoerg             CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7616*13fbcb42Sjoerg             Buffer.data() + BeginLocInfo.second, Buffer.end());
761706f32e7eSjoerg   Lex.SetCommentRetentionState(true);
761806f32e7eSjoerg 
761906f32e7eSjoerg   unsigned NextIdx = 0;
762006f32e7eSjoerg   // Lex tokens in raw mode until we hit the end of the range, to avoid
762106f32e7eSjoerg   // entering #includes or expanding macros.
762206f32e7eSjoerg   while (true) {
762306f32e7eSjoerg     Token Tok;
762406f32e7eSjoerg     if (lexNext(Lex, Tok, NextIdx, NumTokens))
762506f32e7eSjoerg       break;
762606f32e7eSjoerg     unsigned TokIdx = NextIdx - 1;
762706f32e7eSjoerg     assert(Tok.getLocation() ==
762806f32e7eSjoerg            SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
762906f32e7eSjoerg 
763006f32e7eSjoerg   reprocess:
763106f32e7eSjoerg     if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
763206f32e7eSjoerg       // We have found a preprocessing directive. Annotate the tokens
763306f32e7eSjoerg       // appropriately.
763406f32e7eSjoerg       //
763506f32e7eSjoerg       // FIXME: Some simple tests here could identify macro definitions and
763606f32e7eSjoerg       // #undefs, to provide specific cursor kinds for those.
763706f32e7eSjoerg 
763806f32e7eSjoerg       SourceLocation BeginLoc = Tok.getLocation();
763906f32e7eSjoerg       if (lexNext(Lex, Tok, NextIdx, NumTokens))
764006f32e7eSjoerg         break;
764106f32e7eSjoerg 
764206f32e7eSjoerg       MacroInfo *MI = nullptr;
764306f32e7eSjoerg       if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
764406f32e7eSjoerg         if (lexNext(Lex, Tok, NextIdx, NumTokens))
764506f32e7eSjoerg           break;
764606f32e7eSjoerg 
764706f32e7eSjoerg         if (Tok.is(tok::raw_identifier)) {
764806f32e7eSjoerg           IdentifierInfo &II =
764906f32e7eSjoerg               PP.getIdentifierTable().get(Tok.getRawIdentifier());
765006f32e7eSjoerg           SourceLocation MappedTokLoc =
765106f32e7eSjoerg               CXXUnit->mapLocationToPreamble(Tok.getLocation());
765206f32e7eSjoerg           MI = getMacroInfo(II, MappedTokLoc, TU);
765306f32e7eSjoerg         }
765406f32e7eSjoerg       }
765506f32e7eSjoerg 
765606f32e7eSjoerg       bool finished = false;
765706f32e7eSjoerg       do {
765806f32e7eSjoerg         if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
765906f32e7eSjoerg           finished = true;
766006f32e7eSjoerg           break;
766106f32e7eSjoerg         }
766206f32e7eSjoerg         // If we are in a macro definition, check if the token was ever a
766306f32e7eSjoerg         // macro name and annotate it if that's the case.
766406f32e7eSjoerg         if (MI) {
766506f32e7eSjoerg           SourceLocation SaveLoc = Tok.getLocation();
766606f32e7eSjoerg           Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
766706f32e7eSjoerg           MacroDefinitionRecord *MacroDef =
766806f32e7eSjoerg               checkForMacroInMacroDefinition(MI, Tok, TU);
766906f32e7eSjoerg           Tok.setLocation(SaveLoc);
767006f32e7eSjoerg           if (MacroDef)
767106f32e7eSjoerg             Cursors[NextIdx - 1] =
767206f32e7eSjoerg                 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
767306f32e7eSjoerg         }
767406f32e7eSjoerg       } while (!Tok.isAtStartOfLine());
767506f32e7eSjoerg 
767606f32e7eSjoerg       unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
767706f32e7eSjoerg       assert(TokIdx <= LastIdx);
767806f32e7eSjoerg       SourceLocation EndLoc =
767906f32e7eSjoerg           SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
768006f32e7eSjoerg       CXCursor Cursor =
768106f32e7eSjoerg           MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
768206f32e7eSjoerg 
768306f32e7eSjoerg       for (; TokIdx <= LastIdx; ++TokIdx)
768406f32e7eSjoerg         updateCursorAnnotation(Cursors[TokIdx], Cursor);
768506f32e7eSjoerg 
768606f32e7eSjoerg       if (finished)
768706f32e7eSjoerg         break;
768806f32e7eSjoerg       goto reprocess;
768906f32e7eSjoerg     }
769006f32e7eSjoerg   }
769106f32e7eSjoerg }
769206f32e7eSjoerg 
769306f32e7eSjoerg // This gets run a separate thread to avoid stack blowout.
clang_annotateTokensImpl(CXTranslationUnit TU,ASTUnit * CXXUnit,CXToken * Tokens,unsigned NumTokens,CXCursor * Cursors)769406f32e7eSjoerg static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
769506f32e7eSjoerg                                      CXToken *Tokens, unsigned NumTokens,
769606f32e7eSjoerg                                      CXCursor *Cursors) {
769706f32e7eSjoerg   CIndexer *CXXIdx = TU->CIdx;
769806f32e7eSjoerg   if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
769906f32e7eSjoerg     setThreadBackgroundPriority();
770006f32e7eSjoerg 
770106f32e7eSjoerg   // Determine the region of interest, which contains all of the tokens.
770206f32e7eSjoerg   SourceRange RegionOfInterest;
770306f32e7eSjoerg   RegionOfInterest.setBegin(
770406f32e7eSjoerg       cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7705*13fbcb42Sjoerg   RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7706*13fbcb42Sjoerg       clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
770706f32e7eSjoerg 
770806f32e7eSjoerg   // Relex the tokens within the source range to look for preprocessing
770906f32e7eSjoerg   // directives.
771006f32e7eSjoerg   annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
771106f32e7eSjoerg 
771206f32e7eSjoerg   // If begin location points inside a macro argument, set it to the expansion
771306f32e7eSjoerg   // location so we can have the full context when annotating semantically.
771406f32e7eSjoerg   {
771506f32e7eSjoerg     SourceManager &SM = CXXUnit->getSourceManager();
771606f32e7eSjoerg     SourceLocation Loc =
771706f32e7eSjoerg         SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
771806f32e7eSjoerg     if (Loc.isMacroID())
771906f32e7eSjoerg       RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
772006f32e7eSjoerg   }
772106f32e7eSjoerg 
772206f32e7eSjoerg   if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
772306f32e7eSjoerg     // Search and mark tokens that are macro argument expansions.
7724*13fbcb42Sjoerg     MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7725*13fbcb42Sjoerg                                       NumTokens);
7726*13fbcb42Sjoerg     CursorVisitor MacroArgMarker(
7727*13fbcb42Sjoerg         TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
772806f32e7eSjoerg         /*VisitPreprocessorLast=*/true,
7729*13fbcb42Sjoerg         /*VisitIncludedEntities=*/false, RegionOfInterest);
773006f32e7eSjoerg     MacroArgMarker.visitPreprocessedEntitiesInRegion();
773106f32e7eSjoerg   }
773206f32e7eSjoerg 
773306f32e7eSjoerg   // Annotate all of the source locations in the region of interest that map to
773406f32e7eSjoerg   // a specific cursor.
773506f32e7eSjoerg   AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
773606f32e7eSjoerg 
773706f32e7eSjoerg   // FIXME: We use a ridiculous stack size here because the data-recursion
773806f32e7eSjoerg   // algorithm uses a large stack frame than the non-data recursive version,
773906f32e7eSjoerg   // and AnnotationTokensWorker currently transforms the data-recursion
774006f32e7eSjoerg   // algorithm back into a traditional recursion by explicitly calling
774106f32e7eSjoerg   // VisitChildren().  We will need to remove this explicit recursive call.
774206f32e7eSjoerg   W.AnnotateTokens();
774306f32e7eSjoerg 
774406f32e7eSjoerg   // If we ran into any entities that involve context-sensitive keywords,
774506f32e7eSjoerg   // take another pass through the tokens to mark them as such.
774606f32e7eSjoerg   if (W.hasContextSensitiveKeywords()) {
774706f32e7eSjoerg     for (unsigned I = 0; I != NumTokens; ++I) {
774806f32e7eSjoerg       if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
774906f32e7eSjoerg         continue;
775006f32e7eSjoerg 
775106f32e7eSjoerg       if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
775206f32e7eSjoerg         IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7753*13fbcb42Sjoerg         if (const ObjCPropertyDecl *Property =
7754*13fbcb42Sjoerg                 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
775506f32e7eSjoerg           if (Property->getPropertyAttributesAsWritten() != 0 &&
775606f32e7eSjoerg               llvm::StringSwitch<bool>(II->getName())
775706f32e7eSjoerg                   .Case("readonly", true)
775806f32e7eSjoerg                   .Case("assign", true)
775906f32e7eSjoerg                   .Case("unsafe_unretained", true)
776006f32e7eSjoerg                   .Case("readwrite", true)
776106f32e7eSjoerg                   .Case("retain", true)
776206f32e7eSjoerg                   .Case("copy", true)
776306f32e7eSjoerg                   .Case("nonatomic", true)
776406f32e7eSjoerg                   .Case("atomic", true)
776506f32e7eSjoerg                   .Case("getter", true)
776606f32e7eSjoerg                   .Case("setter", true)
776706f32e7eSjoerg                   .Case("strong", true)
776806f32e7eSjoerg                   .Case("weak", true)
776906f32e7eSjoerg                   .Case("class", true)
777006f32e7eSjoerg                   .Default(false))
777106f32e7eSjoerg             Tokens[I].int_data[0] = CXToken_Keyword;
777206f32e7eSjoerg         }
777306f32e7eSjoerg         continue;
777406f32e7eSjoerg       }
777506f32e7eSjoerg 
777606f32e7eSjoerg       if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
777706f32e7eSjoerg           Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
777806f32e7eSjoerg         IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
777906f32e7eSjoerg         if (llvm::StringSwitch<bool>(II->getName())
778006f32e7eSjoerg                 .Case("in", true)
778106f32e7eSjoerg                 .Case("out", true)
778206f32e7eSjoerg                 .Case("inout", true)
778306f32e7eSjoerg                 .Case("oneway", true)
778406f32e7eSjoerg                 .Case("bycopy", true)
778506f32e7eSjoerg                 .Case("byref", true)
778606f32e7eSjoerg                 .Default(false))
778706f32e7eSjoerg           Tokens[I].int_data[0] = CXToken_Keyword;
778806f32e7eSjoerg         continue;
778906f32e7eSjoerg       }
779006f32e7eSjoerg 
779106f32e7eSjoerg       if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
779206f32e7eSjoerg           Cursors[I].kind == CXCursor_CXXOverrideAttr) {
779306f32e7eSjoerg         Tokens[I].int_data[0] = CXToken_Keyword;
779406f32e7eSjoerg         continue;
779506f32e7eSjoerg       }
779606f32e7eSjoerg     }
779706f32e7eSjoerg   }
779806f32e7eSjoerg }
779906f32e7eSjoerg 
clang_annotateTokens(CXTranslationUnit TU,CXToken * Tokens,unsigned NumTokens,CXCursor * Cursors)7800*13fbcb42Sjoerg void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7801*13fbcb42Sjoerg                           unsigned NumTokens, CXCursor *Cursors) {
780206f32e7eSjoerg   if (isNotUsableTU(TU)) {
780306f32e7eSjoerg     LOG_BAD_TU(TU);
780406f32e7eSjoerg     return;
780506f32e7eSjoerg   }
780606f32e7eSjoerg   if (NumTokens == 0 || !Tokens || !Cursors) {
780706f32e7eSjoerg     LOG_FUNC_SECTION { *Log << "<null input>"; }
780806f32e7eSjoerg     return;
780906f32e7eSjoerg   }
781006f32e7eSjoerg 
781106f32e7eSjoerg   LOG_FUNC_SECTION {
781206f32e7eSjoerg     *Log << TU << ' ';
781306f32e7eSjoerg     CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
781406f32e7eSjoerg     CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
781506f32e7eSjoerg     *Log << clang_getRange(bloc, eloc);
781606f32e7eSjoerg   }
781706f32e7eSjoerg 
781806f32e7eSjoerg   // Any token we don't specifically annotate will have a NULL cursor.
781906f32e7eSjoerg   CXCursor C = clang_getNullCursor();
782006f32e7eSjoerg   for (unsigned I = 0; I != NumTokens; ++I)
782106f32e7eSjoerg     Cursors[I] = C;
782206f32e7eSjoerg 
782306f32e7eSjoerg   ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
782406f32e7eSjoerg   if (!CXXUnit)
782506f32e7eSjoerg     return;
782606f32e7eSjoerg 
782706f32e7eSjoerg   ASTUnit::ConcurrencyCheck Check(*CXXUnit);
782806f32e7eSjoerg 
782906f32e7eSjoerg   auto AnnotateTokensImpl = [=]() {
783006f32e7eSjoerg     clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
783106f32e7eSjoerg   };
783206f32e7eSjoerg   llvm::CrashRecoveryContext CRC;
783306f32e7eSjoerg   if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
783406f32e7eSjoerg     fprintf(stderr, "libclang: crash detected while annotating tokens\n");
783506f32e7eSjoerg   }
783606f32e7eSjoerg }
783706f32e7eSjoerg 
783806f32e7eSjoerg //===----------------------------------------------------------------------===//
783906f32e7eSjoerg // Operations for querying linkage of a cursor.
784006f32e7eSjoerg //===----------------------------------------------------------------------===//
784106f32e7eSjoerg 
clang_getCursorLinkage(CXCursor cursor)784206f32e7eSjoerg CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
784306f32e7eSjoerg   if (!clang_isDeclaration(cursor.kind))
784406f32e7eSjoerg     return CXLinkage_Invalid;
784506f32e7eSjoerg 
784606f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(cursor);
784706f32e7eSjoerg   if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
784806f32e7eSjoerg     switch (ND->getLinkageInternal()) {
784906f32e7eSjoerg     case NoLinkage:
7850*13fbcb42Sjoerg     case VisibleNoLinkage:
7851*13fbcb42Sjoerg       return CXLinkage_NoLinkage;
785206f32e7eSjoerg     case ModuleInternalLinkage:
7853*13fbcb42Sjoerg     case InternalLinkage:
7854*13fbcb42Sjoerg       return CXLinkage_Internal;
7855*13fbcb42Sjoerg     case UniqueExternalLinkage:
7856*13fbcb42Sjoerg       return CXLinkage_UniqueExternal;
785706f32e7eSjoerg     case ModuleLinkage:
7858*13fbcb42Sjoerg     case ExternalLinkage:
7859*13fbcb42Sjoerg       return CXLinkage_External;
786006f32e7eSjoerg     };
786106f32e7eSjoerg 
786206f32e7eSjoerg   return CXLinkage_Invalid;
786306f32e7eSjoerg }
786406f32e7eSjoerg 
786506f32e7eSjoerg //===----------------------------------------------------------------------===//
786606f32e7eSjoerg // Operations for querying visibility of a cursor.
786706f32e7eSjoerg //===----------------------------------------------------------------------===//
786806f32e7eSjoerg 
clang_getCursorVisibility(CXCursor cursor)786906f32e7eSjoerg CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
787006f32e7eSjoerg   if (!clang_isDeclaration(cursor.kind))
787106f32e7eSjoerg     return CXVisibility_Invalid;
787206f32e7eSjoerg 
787306f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(cursor);
787406f32e7eSjoerg   if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
787506f32e7eSjoerg     switch (ND->getVisibility()) {
7876*13fbcb42Sjoerg     case HiddenVisibility:
7877*13fbcb42Sjoerg       return CXVisibility_Hidden;
7878*13fbcb42Sjoerg     case ProtectedVisibility:
7879*13fbcb42Sjoerg       return CXVisibility_Protected;
7880*13fbcb42Sjoerg     case DefaultVisibility:
7881*13fbcb42Sjoerg       return CXVisibility_Default;
788206f32e7eSjoerg     };
788306f32e7eSjoerg 
788406f32e7eSjoerg   return CXVisibility_Invalid;
788506f32e7eSjoerg }
788606f32e7eSjoerg 
788706f32e7eSjoerg //===----------------------------------------------------------------------===//
788806f32e7eSjoerg // Operations for querying language of a cursor.
788906f32e7eSjoerg //===----------------------------------------------------------------------===//
789006f32e7eSjoerg 
getDeclLanguage(const Decl * D)789106f32e7eSjoerg static CXLanguageKind getDeclLanguage(const Decl *D) {
789206f32e7eSjoerg   if (!D)
789306f32e7eSjoerg     return CXLanguage_C;
789406f32e7eSjoerg 
789506f32e7eSjoerg   switch (D->getKind()) {
789606f32e7eSjoerg   default:
789706f32e7eSjoerg     break;
789806f32e7eSjoerg   case Decl::ImplicitParam:
789906f32e7eSjoerg   case Decl::ObjCAtDefsField:
790006f32e7eSjoerg   case Decl::ObjCCategory:
790106f32e7eSjoerg   case Decl::ObjCCategoryImpl:
790206f32e7eSjoerg   case Decl::ObjCCompatibleAlias:
790306f32e7eSjoerg   case Decl::ObjCImplementation:
790406f32e7eSjoerg   case Decl::ObjCInterface:
790506f32e7eSjoerg   case Decl::ObjCIvar:
790606f32e7eSjoerg   case Decl::ObjCMethod:
790706f32e7eSjoerg   case Decl::ObjCProperty:
790806f32e7eSjoerg   case Decl::ObjCPropertyImpl:
790906f32e7eSjoerg   case Decl::ObjCProtocol:
791006f32e7eSjoerg   case Decl::ObjCTypeParam:
791106f32e7eSjoerg     return CXLanguage_ObjC;
791206f32e7eSjoerg   case Decl::CXXConstructor:
791306f32e7eSjoerg   case Decl::CXXConversion:
791406f32e7eSjoerg   case Decl::CXXDestructor:
791506f32e7eSjoerg   case Decl::CXXMethod:
791606f32e7eSjoerg   case Decl::CXXRecord:
791706f32e7eSjoerg   case Decl::ClassTemplate:
791806f32e7eSjoerg   case Decl::ClassTemplatePartialSpecialization:
791906f32e7eSjoerg   case Decl::ClassTemplateSpecialization:
792006f32e7eSjoerg   case Decl::Friend:
792106f32e7eSjoerg   case Decl::FriendTemplate:
792206f32e7eSjoerg   case Decl::FunctionTemplate:
792306f32e7eSjoerg   case Decl::LinkageSpec:
792406f32e7eSjoerg   case Decl::Namespace:
792506f32e7eSjoerg   case Decl::NamespaceAlias:
792606f32e7eSjoerg   case Decl::NonTypeTemplateParm:
792706f32e7eSjoerg   case Decl::StaticAssert:
792806f32e7eSjoerg   case Decl::TemplateTemplateParm:
792906f32e7eSjoerg   case Decl::TemplateTypeParm:
793006f32e7eSjoerg   case Decl::UnresolvedUsingTypename:
793106f32e7eSjoerg   case Decl::UnresolvedUsingValue:
793206f32e7eSjoerg   case Decl::Using:
793306f32e7eSjoerg   case Decl::UsingDirective:
793406f32e7eSjoerg   case Decl::UsingShadow:
793506f32e7eSjoerg     return CXLanguage_CPlusPlus;
793606f32e7eSjoerg   }
793706f32e7eSjoerg 
793806f32e7eSjoerg   return CXLanguage_C;
793906f32e7eSjoerg }
794006f32e7eSjoerg 
getCursorAvailabilityForDecl(const Decl * D)794106f32e7eSjoerg static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
794206f32e7eSjoerg   if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
794306f32e7eSjoerg     return CXAvailability_NotAvailable;
794406f32e7eSjoerg 
794506f32e7eSjoerg   switch (D->getAvailability()) {
794606f32e7eSjoerg   case AR_Available:
794706f32e7eSjoerg   case AR_NotYetIntroduced:
794806f32e7eSjoerg     if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
794906f32e7eSjoerg       return getCursorAvailabilityForDecl(
795006f32e7eSjoerg           cast<Decl>(EnumConst->getDeclContext()));
795106f32e7eSjoerg     return CXAvailability_Available;
795206f32e7eSjoerg 
795306f32e7eSjoerg   case AR_Deprecated:
795406f32e7eSjoerg     return CXAvailability_Deprecated;
795506f32e7eSjoerg 
795606f32e7eSjoerg   case AR_Unavailable:
795706f32e7eSjoerg     return CXAvailability_NotAvailable;
795806f32e7eSjoerg   }
795906f32e7eSjoerg 
796006f32e7eSjoerg   llvm_unreachable("Unknown availability kind!");
796106f32e7eSjoerg }
796206f32e7eSjoerg 
clang_getCursorAvailability(CXCursor cursor)796306f32e7eSjoerg enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
796406f32e7eSjoerg   if (clang_isDeclaration(cursor.kind))
796506f32e7eSjoerg     if (const Decl *D = cxcursor::getCursorDecl(cursor))
796606f32e7eSjoerg       return getCursorAvailabilityForDecl(D);
796706f32e7eSjoerg 
796806f32e7eSjoerg   return CXAvailability_Available;
796906f32e7eSjoerg }
797006f32e7eSjoerg 
convertVersion(VersionTuple In)797106f32e7eSjoerg static CXVersion convertVersion(VersionTuple In) {
797206f32e7eSjoerg   CXVersion Out = {-1, -1, -1};
797306f32e7eSjoerg   if (In.empty())
797406f32e7eSjoerg     return Out;
797506f32e7eSjoerg 
797606f32e7eSjoerg   Out.Major = In.getMajor();
797706f32e7eSjoerg 
797806f32e7eSjoerg   Optional<unsigned> Minor = In.getMinor();
797906f32e7eSjoerg   if (Minor.hasValue())
798006f32e7eSjoerg     Out.Minor = *Minor;
798106f32e7eSjoerg   else
798206f32e7eSjoerg     return Out;
798306f32e7eSjoerg 
798406f32e7eSjoerg   Optional<unsigned> Subminor = In.getSubminor();
798506f32e7eSjoerg   if (Subminor.hasValue())
798606f32e7eSjoerg     Out.Subminor = *Subminor;
798706f32e7eSjoerg 
798806f32e7eSjoerg   return Out;
798906f32e7eSjoerg }
799006f32e7eSjoerg 
getCursorPlatformAvailabilityForDecl(const Decl * D,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,SmallVectorImpl<AvailabilityAttr * > & AvailabilityAttrs)799106f32e7eSjoerg static void getCursorPlatformAvailabilityForDecl(
799206f32e7eSjoerg     const Decl *D, int *always_deprecated, CXString *deprecated_message,
799306f32e7eSjoerg     int *always_unavailable, CXString *unavailable_message,
799406f32e7eSjoerg     SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
799506f32e7eSjoerg   bool HadAvailAttr = false;
799606f32e7eSjoerg   for (auto A : D->attrs()) {
799706f32e7eSjoerg     if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
799806f32e7eSjoerg       HadAvailAttr = true;
799906f32e7eSjoerg       if (always_deprecated)
800006f32e7eSjoerg         *always_deprecated = 1;
800106f32e7eSjoerg       if (deprecated_message) {
800206f32e7eSjoerg         clang_disposeString(*deprecated_message);
800306f32e7eSjoerg         *deprecated_message = cxstring::createDup(Deprecated->getMessage());
800406f32e7eSjoerg       }
800506f32e7eSjoerg       continue;
800606f32e7eSjoerg     }
800706f32e7eSjoerg 
800806f32e7eSjoerg     if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
800906f32e7eSjoerg       HadAvailAttr = true;
801006f32e7eSjoerg       if (always_unavailable)
801106f32e7eSjoerg         *always_unavailable = 1;
801206f32e7eSjoerg       if (unavailable_message) {
801306f32e7eSjoerg         clang_disposeString(*unavailable_message);
801406f32e7eSjoerg         *unavailable_message = cxstring::createDup(Unavailable->getMessage());
801506f32e7eSjoerg       }
801606f32e7eSjoerg       continue;
801706f32e7eSjoerg     }
801806f32e7eSjoerg 
801906f32e7eSjoerg     if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
802006f32e7eSjoerg       AvailabilityAttrs.push_back(Avail);
802106f32e7eSjoerg       HadAvailAttr = true;
802206f32e7eSjoerg     }
802306f32e7eSjoerg   }
802406f32e7eSjoerg 
802506f32e7eSjoerg   if (!HadAvailAttr)
802606f32e7eSjoerg     if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
802706f32e7eSjoerg       return getCursorPlatformAvailabilityForDecl(
802806f32e7eSjoerg           cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
802906f32e7eSjoerg           deprecated_message, always_unavailable, unavailable_message,
803006f32e7eSjoerg           AvailabilityAttrs);
803106f32e7eSjoerg 
803206f32e7eSjoerg   if (AvailabilityAttrs.empty())
803306f32e7eSjoerg     return;
803406f32e7eSjoerg 
8035*13fbcb42Sjoerg   llvm::sort(
8036*13fbcb42Sjoerg       AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
8037*13fbcb42Sjoerg         return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
803806f32e7eSjoerg       });
803906f32e7eSjoerg   ASTContext &Ctx = D->getASTContext();
804006f32e7eSjoerg   auto It = std::unique(
804106f32e7eSjoerg       AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
804206f32e7eSjoerg       [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
804306f32e7eSjoerg         if (LHS->getPlatform() != RHS->getPlatform())
804406f32e7eSjoerg           return false;
804506f32e7eSjoerg 
804606f32e7eSjoerg         if (LHS->getIntroduced() == RHS->getIntroduced() &&
804706f32e7eSjoerg             LHS->getDeprecated() == RHS->getDeprecated() &&
804806f32e7eSjoerg             LHS->getObsoleted() == RHS->getObsoleted() &&
804906f32e7eSjoerg             LHS->getMessage() == RHS->getMessage() &&
805006f32e7eSjoerg             LHS->getReplacement() == RHS->getReplacement())
805106f32e7eSjoerg           return true;
805206f32e7eSjoerg 
805306f32e7eSjoerg         if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
805406f32e7eSjoerg             (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
805506f32e7eSjoerg             (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
805606f32e7eSjoerg           return false;
805706f32e7eSjoerg 
805806f32e7eSjoerg         if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
805906f32e7eSjoerg           LHS->setIntroduced(Ctx, RHS->getIntroduced());
806006f32e7eSjoerg 
806106f32e7eSjoerg         if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
806206f32e7eSjoerg           LHS->setDeprecated(Ctx, RHS->getDeprecated());
806306f32e7eSjoerg           if (LHS->getMessage().empty())
806406f32e7eSjoerg             LHS->setMessage(Ctx, RHS->getMessage());
806506f32e7eSjoerg           if (LHS->getReplacement().empty())
806606f32e7eSjoerg             LHS->setReplacement(Ctx, RHS->getReplacement());
806706f32e7eSjoerg         }
806806f32e7eSjoerg 
806906f32e7eSjoerg         if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
807006f32e7eSjoerg           LHS->setObsoleted(Ctx, RHS->getObsoleted());
807106f32e7eSjoerg           if (LHS->getMessage().empty())
807206f32e7eSjoerg             LHS->setMessage(Ctx, RHS->getMessage());
807306f32e7eSjoerg           if (LHS->getReplacement().empty())
807406f32e7eSjoerg             LHS->setReplacement(Ctx, RHS->getReplacement());
807506f32e7eSjoerg         }
807606f32e7eSjoerg 
807706f32e7eSjoerg         return true;
807806f32e7eSjoerg       });
807906f32e7eSjoerg   AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
808006f32e7eSjoerg }
808106f32e7eSjoerg 
clang_getCursorPlatformAvailability(CXCursor cursor,int * always_deprecated,CXString * deprecated_message,int * always_unavailable,CXString * unavailable_message,CXPlatformAvailability * availability,int availability_size)808206f32e7eSjoerg int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
808306f32e7eSjoerg                                         CXString *deprecated_message,
808406f32e7eSjoerg                                         int *always_unavailable,
808506f32e7eSjoerg                                         CXString *unavailable_message,
808606f32e7eSjoerg                                         CXPlatformAvailability *availability,
808706f32e7eSjoerg                                         int availability_size) {
808806f32e7eSjoerg   if (always_deprecated)
808906f32e7eSjoerg     *always_deprecated = 0;
809006f32e7eSjoerg   if (deprecated_message)
809106f32e7eSjoerg     *deprecated_message = cxstring::createEmpty();
809206f32e7eSjoerg   if (always_unavailable)
809306f32e7eSjoerg     *always_unavailable = 0;
809406f32e7eSjoerg   if (unavailable_message)
809506f32e7eSjoerg     *unavailable_message = cxstring::createEmpty();
809606f32e7eSjoerg 
809706f32e7eSjoerg   if (!clang_isDeclaration(cursor.kind))
809806f32e7eSjoerg     return 0;
809906f32e7eSjoerg 
810006f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(cursor);
810106f32e7eSjoerg   if (!D)
810206f32e7eSjoerg     return 0;
810306f32e7eSjoerg 
810406f32e7eSjoerg   SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
810506f32e7eSjoerg   getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
810606f32e7eSjoerg                                        always_unavailable, unavailable_message,
810706f32e7eSjoerg                                        AvailabilityAttrs);
810806f32e7eSjoerg   for (const auto &Avail :
810906f32e7eSjoerg        llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
811006f32e7eSjoerg                            .take_front(availability_size))) {
811106f32e7eSjoerg     availability[Avail.index()].Platform =
811206f32e7eSjoerg         cxstring::createDup(Avail.value()->getPlatform()->getName());
811306f32e7eSjoerg     availability[Avail.index()].Introduced =
811406f32e7eSjoerg         convertVersion(Avail.value()->getIntroduced());
811506f32e7eSjoerg     availability[Avail.index()].Deprecated =
811606f32e7eSjoerg         convertVersion(Avail.value()->getDeprecated());
811706f32e7eSjoerg     availability[Avail.index()].Obsoleted =
811806f32e7eSjoerg         convertVersion(Avail.value()->getObsoleted());
811906f32e7eSjoerg     availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
812006f32e7eSjoerg     availability[Avail.index()].Message =
812106f32e7eSjoerg         cxstring::createDup(Avail.value()->getMessage());
812206f32e7eSjoerg   }
812306f32e7eSjoerg 
812406f32e7eSjoerg   return AvailabilityAttrs.size();
812506f32e7eSjoerg }
812606f32e7eSjoerg 
clang_disposeCXPlatformAvailability(CXPlatformAvailability * availability)812706f32e7eSjoerg void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
812806f32e7eSjoerg   clang_disposeString(availability->Platform);
812906f32e7eSjoerg   clang_disposeString(availability->Message);
813006f32e7eSjoerg }
813106f32e7eSjoerg 
clang_getCursorLanguage(CXCursor cursor)813206f32e7eSjoerg CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
813306f32e7eSjoerg   if (clang_isDeclaration(cursor.kind))
813406f32e7eSjoerg     return getDeclLanguage(cxcursor::getCursorDecl(cursor));
813506f32e7eSjoerg 
813606f32e7eSjoerg   return CXLanguage_Invalid;
813706f32e7eSjoerg }
813806f32e7eSjoerg 
clang_getCursorTLSKind(CXCursor cursor)813906f32e7eSjoerg CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
814006f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(cursor);
814106f32e7eSjoerg   if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
814206f32e7eSjoerg     switch (VD->getTLSKind()) {
814306f32e7eSjoerg     case VarDecl::TLS_None:
814406f32e7eSjoerg       return CXTLS_None;
814506f32e7eSjoerg     case VarDecl::TLS_Dynamic:
814606f32e7eSjoerg       return CXTLS_Dynamic;
814706f32e7eSjoerg     case VarDecl::TLS_Static:
814806f32e7eSjoerg       return CXTLS_Static;
814906f32e7eSjoerg     }
815006f32e7eSjoerg   }
815106f32e7eSjoerg 
815206f32e7eSjoerg   return CXTLS_None;
815306f32e7eSjoerg }
815406f32e7eSjoerg 
815506f32e7eSjoerg /// If the given cursor is the "templated" declaration
815606f32e7eSjoerg /// describing a class or function template, return the class or
815706f32e7eSjoerg /// function template.
maybeGetTemplateCursor(const Decl * D)815806f32e7eSjoerg static const Decl *maybeGetTemplateCursor(const Decl *D) {
815906f32e7eSjoerg   if (!D)
816006f32e7eSjoerg     return nullptr;
816106f32e7eSjoerg 
816206f32e7eSjoerg   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
816306f32e7eSjoerg     if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
816406f32e7eSjoerg       return FunTmpl;
816506f32e7eSjoerg 
816606f32e7eSjoerg   if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
816706f32e7eSjoerg     if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
816806f32e7eSjoerg       return ClassTmpl;
816906f32e7eSjoerg 
817006f32e7eSjoerg   return D;
817106f32e7eSjoerg }
817206f32e7eSjoerg 
clang_Cursor_getStorageClass(CXCursor C)817306f32e7eSjoerg enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
817406f32e7eSjoerg   StorageClass sc = SC_None;
817506f32e7eSjoerg   const Decl *D = getCursorDecl(C);
817606f32e7eSjoerg   if (D) {
817706f32e7eSjoerg     if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
817806f32e7eSjoerg       sc = FD->getStorageClass();
817906f32e7eSjoerg     } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
818006f32e7eSjoerg       sc = VD->getStorageClass();
818106f32e7eSjoerg     } else {
818206f32e7eSjoerg       return CX_SC_Invalid;
818306f32e7eSjoerg     }
818406f32e7eSjoerg   } else {
818506f32e7eSjoerg     return CX_SC_Invalid;
818606f32e7eSjoerg   }
818706f32e7eSjoerg   switch (sc) {
818806f32e7eSjoerg   case SC_None:
818906f32e7eSjoerg     return CX_SC_None;
819006f32e7eSjoerg   case SC_Extern:
819106f32e7eSjoerg     return CX_SC_Extern;
819206f32e7eSjoerg   case SC_Static:
819306f32e7eSjoerg     return CX_SC_Static;
819406f32e7eSjoerg   case SC_PrivateExtern:
819506f32e7eSjoerg     return CX_SC_PrivateExtern;
819606f32e7eSjoerg   case SC_Auto:
819706f32e7eSjoerg     return CX_SC_Auto;
819806f32e7eSjoerg   case SC_Register:
819906f32e7eSjoerg     return CX_SC_Register;
820006f32e7eSjoerg   }
820106f32e7eSjoerg   llvm_unreachable("Unhandled storage class!");
820206f32e7eSjoerg }
820306f32e7eSjoerg 
clang_getCursorSemanticParent(CXCursor cursor)820406f32e7eSjoerg CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
820506f32e7eSjoerg   if (clang_isDeclaration(cursor.kind)) {
820606f32e7eSjoerg     if (const Decl *D = getCursorDecl(cursor)) {
820706f32e7eSjoerg       const DeclContext *DC = D->getDeclContext();
820806f32e7eSjoerg       if (!DC)
820906f32e7eSjoerg         return clang_getNullCursor();
821006f32e7eSjoerg 
821106f32e7eSjoerg       return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
821206f32e7eSjoerg                           getCursorTU(cursor));
821306f32e7eSjoerg     }
821406f32e7eSjoerg   }
821506f32e7eSjoerg 
821606f32e7eSjoerg   if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
821706f32e7eSjoerg     if (const Decl *D = getCursorDecl(cursor))
821806f32e7eSjoerg       return MakeCXCursor(D, getCursorTU(cursor));
821906f32e7eSjoerg   }
822006f32e7eSjoerg 
822106f32e7eSjoerg   return clang_getNullCursor();
822206f32e7eSjoerg }
822306f32e7eSjoerg 
clang_getCursorLexicalParent(CXCursor cursor)822406f32e7eSjoerg CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
822506f32e7eSjoerg   if (clang_isDeclaration(cursor.kind)) {
822606f32e7eSjoerg     if (const Decl *D = getCursorDecl(cursor)) {
822706f32e7eSjoerg       const DeclContext *DC = D->getLexicalDeclContext();
822806f32e7eSjoerg       if (!DC)
822906f32e7eSjoerg         return clang_getNullCursor();
823006f32e7eSjoerg 
823106f32e7eSjoerg       return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
823206f32e7eSjoerg                           getCursorTU(cursor));
823306f32e7eSjoerg     }
823406f32e7eSjoerg   }
823506f32e7eSjoerg 
823606f32e7eSjoerg   // FIXME: Note that we can't easily compute the lexical context of a
823706f32e7eSjoerg   // statement or expression, so we return nothing.
823806f32e7eSjoerg   return clang_getNullCursor();
823906f32e7eSjoerg }
824006f32e7eSjoerg 
clang_getIncludedFile(CXCursor cursor)824106f32e7eSjoerg CXFile clang_getIncludedFile(CXCursor cursor) {
824206f32e7eSjoerg   if (cursor.kind != CXCursor_InclusionDirective)
824306f32e7eSjoerg     return nullptr;
824406f32e7eSjoerg 
824506f32e7eSjoerg   const InclusionDirective *ID = getCursorInclusionDirective(cursor);
824606f32e7eSjoerg   return const_cast<FileEntry *>(ID->getFile());
824706f32e7eSjoerg }
824806f32e7eSjoerg 
clang_Cursor_getObjCPropertyAttributes(CXCursor C,unsigned reserved)824906f32e7eSjoerg unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
825006f32e7eSjoerg   if (C.kind != CXCursor_ObjCPropertyDecl)
825106f32e7eSjoerg     return CXObjCPropertyAttr_noattr;
825206f32e7eSjoerg 
825306f32e7eSjoerg   unsigned Result = CXObjCPropertyAttr_noattr;
825406f32e7eSjoerg   const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8255*13fbcb42Sjoerg   ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
825606f32e7eSjoerg 
825706f32e7eSjoerg #define SET_CXOBJCPROP_ATTR(A)                                                 \
8258*13fbcb42Sjoerg   if (Attr & ObjCPropertyAttribute::kind_##A)                                  \
825906f32e7eSjoerg   Result |= CXObjCPropertyAttr_##A
826006f32e7eSjoerg   SET_CXOBJCPROP_ATTR(readonly);
826106f32e7eSjoerg   SET_CXOBJCPROP_ATTR(getter);
826206f32e7eSjoerg   SET_CXOBJCPROP_ATTR(assign);
826306f32e7eSjoerg   SET_CXOBJCPROP_ATTR(readwrite);
826406f32e7eSjoerg   SET_CXOBJCPROP_ATTR(retain);
826506f32e7eSjoerg   SET_CXOBJCPROP_ATTR(copy);
826606f32e7eSjoerg   SET_CXOBJCPROP_ATTR(nonatomic);
826706f32e7eSjoerg   SET_CXOBJCPROP_ATTR(setter);
826806f32e7eSjoerg   SET_CXOBJCPROP_ATTR(atomic);
826906f32e7eSjoerg   SET_CXOBJCPROP_ATTR(weak);
827006f32e7eSjoerg   SET_CXOBJCPROP_ATTR(strong);
827106f32e7eSjoerg   SET_CXOBJCPROP_ATTR(unsafe_unretained);
827206f32e7eSjoerg   SET_CXOBJCPROP_ATTR(class);
827306f32e7eSjoerg #undef SET_CXOBJCPROP_ATTR
827406f32e7eSjoerg 
827506f32e7eSjoerg   return Result;
827606f32e7eSjoerg }
827706f32e7eSjoerg 
clang_Cursor_getObjCPropertyGetterName(CXCursor C)827806f32e7eSjoerg CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
827906f32e7eSjoerg   if (C.kind != CXCursor_ObjCPropertyDecl)
828006f32e7eSjoerg     return cxstring::createNull();
828106f32e7eSjoerg 
828206f32e7eSjoerg   const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
828306f32e7eSjoerg   Selector sel = PD->getGetterName();
828406f32e7eSjoerg   if (sel.isNull())
828506f32e7eSjoerg     return cxstring::createNull();
828606f32e7eSjoerg 
828706f32e7eSjoerg   return cxstring::createDup(sel.getAsString());
828806f32e7eSjoerg }
828906f32e7eSjoerg 
clang_Cursor_getObjCPropertySetterName(CXCursor C)829006f32e7eSjoerg CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
829106f32e7eSjoerg   if (C.kind != CXCursor_ObjCPropertyDecl)
829206f32e7eSjoerg     return cxstring::createNull();
829306f32e7eSjoerg 
829406f32e7eSjoerg   const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
829506f32e7eSjoerg   Selector sel = PD->getSetterName();
829606f32e7eSjoerg   if (sel.isNull())
829706f32e7eSjoerg     return cxstring::createNull();
829806f32e7eSjoerg 
829906f32e7eSjoerg   return cxstring::createDup(sel.getAsString());
830006f32e7eSjoerg }
830106f32e7eSjoerg 
clang_Cursor_getObjCDeclQualifiers(CXCursor C)830206f32e7eSjoerg unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
830306f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
830406f32e7eSjoerg     return CXObjCDeclQualifier_None;
830506f32e7eSjoerg 
830606f32e7eSjoerg   Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
830706f32e7eSjoerg   const Decl *D = getCursorDecl(C);
830806f32e7eSjoerg   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
830906f32e7eSjoerg     QT = MD->getObjCDeclQualifier();
831006f32e7eSjoerg   else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
831106f32e7eSjoerg     QT = PD->getObjCDeclQualifier();
831206f32e7eSjoerg   if (QT == Decl::OBJC_TQ_None)
831306f32e7eSjoerg     return CXObjCDeclQualifier_None;
831406f32e7eSjoerg 
831506f32e7eSjoerg   unsigned Result = CXObjCDeclQualifier_None;
8316*13fbcb42Sjoerg   if (QT & Decl::OBJC_TQ_In)
8317*13fbcb42Sjoerg     Result |= CXObjCDeclQualifier_In;
8318*13fbcb42Sjoerg   if (QT & Decl::OBJC_TQ_Inout)
8319*13fbcb42Sjoerg     Result |= CXObjCDeclQualifier_Inout;
8320*13fbcb42Sjoerg   if (QT & Decl::OBJC_TQ_Out)
8321*13fbcb42Sjoerg     Result |= CXObjCDeclQualifier_Out;
8322*13fbcb42Sjoerg   if (QT & Decl::OBJC_TQ_Bycopy)
8323*13fbcb42Sjoerg     Result |= CXObjCDeclQualifier_Bycopy;
8324*13fbcb42Sjoerg   if (QT & Decl::OBJC_TQ_Byref)
8325*13fbcb42Sjoerg     Result |= CXObjCDeclQualifier_Byref;
8326*13fbcb42Sjoerg   if (QT & Decl::OBJC_TQ_Oneway)
8327*13fbcb42Sjoerg     Result |= CXObjCDeclQualifier_Oneway;
832806f32e7eSjoerg 
832906f32e7eSjoerg   return Result;
833006f32e7eSjoerg }
833106f32e7eSjoerg 
clang_Cursor_isObjCOptional(CXCursor C)833206f32e7eSjoerg unsigned clang_Cursor_isObjCOptional(CXCursor C) {
833306f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
833406f32e7eSjoerg     return 0;
833506f32e7eSjoerg 
833606f32e7eSjoerg   const Decl *D = getCursorDecl(C);
833706f32e7eSjoerg   if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
833806f32e7eSjoerg     return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
833906f32e7eSjoerg   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
834006f32e7eSjoerg     return MD->getImplementationControl() == ObjCMethodDecl::Optional;
834106f32e7eSjoerg 
834206f32e7eSjoerg   return 0;
834306f32e7eSjoerg }
834406f32e7eSjoerg 
clang_Cursor_isVariadic(CXCursor C)834506f32e7eSjoerg unsigned clang_Cursor_isVariadic(CXCursor C) {
834606f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
834706f32e7eSjoerg     return 0;
834806f32e7eSjoerg 
834906f32e7eSjoerg   const Decl *D = getCursorDecl(C);
835006f32e7eSjoerg   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
835106f32e7eSjoerg     return FD->isVariadic();
835206f32e7eSjoerg   if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
835306f32e7eSjoerg     return MD->isVariadic();
835406f32e7eSjoerg 
835506f32e7eSjoerg   return 0;
835606f32e7eSjoerg }
835706f32e7eSjoerg 
clang_Cursor_isExternalSymbol(CXCursor C,CXString * language,CXString * definedIn,unsigned * isGenerated)8358*13fbcb42Sjoerg unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8359*13fbcb42Sjoerg                                        CXString *definedIn,
836006f32e7eSjoerg                                        unsigned *isGenerated) {
836106f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
836206f32e7eSjoerg     return 0;
836306f32e7eSjoerg 
836406f32e7eSjoerg   const Decl *D = getCursorDecl(C);
836506f32e7eSjoerg 
836606f32e7eSjoerg   if (auto *attr = D->getExternalSourceSymbolAttr()) {
836706f32e7eSjoerg     if (language)
836806f32e7eSjoerg       *language = cxstring::createDup(attr->getLanguage());
836906f32e7eSjoerg     if (definedIn)
837006f32e7eSjoerg       *definedIn = cxstring::createDup(attr->getDefinedIn());
837106f32e7eSjoerg     if (isGenerated)
837206f32e7eSjoerg       *isGenerated = attr->getGeneratedDeclaration();
837306f32e7eSjoerg     return 1;
837406f32e7eSjoerg   }
837506f32e7eSjoerg   return 0;
837606f32e7eSjoerg }
837706f32e7eSjoerg 
clang_Cursor_getCommentRange(CXCursor C)837806f32e7eSjoerg CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
837906f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
838006f32e7eSjoerg     return clang_getNullRange();
838106f32e7eSjoerg 
838206f32e7eSjoerg   const Decl *D = getCursorDecl(C);
838306f32e7eSjoerg   ASTContext &Context = getCursorContext(C);
838406f32e7eSjoerg   const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
838506f32e7eSjoerg   if (!RC)
838606f32e7eSjoerg     return clang_getNullRange();
838706f32e7eSjoerg 
838806f32e7eSjoerg   return cxloc::translateSourceRange(Context, RC->getSourceRange());
838906f32e7eSjoerg }
839006f32e7eSjoerg 
clang_Cursor_getRawCommentText(CXCursor C)839106f32e7eSjoerg CXString clang_Cursor_getRawCommentText(CXCursor C) {
839206f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
839306f32e7eSjoerg     return cxstring::createNull();
839406f32e7eSjoerg 
839506f32e7eSjoerg   const Decl *D = getCursorDecl(C);
839606f32e7eSjoerg   ASTContext &Context = getCursorContext(C);
839706f32e7eSjoerg   const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8398*13fbcb42Sjoerg   StringRef RawText =
8399*13fbcb42Sjoerg       RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
840006f32e7eSjoerg 
840106f32e7eSjoerg   // Don't duplicate the string because RawText points directly into source
840206f32e7eSjoerg   // code.
840306f32e7eSjoerg   return cxstring::createRef(RawText);
840406f32e7eSjoerg }
840506f32e7eSjoerg 
clang_Cursor_getBriefCommentText(CXCursor C)840606f32e7eSjoerg CXString clang_Cursor_getBriefCommentText(CXCursor C) {
840706f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
840806f32e7eSjoerg     return cxstring::createNull();
840906f32e7eSjoerg 
841006f32e7eSjoerg   const Decl *D = getCursorDecl(C);
841106f32e7eSjoerg   const ASTContext &Context = getCursorContext(C);
841206f32e7eSjoerg   const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
841306f32e7eSjoerg 
841406f32e7eSjoerg   if (RC) {
841506f32e7eSjoerg     StringRef BriefText = RC->getBriefText(Context);
841606f32e7eSjoerg 
841706f32e7eSjoerg     // Don't duplicate the string because RawComment ensures that this memory
841806f32e7eSjoerg     // will not go away.
841906f32e7eSjoerg     return cxstring::createRef(BriefText);
842006f32e7eSjoerg   }
842106f32e7eSjoerg 
842206f32e7eSjoerg   return cxstring::createNull();
842306f32e7eSjoerg }
842406f32e7eSjoerg 
clang_Cursor_getModule(CXCursor C)842506f32e7eSjoerg CXModule clang_Cursor_getModule(CXCursor C) {
842606f32e7eSjoerg   if (C.kind == CXCursor_ModuleImportDecl) {
842706f32e7eSjoerg     if (const ImportDecl *ImportD =
842806f32e7eSjoerg             dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
842906f32e7eSjoerg       return ImportD->getImportedModule();
843006f32e7eSjoerg   }
843106f32e7eSjoerg 
843206f32e7eSjoerg   return nullptr;
843306f32e7eSjoerg }
843406f32e7eSjoerg 
clang_getModuleForFile(CXTranslationUnit TU,CXFile File)843506f32e7eSjoerg CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
843606f32e7eSjoerg   if (isNotUsableTU(TU)) {
843706f32e7eSjoerg     LOG_BAD_TU(TU);
843806f32e7eSjoerg     return nullptr;
843906f32e7eSjoerg   }
844006f32e7eSjoerg   if (!File)
844106f32e7eSjoerg     return nullptr;
844206f32e7eSjoerg   FileEntry *FE = static_cast<FileEntry *>(File);
844306f32e7eSjoerg 
844406f32e7eSjoerg   ASTUnit &Unit = *cxtu::getASTUnit(TU);
844506f32e7eSjoerg   HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
844606f32e7eSjoerg   ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
844706f32e7eSjoerg 
844806f32e7eSjoerg   return Header.getModule();
844906f32e7eSjoerg }
845006f32e7eSjoerg 
clang_Module_getASTFile(CXModule CXMod)845106f32e7eSjoerg CXFile clang_Module_getASTFile(CXModule CXMod) {
845206f32e7eSjoerg   if (!CXMod)
845306f32e7eSjoerg     return nullptr;
845406f32e7eSjoerg   Module *Mod = static_cast<Module *>(CXMod);
8455*13fbcb42Sjoerg   if (auto File = Mod->getASTFile())
8456*13fbcb42Sjoerg     return const_cast<FileEntry *>(&File->getFileEntry());
8457*13fbcb42Sjoerg   return nullptr;
845806f32e7eSjoerg }
845906f32e7eSjoerg 
clang_Module_getParent(CXModule CXMod)846006f32e7eSjoerg CXModule clang_Module_getParent(CXModule CXMod) {
846106f32e7eSjoerg   if (!CXMod)
846206f32e7eSjoerg     return nullptr;
846306f32e7eSjoerg   Module *Mod = static_cast<Module *>(CXMod);
846406f32e7eSjoerg   return Mod->Parent;
846506f32e7eSjoerg }
846606f32e7eSjoerg 
clang_Module_getName(CXModule CXMod)846706f32e7eSjoerg CXString clang_Module_getName(CXModule CXMod) {
846806f32e7eSjoerg   if (!CXMod)
846906f32e7eSjoerg     return cxstring::createEmpty();
847006f32e7eSjoerg   Module *Mod = static_cast<Module *>(CXMod);
847106f32e7eSjoerg   return cxstring::createDup(Mod->Name);
847206f32e7eSjoerg }
847306f32e7eSjoerg 
clang_Module_getFullName(CXModule CXMod)847406f32e7eSjoerg CXString clang_Module_getFullName(CXModule CXMod) {
847506f32e7eSjoerg   if (!CXMod)
847606f32e7eSjoerg     return cxstring::createEmpty();
847706f32e7eSjoerg   Module *Mod = static_cast<Module *>(CXMod);
847806f32e7eSjoerg   return cxstring::createDup(Mod->getFullModuleName());
847906f32e7eSjoerg }
848006f32e7eSjoerg 
clang_Module_isSystem(CXModule CXMod)848106f32e7eSjoerg int clang_Module_isSystem(CXModule CXMod) {
848206f32e7eSjoerg   if (!CXMod)
848306f32e7eSjoerg     return 0;
848406f32e7eSjoerg   Module *Mod = static_cast<Module *>(CXMod);
848506f32e7eSjoerg   return Mod->IsSystem;
848606f32e7eSjoerg }
848706f32e7eSjoerg 
clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,CXModule CXMod)848806f32e7eSjoerg unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
848906f32e7eSjoerg                                             CXModule CXMod) {
849006f32e7eSjoerg   if (isNotUsableTU(TU)) {
849106f32e7eSjoerg     LOG_BAD_TU(TU);
849206f32e7eSjoerg     return 0;
849306f32e7eSjoerg   }
849406f32e7eSjoerg   if (!CXMod)
849506f32e7eSjoerg     return 0;
849606f32e7eSjoerg   Module *Mod = static_cast<Module *>(CXMod);
849706f32e7eSjoerg   FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
849806f32e7eSjoerg   ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
849906f32e7eSjoerg   return TopHeaders.size();
850006f32e7eSjoerg }
850106f32e7eSjoerg 
clang_Module_getTopLevelHeader(CXTranslationUnit TU,CXModule CXMod,unsigned Index)8502*13fbcb42Sjoerg CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8503*13fbcb42Sjoerg                                       unsigned Index) {
850406f32e7eSjoerg   if (isNotUsableTU(TU)) {
850506f32e7eSjoerg     LOG_BAD_TU(TU);
850606f32e7eSjoerg     return nullptr;
850706f32e7eSjoerg   }
850806f32e7eSjoerg   if (!CXMod)
850906f32e7eSjoerg     return nullptr;
851006f32e7eSjoerg   Module *Mod = static_cast<Module *>(CXMod);
851106f32e7eSjoerg   FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
851206f32e7eSjoerg 
851306f32e7eSjoerg   ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
851406f32e7eSjoerg   if (Index < TopHeaders.size())
851506f32e7eSjoerg     return const_cast<FileEntry *>(TopHeaders[Index]);
851606f32e7eSjoerg 
851706f32e7eSjoerg   return nullptr;
851806f32e7eSjoerg }
851906f32e7eSjoerg 
852006f32e7eSjoerg //===----------------------------------------------------------------------===//
852106f32e7eSjoerg // C++ AST instrospection.
852206f32e7eSjoerg //===----------------------------------------------------------------------===//
852306f32e7eSjoerg 
clang_CXXConstructor_isDefaultConstructor(CXCursor C)852406f32e7eSjoerg unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
852506f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
852606f32e7eSjoerg     return 0;
852706f32e7eSjoerg 
852806f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(C);
852906f32e7eSjoerg   const CXXConstructorDecl *Constructor =
853006f32e7eSjoerg       D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
853106f32e7eSjoerg   return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
853206f32e7eSjoerg }
853306f32e7eSjoerg 
clang_CXXConstructor_isCopyConstructor(CXCursor C)853406f32e7eSjoerg unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
853506f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
853606f32e7eSjoerg     return 0;
853706f32e7eSjoerg 
853806f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(C);
853906f32e7eSjoerg   const CXXConstructorDecl *Constructor =
854006f32e7eSjoerg       D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
854106f32e7eSjoerg   return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
854206f32e7eSjoerg }
854306f32e7eSjoerg 
clang_CXXConstructor_isMoveConstructor(CXCursor C)854406f32e7eSjoerg unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
854506f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
854606f32e7eSjoerg     return 0;
854706f32e7eSjoerg 
854806f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(C);
854906f32e7eSjoerg   const CXXConstructorDecl *Constructor =
855006f32e7eSjoerg       D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
855106f32e7eSjoerg   return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
855206f32e7eSjoerg }
855306f32e7eSjoerg 
clang_CXXConstructor_isConvertingConstructor(CXCursor C)855406f32e7eSjoerg unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
855506f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
855606f32e7eSjoerg     return 0;
855706f32e7eSjoerg 
855806f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(C);
855906f32e7eSjoerg   const CXXConstructorDecl *Constructor =
856006f32e7eSjoerg       D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
856106f32e7eSjoerg   // Passing 'false' excludes constructors marked 'explicit'.
856206f32e7eSjoerg   return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
856306f32e7eSjoerg }
856406f32e7eSjoerg 
clang_CXXField_isMutable(CXCursor C)856506f32e7eSjoerg unsigned clang_CXXField_isMutable(CXCursor C) {
856606f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
856706f32e7eSjoerg     return 0;
856806f32e7eSjoerg 
856906f32e7eSjoerg   if (const auto D = cxcursor::getCursorDecl(C))
857006f32e7eSjoerg     if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
857106f32e7eSjoerg       return FD->isMutable() ? 1 : 0;
857206f32e7eSjoerg   return 0;
857306f32e7eSjoerg }
857406f32e7eSjoerg 
clang_CXXMethod_isPureVirtual(CXCursor C)857506f32e7eSjoerg unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
857606f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
857706f32e7eSjoerg     return 0;
857806f32e7eSjoerg 
857906f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(C);
858006f32e7eSjoerg   const CXXMethodDecl *Method =
858106f32e7eSjoerg       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
858206f32e7eSjoerg   return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
858306f32e7eSjoerg }
858406f32e7eSjoerg 
clang_CXXMethod_isConst(CXCursor C)858506f32e7eSjoerg unsigned clang_CXXMethod_isConst(CXCursor C) {
858606f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
858706f32e7eSjoerg     return 0;
858806f32e7eSjoerg 
858906f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(C);
859006f32e7eSjoerg   const CXXMethodDecl *Method =
859106f32e7eSjoerg       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
859206f32e7eSjoerg   return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
859306f32e7eSjoerg }
859406f32e7eSjoerg 
clang_CXXMethod_isDefaulted(CXCursor C)859506f32e7eSjoerg unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
859606f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
859706f32e7eSjoerg     return 0;
859806f32e7eSjoerg 
859906f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(C);
860006f32e7eSjoerg   const CXXMethodDecl *Method =
860106f32e7eSjoerg       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
860206f32e7eSjoerg   return (Method && Method->isDefaulted()) ? 1 : 0;
860306f32e7eSjoerg }
860406f32e7eSjoerg 
clang_CXXMethod_isStatic(CXCursor C)860506f32e7eSjoerg unsigned clang_CXXMethod_isStatic(CXCursor C) {
860606f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
860706f32e7eSjoerg     return 0;
860806f32e7eSjoerg 
860906f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(C);
861006f32e7eSjoerg   const CXXMethodDecl *Method =
861106f32e7eSjoerg       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
861206f32e7eSjoerg   return (Method && Method->isStatic()) ? 1 : 0;
861306f32e7eSjoerg }
861406f32e7eSjoerg 
clang_CXXMethod_isVirtual(CXCursor C)861506f32e7eSjoerg unsigned clang_CXXMethod_isVirtual(CXCursor C) {
861606f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
861706f32e7eSjoerg     return 0;
861806f32e7eSjoerg 
861906f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(C);
862006f32e7eSjoerg   const CXXMethodDecl *Method =
862106f32e7eSjoerg       D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
862206f32e7eSjoerg   return (Method && Method->isVirtual()) ? 1 : 0;
862306f32e7eSjoerg }
862406f32e7eSjoerg 
clang_CXXRecord_isAbstract(CXCursor C)862506f32e7eSjoerg unsigned clang_CXXRecord_isAbstract(CXCursor C) {
862606f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
862706f32e7eSjoerg     return 0;
862806f32e7eSjoerg 
862906f32e7eSjoerg   const auto *D = cxcursor::getCursorDecl(C);
863006f32e7eSjoerg   const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
863106f32e7eSjoerg   if (RD)
863206f32e7eSjoerg     RD = RD->getDefinition();
863306f32e7eSjoerg   return (RD && RD->isAbstract()) ? 1 : 0;
863406f32e7eSjoerg }
863506f32e7eSjoerg 
clang_EnumDecl_isScoped(CXCursor C)863606f32e7eSjoerg unsigned clang_EnumDecl_isScoped(CXCursor C) {
863706f32e7eSjoerg   if (!clang_isDeclaration(C.kind))
863806f32e7eSjoerg     return 0;
863906f32e7eSjoerg 
864006f32e7eSjoerg   const Decl *D = cxcursor::getCursorDecl(C);
864106f32e7eSjoerg   auto *Enum = dyn_cast_or_null<EnumDecl>(D);
864206f32e7eSjoerg   return (Enum && Enum->isScoped()) ? 1 : 0;
864306f32e7eSjoerg }
864406f32e7eSjoerg 
864506f32e7eSjoerg //===----------------------------------------------------------------------===//
864606f32e7eSjoerg // Attribute introspection.
864706f32e7eSjoerg //===----------------------------------------------------------------------===//
864806f32e7eSjoerg 
clang_getIBOutletCollectionType(CXCursor C)864906f32e7eSjoerg CXType clang_getIBOutletCollectionType(CXCursor C) {
865006f32e7eSjoerg   if (C.kind != CXCursor_IBOutletCollectionAttr)
865106f32e7eSjoerg     return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
865206f32e7eSjoerg 
865306f32e7eSjoerg   const IBOutletCollectionAttr *A =
865406f32e7eSjoerg       cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
865506f32e7eSjoerg 
865606f32e7eSjoerg   return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
865706f32e7eSjoerg }
865806f32e7eSjoerg 
865906f32e7eSjoerg //===----------------------------------------------------------------------===//
866006f32e7eSjoerg // Inspecting memory usage.
866106f32e7eSjoerg //===----------------------------------------------------------------------===//
866206f32e7eSjoerg 
866306f32e7eSjoerg typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
866406f32e7eSjoerg 
createCXTUResourceUsageEntry(MemUsageEntries & entries,enum CXTUResourceUsageKind k,unsigned long amount)866506f32e7eSjoerg static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
866606f32e7eSjoerg                                                 enum CXTUResourceUsageKind k,
866706f32e7eSjoerg                                                 unsigned long amount) {
866806f32e7eSjoerg   CXTUResourceUsageEntry entry = {k, amount};
866906f32e7eSjoerg   entries.push_back(entry);
867006f32e7eSjoerg }
867106f32e7eSjoerg 
clang_getTUResourceUsageName(CXTUResourceUsageKind kind)867206f32e7eSjoerg const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
867306f32e7eSjoerg   const char *str = "";
867406f32e7eSjoerg   switch (kind) {
867506f32e7eSjoerg   case CXTUResourceUsage_AST:
867606f32e7eSjoerg     str = "ASTContext: expressions, declarations, and types";
867706f32e7eSjoerg     break;
867806f32e7eSjoerg   case CXTUResourceUsage_Identifiers:
867906f32e7eSjoerg     str = "ASTContext: identifiers";
868006f32e7eSjoerg     break;
868106f32e7eSjoerg   case CXTUResourceUsage_Selectors:
868206f32e7eSjoerg     str = "ASTContext: selectors";
868306f32e7eSjoerg     break;
868406f32e7eSjoerg   case CXTUResourceUsage_GlobalCompletionResults:
868506f32e7eSjoerg     str = "Code completion: cached global results";
868606f32e7eSjoerg     break;
868706f32e7eSjoerg   case CXTUResourceUsage_SourceManagerContentCache:
868806f32e7eSjoerg     str = "SourceManager: content cache allocator";
868906f32e7eSjoerg     break;
869006f32e7eSjoerg   case CXTUResourceUsage_AST_SideTables:
869106f32e7eSjoerg     str = "ASTContext: side tables";
869206f32e7eSjoerg     break;
869306f32e7eSjoerg   case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
869406f32e7eSjoerg     str = "SourceManager: malloc'ed memory buffers";
869506f32e7eSjoerg     break;
869606f32e7eSjoerg   case CXTUResourceUsage_SourceManager_Membuffer_MMap:
869706f32e7eSjoerg     str = "SourceManager: mmap'ed memory buffers";
869806f32e7eSjoerg     break;
869906f32e7eSjoerg   case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
870006f32e7eSjoerg     str = "ExternalASTSource: malloc'ed memory buffers";
870106f32e7eSjoerg     break;
870206f32e7eSjoerg   case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
870306f32e7eSjoerg     str = "ExternalASTSource: mmap'ed memory buffers";
870406f32e7eSjoerg     break;
870506f32e7eSjoerg   case CXTUResourceUsage_Preprocessor:
870606f32e7eSjoerg     str = "Preprocessor: malloc'ed memory";
870706f32e7eSjoerg     break;
870806f32e7eSjoerg   case CXTUResourceUsage_PreprocessingRecord:
870906f32e7eSjoerg     str = "Preprocessor: PreprocessingRecord";
871006f32e7eSjoerg     break;
871106f32e7eSjoerg   case CXTUResourceUsage_SourceManager_DataStructures:
871206f32e7eSjoerg     str = "SourceManager: data structures and tables";
871306f32e7eSjoerg     break;
871406f32e7eSjoerg   case CXTUResourceUsage_Preprocessor_HeaderSearch:
871506f32e7eSjoerg     str = "Preprocessor: header search tables";
871606f32e7eSjoerg     break;
871706f32e7eSjoerg   }
871806f32e7eSjoerg   return str;
871906f32e7eSjoerg }
872006f32e7eSjoerg 
clang_getCXTUResourceUsage(CXTranslationUnit TU)872106f32e7eSjoerg CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
872206f32e7eSjoerg   if (isNotUsableTU(TU)) {
872306f32e7eSjoerg     LOG_BAD_TU(TU);
872406f32e7eSjoerg     CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
872506f32e7eSjoerg     return usage;
872606f32e7eSjoerg   }
872706f32e7eSjoerg 
872806f32e7eSjoerg   ASTUnit *astUnit = cxtu::getASTUnit(TU);
872906f32e7eSjoerg   std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
873006f32e7eSjoerg   ASTContext &astContext = astUnit->getASTContext();
873106f32e7eSjoerg 
873206f32e7eSjoerg   // How much memory is used by AST nodes and types?
8733*13fbcb42Sjoerg   createCXTUResourceUsageEntry(
8734*13fbcb42Sjoerg       *entries, CXTUResourceUsage_AST,
873506f32e7eSjoerg       (unsigned long)astContext.getASTAllocatedMemory());
873606f32e7eSjoerg 
873706f32e7eSjoerg   // How much memory is used by identifiers?
8738*13fbcb42Sjoerg   createCXTUResourceUsageEntry(
8739*13fbcb42Sjoerg       *entries, CXTUResourceUsage_Identifiers,
874006f32e7eSjoerg       (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
874106f32e7eSjoerg 
874206f32e7eSjoerg   // How much memory is used for selectors?
8743*13fbcb42Sjoerg   createCXTUResourceUsageEntry(
8744*13fbcb42Sjoerg       *entries, CXTUResourceUsage_Selectors,
874506f32e7eSjoerg       (unsigned long)astContext.Selectors.getTotalMemory());
874606f32e7eSjoerg 
874706f32e7eSjoerg   // How much memory is used by ASTContext's side tables?
8748*13fbcb42Sjoerg   createCXTUResourceUsageEntry(
8749*13fbcb42Sjoerg       *entries, CXTUResourceUsage_AST_SideTables,
875006f32e7eSjoerg       (unsigned long)astContext.getSideTableAllocatedMemory());
875106f32e7eSjoerg 
875206f32e7eSjoerg   // How much memory is used for caching global code completion results?
875306f32e7eSjoerg   unsigned long completionBytes = 0;
875406f32e7eSjoerg   if (GlobalCodeCompletionAllocator *completionAllocator =
875506f32e7eSjoerg           astUnit->getCachedCompletionAllocator().get()) {
875606f32e7eSjoerg     completionBytes = completionAllocator->getTotalMemory();
875706f32e7eSjoerg   }
8758*13fbcb42Sjoerg   createCXTUResourceUsageEntry(
8759*13fbcb42Sjoerg       *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
876006f32e7eSjoerg 
876106f32e7eSjoerg   // How much memory is being used by SourceManager's content cache?
8762*13fbcb42Sjoerg   createCXTUResourceUsageEntry(
8763*13fbcb42Sjoerg       *entries, CXTUResourceUsage_SourceManagerContentCache,
876406f32e7eSjoerg       (unsigned long)astContext.getSourceManager().getContentCacheSize());
876506f32e7eSjoerg 
876606f32e7eSjoerg   // How much memory is being used by the MemoryBuffer's in SourceManager?
876706f32e7eSjoerg   const SourceManager::MemoryBufferSizes &srcBufs =
876806f32e7eSjoerg       astUnit->getSourceManager().getMemoryBufferSizes();
876906f32e7eSjoerg 
877006f32e7eSjoerg   createCXTUResourceUsageEntry(*entries,
877106f32e7eSjoerg                                CXTUResourceUsage_SourceManager_Membuffer_Malloc,
877206f32e7eSjoerg                                (unsigned long)srcBufs.malloc_bytes);
877306f32e7eSjoerg   createCXTUResourceUsageEntry(*entries,
877406f32e7eSjoerg                                CXTUResourceUsage_SourceManager_Membuffer_MMap,
877506f32e7eSjoerg                                (unsigned long)srcBufs.mmap_bytes);
8776*13fbcb42Sjoerg   createCXTUResourceUsageEntry(
8777*13fbcb42Sjoerg       *entries, CXTUResourceUsage_SourceManager_DataStructures,
8778*13fbcb42Sjoerg       (unsigned long)astContext.getSourceManager().getDataStructureSizes());
877906f32e7eSjoerg 
878006f32e7eSjoerg   // How much memory is being used by the ExternalASTSource?
878106f32e7eSjoerg   if (ExternalASTSource *esrc = astContext.getExternalSource()) {
878206f32e7eSjoerg     const ExternalASTSource::MemoryBufferSizes &sizes =
878306f32e7eSjoerg         esrc->getMemoryBufferSizes();
878406f32e7eSjoerg 
8785*13fbcb42Sjoerg     createCXTUResourceUsageEntry(
8786*13fbcb42Sjoerg         *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
878706f32e7eSjoerg         (unsigned long)sizes.malloc_bytes);
8788*13fbcb42Sjoerg     createCXTUResourceUsageEntry(
8789*13fbcb42Sjoerg         *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
879006f32e7eSjoerg         (unsigned long)sizes.mmap_bytes);
879106f32e7eSjoerg   }
879206f32e7eSjoerg 
879306f32e7eSjoerg   // How much memory is being used by the Preprocessor?
879406f32e7eSjoerg   Preprocessor &pp = astUnit->getPreprocessor();
8795*13fbcb42Sjoerg   createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
879606f32e7eSjoerg                                pp.getTotalMemory());
879706f32e7eSjoerg 
879806f32e7eSjoerg   if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
879906f32e7eSjoerg     createCXTUResourceUsageEntry(*entries,
880006f32e7eSjoerg                                  CXTUResourceUsage_PreprocessingRecord,
880106f32e7eSjoerg                                  pRec->getTotalMemory());
880206f32e7eSjoerg   }
880306f32e7eSjoerg 
880406f32e7eSjoerg   createCXTUResourceUsageEntry(*entries,
880506f32e7eSjoerg                                CXTUResourceUsage_Preprocessor_HeaderSearch,
880606f32e7eSjoerg                                pp.getHeaderSearchInfo().getTotalMemory());
880706f32e7eSjoerg 
8808*13fbcb42Sjoerg   CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
880906f32e7eSjoerg                              !entries->empty() ? &(*entries)[0] : nullptr};
881006f32e7eSjoerg   (void)entries.release();
881106f32e7eSjoerg   return usage;
881206f32e7eSjoerg }
881306f32e7eSjoerg 
clang_disposeCXTUResourceUsage(CXTUResourceUsage usage)881406f32e7eSjoerg void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
881506f32e7eSjoerg   if (usage.data)
881606f32e7eSjoerg     delete (MemUsageEntries *)usage.data;
881706f32e7eSjoerg }
881806f32e7eSjoerg 
clang_getSkippedRanges(CXTranslationUnit TU,CXFile file)881906f32e7eSjoerg CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
882006f32e7eSjoerg   CXSourceRangeList *skipped = new CXSourceRangeList;
882106f32e7eSjoerg   skipped->count = 0;
882206f32e7eSjoerg   skipped->ranges = nullptr;
882306f32e7eSjoerg 
882406f32e7eSjoerg   if (isNotUsableTU(TU)) {
882506f32e7eSjoerg     LOG_BAD_TU(TU);
882606f32e7eSjoerg     return skipped;
882706f32e7eSjoerg   }
882806f32e7eSjoerg 
882906f32e7eSjoerg   if (!file)
883006f32e7eSjoerg     return skipped;
883106f32e7eSjoerg 
883206f32e7eSjoerg   ASTUnit *astUnit = cxtu::getASTUnit(TU);
8833*13fbcb42Sjoerg   PreprocessingRecord *ppRec =
8834*13fbcb42Sjoerg       astUnit->getPreprocessor().getPreprocessingRecord();
883506f32e7eSjoerg   if (!ppRec)
883606f32e7eSjoerg     return skipped;
883706f32e7eSjoerg 
883806f32e7eSjoerg   ASTContext &Ctx = astUnit->getASTContext();
883906f32e7eSjoerg   SourceManager &sm = Ctx.getSourceManager();
884006f32e7eSjoerg   FileEntry *fileEntry = static_cast<FileEntry *>(file);
884106f32e7eSjoerg   FileID wantedFileID = sm.translateFile(fileEntry);
884206f32e7eSjoerg   bool isMainFile = wantedFileID == sm.getMainFileID();
884306f32e7eSjoerg 
884406f32e7eSjoerg   const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
884506f32e7eSjoerg   std::vector<SourceRange> wantedRanges;
8846*13fbcb42Sjoerg   for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8847*13fbcb42Sjoerg                                                 ei = SkippedRanges.end();
884806f32e7eSjoerg        i != ei; ++i) {
8849*13fbcb42Sjoerg     if (sm.getFileID(i->getBegin()) == wantedFileID ||
8850*13fbcb42Sjoerg         sm.getFileID(i->getEnd()) == wantedFileID)
885106f32e7eSjoerg       wantedRanges.push_back(*i);
8852*13fbcb42Sjoerg     else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8853*13fbcb42Sjoerg                             astUnit->isInPreambleFileID(i->getEnd())))
885406f32e7eSjoerg       wantedRanges.push_back(*i);
885506f32e7eSjoerg   }
885606f32e7eSjoerg 
885706f32e7eSjoerg   skipped->count = wantedRanges.size();
885806f32e7eSjoerg   skipped->ranges = new CXSourceRange[skipped->count];
885906f32e7eSjoerg   for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
886006f32e7eSjoerg     skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
886106f32e7eSjoerg 
886206f32e7eSjoerg   return skipped;
886306f32e7eSjoerg }
886406f32e7eSjoerg 
clang_getAllSkippedRanges(CXTranslationUnit TU)886506f32e7eSjoerg CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
886606f32e7eSjoerg   CXSourceRangeList *skipped = new CXSourceRangeList;
886706f32e7eSjoerg   skipped->count = 0;
886806f32e7eSjoerg   skipped->ranges = nullptr;
886906f32e7eSjoerg 
887006f32e7eSjoerg   if (isNotUsableTU(TU)) {
887106f32e7eSjoerg     LOG_BAD_TU(TU);
887206f32e7eSjoerg     return skipped;
887306f32e7eSjoerg   }
887406f32e7eSjoerg 
887506f32e7eSjoerg   ASTUnit *astUnit = cxtu::getASTUnit(TU);
8876*13fbcb42Sjoerg   PreprocessingRecord *ppRec =
8877*13fbcb42Sjoerg       astUnit->getPreprocessor().getPreprocessingRecord();
887806f32e7eSjoerg   if (!ppRec)
887906f32e7eSjoerg     return skipped;
888006f32e7eSjoerg 
888106f32e7eSjoerg   ASTContext &Ctx = astUnit->getASTContext();
888206f32e7eSjoerg 
888306f32e7eSjoerg   const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
888406f32e7eSjoerg 
888506f32e7eSjoerg   skipped->count = SkippedRanges.size();
888606f32e7eSjoerg   skipped->ranges = new CXSourceRange[skipped->count];
888706f32e7eSjoerg   for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
888806f32e7eSjoerg     skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
888906f32e7eSjoerg 
889006f32e7eSjoerg   return skipped;
889106f32e7eSjoerg }
889206f32e7eSjoerg 
clang_disposeSourceRangeList(CXSourceRangeList * ranges)889306f32e7eSjoerg void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
889406f32e7eSjoerg   if (ranges) {
889506f32e7eSjoerg     delete[] ranges->ranges;
889606f32e7eSjoerg     delete ranges;
889706f32e7eSjoerg   }
889806f32e7eSjoerg }
889906f32e7eSjoerg 
PrintLibclangResourceUsage(CXTranslationUnit TU)890006f32e7eSjoerg void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
890106f32e7eSjoerg   CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
890206f32e7eSjoerg   for (unsigned I = 0; I != Usage.numEntries; ++I)
890306f32e7eSjoerg     fprintf(stderr, "  %s: %lu\n",
890406f32e7eSjoerg             clang_getTUResourceUsageName(Usage.entries[I].kind),
890506f32e7eSjoerg             Usage.entries[I].amount);
890606f32e7eSjoerg 
890706f32e7eSjoerg   clang_disposeCXTUResourceUsage(Usage);
890806f32e7eSjoerg }
890906f32e7eSjoerg 
clang_Cursor_getVarDeclInitializer(CXCursor cursor)8910*13fbcb42Sjoerg CXCursor clang_Cursor_getVarDeclInitializer(CXCursor cursor) {
8911*13fbcb42Sjoerg   const Decl *const D = getCursorDecl(cursor);
8912*13fbcb42Sjoerg   if (!D)
8913*13fbcb42Sjoerg     return clang_getNullCursor();
8914*13fbcb42Sjoerg   const auto *const VD = dyn_cast<VarDecl>(D);
8915*13fbcb42Sjoerg   if (!VD)
8916*13fbcb42Sjoerg     return clang_getNullCursor();
8917*13fbcb42Sjoerg   const Expr *const Init = VD->getInit();
8918*13fbcb42Sjoerg   if (!Init)
8919*13fbcb42Sjoerg     return clang_getNullCursor();
8920*13fbcb42Sjoerg 
8921*13fbcb42Sjoerg   return cxcursor::MakeCXCursor(Init, VD, cxcursor::getCursorTU(cursor));
8922*13fbcb42Sjoerg }
8923*13fbcb42Sjoerg 
clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor)8924*13fbcb42Sjoerg int clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor) {
8925*13fbcb42Sjoerg   const Decl *const D = getCursorDecl(cursor);
8926*13fbcb42Sjoerg   if (!D)
8927*13fbcb42Sjoerg     return -1;
8928*13fbcb42Sjoerg   const auto *const VD = dyn_cast<VarDecl>(D);
8929*13fbcb42Sjoerg   if (!VD)
8930*13fbcb42Sjoerg     return -1;
8931*13fbcb42Sjoerg 
8932*13fbcb42Sjoerg   return VD->hasGlobalStorage();
8933*13fbcb42Sjoerg }
8934*13fbcb42Sjoerg 
clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor)8935*13fbcb42Sjoerg int clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor) {
8936*13fbcb42Sjoerg   const Decl *const D = getCursorDecl(cursor);
8937*13fbcb42Sjoerg   if (!D)
8938*13fbcb42Sjoerg     return -1;
8939*13fbcb42Sjoerg   const auto *const VD = dyn_cast<VarDecl>(D);
8940*13fbcb42Sjoerg   if (!VD)
8941*13fbcb42Sjoerg     return -1;
8942*13fbcb42Sjoerg 
8943*13fbcb42Sjoerg   return VD->hasExternalStorage();
8944*13fbcb42Sjoerg }
8945*13fbcb42Sjoerg 
894606f32e7eSjoerg //===----------------------------------------------------------------------===//
894706f32e7eSjoerg // Misc. utility functions.
894806f32e7eSjoerg //===----------------------------------------------------------------------===//
894906f32e7eSjoerg 
895006f32e7eSjoerg /// Default to using our desired 8 MB stack size on "safety" threads.
895106f32e7eSjoerg static unsigned SafetyStackThreadSize = DesiredStackSize;
895206f32e7eSjoerg 
895306f32e7eSjoerg namespace clang {
895406f32e7eSjoerg 
RunSafely(llvm::CrashRecoveryContext & CRC,llvm::function_ref<void ()> Fn,unsigned Size)895506f32e7eSjoerg bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
895606f32e7eSjoerg                unsigned Size) {
895706f32e7eSjoerg   if (!Size)
895806f32e7eSjoerg     Size = GetSafetyThreadStackSize();
895906f32e7eSjoerg   if (Size && !getenv("LIBCLANG_NOTHREADS"))
896006f32e7eSjoerg     return CRC.RunSafelyOnThread(Fn, Size);
896106f32e7eSjoerg   return CRC.RunSafely(Fn);
896206f32e7eSjoerg }
896306f32e7eSjoerg 
GetSafetyThreadStackSize()8964*13fbcb42Sjoerg unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
896506f32e7eSjoerg 
SetSafetyThreadStackSize(unsigned Value)8966*13fbcb42Sjoerg void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
896706f32e7eSjoerg 
8968*13fbcb42Sjoerg } // namespace clang
896906f32e7eSjoerg 
setThreadBackgroundPriority()897006f32e7eSjoerg void clang::setThreadBackgroundPriority() {
897106f32e7eSjoerg   if (getenv("LIBCLANG_BGPRIO_DISABLE"))
897206f32e7eSjoerg     return;
897306f32e7eSjoerg 
897406f32e7eSjoerg #if LLVM_ENABLE_THREADS
897506f32e7eSjoerg   llvm::set_thread_priority(llvm::ThreadPriority::Background);
897606f32e7eSjoerg #endif
897706f32e7eSjoerg }
897806f32e7eSjoerg 
printDiagsToStderr(ASTUnit * Unit)897906f32e7eSjoerg void cxindex::printDiagsToStderr(ASTUnit *Unit) {
898006f32e7eSjoerg   if (!Unit)
898106f32e7eSjoerg     return;
898206f32e7eSjoerg 
898306f32e7eSjoerg   for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
898406f32e7eSjoerg                                      DEnd = Unit->stored_diag_end();
898506f32e7eSjoerg        D != DEnd; ++D) {
898606f32e7eSjoerg     CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
8987*13fbcb42Sjoerg     CXString Msg =
8988*13fbcb42Sjoerg         clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
898906f32e7eSjoerg     fprintf(stderr, "%s\n", clang_getCString(Msg));
899006f32e7eSjoerg     clang_disposeString(Msg);
899106f32e7eSjoerg   }
899206f32e7eSjoerg #ifdef _WIN32
899306f32e7eSjoerg   // On Windows, force a flush, since there may be multiple copies of
899406f32e7eSjoerg   // stderr and stdout in the file system, all with different buffers
899506f32e7eSjoerg   // but writing to the same device.
899606f32e7eSjoerg   fflush(stderr);
899706f32e7eSjoerg #endif
899806f32e7eSjoerg }
899906f32e7eSjoerg 
getMacroInfo(const IdentifierInfo & II,SourceLocation MacroDefLoc,CXTranslationUnit TU)900006f32e7eSjoerg MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
900106f32e7eSjoerg                                  SourceLocation MacroDefLoc,
900206f32e7eSjoerg                                  CXTranslationUnit TU) {
900306f32e7eSjoerg   if (MacroDefLoc.isInvalid() || !TU)
900406f32e7eSjoerg     return nullptr;
900506f32e7eSjoerg   if (!II.hadMacroDefinition())
900606f32e7eSjoerg     return nullptr;
900706f32e7eSjoerg 
900806f32e7eSjoerg   ASTUnit *Unit = cxtu::getASTUnit(TU);
900906f32e7eSjoerg   Preprocessor &PP = Unit->getPreprocessor();
901006f32e7eSjoerg   MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
901106f32e7eSjoerg   if (MD) {
9012*13fbcb42Sjoerg     for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
9013*13fbcb42Sjoerg          Def = Def.getPreviousDefinition()) {
901406f32e7eSjoerg       if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
901506f32e7eSjoerg         return Def.getMacroInfo();
901606f32e7eSjoerg     }
901706f32e7eSjoerg   }
901806f32e7eSjoerg 
901906f32e7eSjoerg   return nullptr;
902006f32e7eSjoerg }
902106f32e7eSjoerg 
getMacroInfo(const MacroDefinitionRecord * MacroDef,CXTranslationUnit TU)902206f32e7eSjoerg const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
902306f32e7eSjoerg                                        CXTranslationUnit TU) {
902406f32e7eSjoerg   if (!MacroDef || !TU)
902506f32e7eSjoerg     return nullptr;
902606f32e7eSjoerg   const IdentifierInfo *II = MacroDef->getName();
902706f32e7eSjoerg   if (!II)
902806f32e7eSjoerg     return nullptr;
902906f32e7eSjoerg 
903006f32e7eSjoerg   return getMacroInfo(*II, MacroDef->getLocation(), TU);
903106f32e7eSjoerg }
903206f32e7eSjoerg 
903306f32e7eSjoerg MacroDefinitionRecord *
checkForMacroInMacroDefinition(const MacroInfo * MI,const Token & Tok,CXTranslationUnit TU)903406f32e7eSjoerg cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
903506f32e7eSjoerg                                         CXTranslationUnit TU) {
903606f32e7eSjoerg   if (!MI || !TU)
903706f32e7eSjoerg     return nullptr;
903806f32e7eSjoerg   if (Tok.isNot(tok::raw_identifier))
903906f32e7eSjoerg     return nullptr;
904006f32e7eSjoerg 
904106f32e7eSjoerg   if (MI->getNumTokens() == 0)
904206f32e7eSjoerg     return nullptr;
904306f32e7eSjoerg   SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
904406f32e7eSjoerg                        MI->getDefinitionEndLoc());
904506f32e7eSjoerg   ASTUnit *Unit = cxtu::getASTUnit(TU);
904606f32e7eSjoerg 
904706f32e7eSjoerg   // Check that the token is inside the definition and not its argument list.
904806f32e7eSjoerg   SourceManager &SM = Unit->getSourceManager();
904906f32e7eSjoerg   if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
905006f32e7eSjoerg     return nullptr;
905106f32e7eSjoerg   if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
905206f32e7eSjoerg     return nullptr;
905306f32e7eSjoerg 
905406f32e7eSjoerg   Preprocessor &PP = Unit->getPreprocessor();
905506f32e7eSjoerg   PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
905606f32e7eSjoerg   if (!PPRec)
905706f32e7eSjoerg     return nullptr;
905806f32e7eSjoerg 
905906f32e7eSjoerg   IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
906006f32e7eSjoerg   if (!II.hadMacroDefinition())
906106f32e7eSjoerg     return nullptr;
906206f32e7eSjoerg 
906306f32e7eSjoerg   // Check that the identifier is not one of the macro arguments.
906406f32e7eSjoerg   if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
906506f32e7eSjoerg     return nullptr;
906606f32e7eSjoerg 
906706f32e7eSjoerg   MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
906806f32e7eSjoerg   if (!InnerMD)
906906f32e7eSjoerg     return nullptr;
907006f32e7eSjoerg 
907106f32e7eSjoerg   return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
907206f32e7eSjoerg }
907306f32e7eSjoerg 
907406f32e7eSjoerg MacroDefinitionRecord *
checkForMacroInMacroDefinition(const MacroInfo * MI,SourceLocation Loc,CXTranslationUnit TU)907506f32e7eSjoerg cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
907606f32e7eSjoerg                                         CXTranslationUnit TU) {
907706f32e7eSjoerg   if (Loc.isInvalid() || !MI || !TU)
907806f32e7eSjoerg     return nullptr;
907906f32e7eSjoerg 
908006f32e7eSjoerg   if (MI->getNumTokens() == 0)
908106f32e7eSjoerg     return nullptr;
908206f32e7eSjoerg   ASTUnit *Unit = cxtu::getASTUnit(TU);
908306f32e7eSjoerg   Preprocessor &PP = Unit->getPreprocessor();
908406f32e7eSjoerg   if (!PP.getPreprocessingRecord())
908506f32e7eSjoerg     return nullptr;
908606f32e7eSjoerg   Loc = Unit->getSourceManager().getSpellingLoc(Loc);
908706f32e7eSjoerg   Token Tok;
908806f32e7eSjoerg   if (PP.getRawToken(Loc, Tok))
908906f32e7eSjoerg     return nullptr;
909006f32e7eSjoerg 
909106f32e7eSjoerg   return checkForMacroInMacroDefinition(MI, Tok, TU);
909206f32e7eSjoerg }
909306f32e7eSjoerg 
clang_getClangVersion()909406f32e7eSjoerg CXString clang_getClangVersion() {
909506f32e7eSjoerg   return cxstring::createDup(getClangFullVersion());
909606f32e7eSjoerg }
909706f32e7eSjoerg 
operator <<(CXTranslationUnit TU)909806f32e7eSjoerg Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
909906f32e7eSjoerg   if (TU) {
910006f32e7eSjoerg     if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
910106f32e7eSjoerg       LogOS << '<' << Unit->getMainFileName() << '>';
910206f32e7eSjoerg       if (Unit->isMainFileAST())
910306f32e7eSjoerg         LogOS << " (" << Unit->getASTFileName() << ')';
910406f32e7eSjoerg       return *this;
910506f32e7eSjoerg     }
910606f32e7eSjoerg   } else {
910706f32e7eSjoerg     LogOS << "<NULL TU>";
910806f32e7eSjoerg   }
910906f32e7eSjoerg   return *this;
911006f32e7eSjoerg }
911106f32e7eSjoerg 
operator <<(const FileEntry * FE)911206f32e7eSjoerg Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
911306f32e7eSjoerg   *this << FE->getName();
911406f32e7eSjoerg   return *this;
911506f32e7eSjoerg }
911606f32e7eSjoerg 
operator <<(CXCursor cursor)911706f32e7eSjoerg Logger &cxindex::Logger::operator<<(CXCursor cursor) {
911806f32e7eSjoerg   CXString cursorName = clang_getCursorDisplayName(cursor);
911906f32e7eSjoerg   *this << cursorName << "@" << clang_getCursorLocation(cursor);
912006f32e7eSjoerg   clang_disposeString(cursorName);
912106f32e7eSjoerg   return *this;
912206f32e7eSjoerg }
912306f32e7eSjoerg 
operator <<(CXSourceLocation Loc)912406f32e7eSjoerg Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
912506f32e7eSjoerg   CXFile File;
912606f32e7eSjoerg   unsigned Line, Column;
912706f32e7eSjoerg   clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
912806f32e7eSjoerg   CXString FileName = clang_getFileName(File);
912906f32e7eSjoerg   *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
913006f32e7eSjoerg   clang_disposeString(FileName);
913106f32e7eSjoerg   return *this;
913206f32e7eSjoerg }
913306f32e7eSjoerg 
operator <<(CXSourceRange range)913406f32e7eSjoerg Logger &cxindex::Logger::operator<<(CXSourceRange range) {
913506f32e7eSjoerg   CXSourceLocation BLoc = clang_getRangeStart(range);
913606f32e7eSjoerg   CXSourceLocation ELoc = clang_getRangeEnd(range);
913706f32e7eSjoerg 
913806f32e7eSjoerg   CXFile BFile;
913906f32e7eSjoerg   unsigned BLine, BColumn;
914006f32e7eSjoerg   clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
914106f32e7eSjoerg 
914206f32e7eSjoerg   CXFile EFile;
914306f32e7eSjoerg   unsigned ELine, EColumn;
914406f32e7eSjoerg   clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
914506f32e7eSjoerg 
914606f32e7eSjoerg   CXString BFileName = clang_getFileName(BFile);
914706f32e7eSjoerg   if (BFile == EFile) {
914806f32e7eSjoerg     *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
914906f32e7eSjoerg                           BLine, BColumn, ELine, EColumn);
915006f32e7eSjoerg   } else {
915106f32e7eSjoerg     CXString EFileName = clang_getFileName(EFile);
9152*13fbcb42Sjoerg     *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9153*13fbcb42Sjoerg                           BColumn)
9154*13fbcb42Sjoerg           << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9155*13fbcb42Sjoerg                           EColumn);
915606f32e7eSjoerg     clang_disposeString(EFileName);
915706f32e7eSjoerg   }
915806f32e7eSjoerg   clang_disposeString(BFileName);
915906f32e7eSjoerg   return *this;
916006f32e7eSjoerg }
916106f32e7eSjoerg 
operator <<(CXString Str)916206f32e7eSjoerg Logger &cxindex::Logger::operator<<(CXString Str) {
916306f32e7eSjoerg   *this << clang_getCString(Str);
916406f32e7eSjoerg   return *this;
916506f32e7eSjoerg }
916606f32e7eSjoerg 
operator <<(const llvm::format_object_base & Fmt)916706f32e7eSjoerg Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
916806f32e7eSjoerg   LogOS << Fmt;
916906f32e7eSjoerg   return *this;
917006f32e7eSjoerg }
917106f32e7eSjoerg 
917206f32e7eSjoerg static llvm::ManagedStatic<std::mutex> LoggingMutex;
917306f32e7eSjoerg 
~Logger()917406f32e7eSjoerg cxindex::Logger::~Logger() {
917506f32e7eSjoerg   std::lock_guard<std::mutex> L(*LoggingMutex);
917606f32e7eSjoerg 
917706f32e7eSjoerg   static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
917806f32e7eSjoerg 
917906f32e7eSjoerg   raw_ostream &OS = llvm::errs();
918006f32e7eSjoerg   OS << "[libclang:" << Name << ':';
918106f32e7eSjoerg 
918206f32e7eSjoerg #ifdef USE_DARWIN_THREADS
918306f32e7eSjoerg   // TODO: Portability.
918406f32e7eSjoerg   mach_port_t tid = pthread_mach_thread_np(pthread_self());
918506f32e7eSjoerg   OS << tid << ':';
918606f32e7eSjoerg #endif
918706f32e7eSjoerg 
918806f32e7eSjoerg   llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
918906f32e7eSjoerg   OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
919006f32e7eSjoerg   OS << Msg << '\n';
919106f32e7eSjoerg 
919206f32e7eSjoerg   if (Trace) {
919306f32e7eSjoerg     llvm::sys::PrintStackTrace(OS);
919406f32e7eSjoerg     OS << "--------------------------------------------------\n";
919506f32e7eSjoerg   }
919606f32e7eSjoerg }
9197