brintos

brintos / llvm-project-archived public Read only

0
0
Text · 340.4 KiB · 32e8424 Raw
10207 lines · cpp
1//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the main API hooks in the Clang-C Source Indexing10// library.11//12//===----------------------------------------------------------------------===//13 14#include "CIndexDiagnostic.h"15#include "CIndexer.h"16#include "CLog.h"17#include "CXCursor.h"18#include "CXFile.h"19#include "CXSourceLocation.h"20#include "CXString.h"21#include "CXTranslationUnit.h"22#include "CXType.h"23#include "CursorVisitor.h"24#include "clang-c/FatalErrorHandler.h"25#include "clang/AST/Attr.h"26#include "clang/AST/AttrVisitor.h"27#include "clang/AST/DeclObjCCommon.h"28#include "clang/AST/Expr.h"29#include "clang/AST/ExprCXX.h"30#include "clang/AST/Mangle.h"31#include "clang/AST/OpenACCClause.h"32#include "clang/AST/OpenMPClause.h"33#include "clang/AST/OperationKinds.h"34#include "clang/AST/StmtVisitor.h"35#include "clang/Basic/Diagnostic.h"36#include "clang/Basic/DiagnosticCategories.h"37#include "clang/Basic/DiagnosticIDs.h"38#include "clang/Basic/Stack.h"39#include "clang/Basic/TargetInfo.h"40#include "clang/Basic/Version.h"41#include "clang/Driver/CreateASTUnitFromArgs.h"42#include "clang/Frontend/ASTUnit.h"43#include "clang/Frontend/CompilerInstance.h"44#include "clang/Index/CommentToXML.h"45#include "clang/Lex/HeaderSearch.h"46#include "clang/Lex/Lexer.h"47#include "clang/Lex/PreprocessingRecord.h"48#include "clang/Lex/Preprocessor.h"49#include "llvm/ADT/STLExtras.h"50#include "llvm/ADT/StringSwitch.h"51#include "llvm/Config/llvm-config.h"52#include "llvm/Support/Compiler.h"53#include "llvm/Support/CrashRecoveryContext.h"54#include "llvm/Support/Format.h"55#include "llvm/Support/ManagedStatic.h"56#include "llvm/Support/MemoryBuffer.h"57#include "llvm/Support/Program.h"58#include "llvm/Support/SaveAndRestore.h"59#include "llvm/Support/Signals.h"60#include "llvm/Support/TargetSelect.h"61#include "llvm/Support/Threading.h"62#include "llvm/Support/Timer.h"63#include "llvm/Support/VirtualFileSystem.h"64#include "llvm/Support/raw_ostream.h"65#include "llvm/Support/thread.h"66#include <mutex>67#include <optional>68 69#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)70#define USE_DARWIN_THREADS71#endif72 73#ifdef USE_DARWIN_THREADS74#include <pthread.h>75#endif76 77using namespace clang;78using namespace clang::cxcursor;79using namespace clang::cxtu;80using namespace clang::cxindex;81 82CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,83                                              std::unique_ptr<ASTUnit> AU) {84  if (!AU)85    return nullptr;86  assert(CIdx);87  CXTranslationUnit D = new CXTranslationUnitImpl();88  D->CIdx = CIdx;89  D->TheASTUnit = AU.release();90  D->StringPool = new cxstring::CXStringPool();91  D->Diagnostics = nullptr;92  D->OverridenCursorsPool = createOverridenCXCursorsPool();93  D->CommentToXML = nullptr;94  D->ParsingOptions = 0;95  D->Arguments = {};96  return D;97}98 99bool cxtu::isASTReadError(ASTUnit *AU) {100  for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),101                                     DEnd = AU->stored_diag_end();102       D != DEnd; ++D) {103    if (D->getLevel() >= DiagnosticsEngine::Error &&104        DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==105            diag::DiagCat_AST_Deserialization_Issue)106      return true;107  }108  return false;109}110 111cxtu::CXTUOwner::~CXTUOwner() {112  if (TU)113    clang_disposeTranslationUnit(TU);114}115 116/// Compare two source ranges to determine their relative position in117/// the translation unit.118static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1,119                                          SourceRange R2) {120  assert(R1.isValid() && "First range is invalid?");121  assert(R2.isValid() && "Second range is invalid?");122  if (R1.getEnd() != R2.getBegin() &&123      SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))124    return RangeBefore;125  if (R2.getEnd() != R1.getBegin() &&126      SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))127    return RangeAfter;128  return RangeOverlap;129}130 131/// Determine if a source location falls within, before, or after a132///   a given source range.133static RangeComparisonResult LocationCompare(SourceManager &SM,134                                             SourceLocation L, SourceRange R) {135  assert(R.isValid() && "First range is invalid?");136  assert(L.isValid() && "Second range is invalid?");137  if (L == R.getBegin() || L == R.getEnd())138    return RangeOverlap;139  if (SM.isBeforeInTranslationUnit(L, R.getBegin()))140    return RangeBefore;141  if (SM.isBeforeInTranslationUnit(R.getEnd(), L))142    return RangeAfter;143  return RangeOverlap;144}145 146/// Translate a Clang source range into a CIndex source range.147///148/// Clang internally represents ranges where the end location points to the149/// start of the token at the end. However, for external clients it is more150/// useful to have a CXSourceRange be a proper half-open interval. This routine151/// does the appropriate translation.152CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,153                                          const LangOptions &LangOpts,154                                          const CharSourceRange &R) {155  // We want the last character in this location, so we will adjust the156  // location accordingly.157  SourceLocation EndLoc = R.getEnd();158  bool IsTokenRange = R.isTokenRange();159  if (EndLoc.isValid() && EndLoc.isMacroID() &&160      !SM.isMacroArgExpansion(EndLoc)) {161    CharSourceRange Expansion = SM.getExpansionRange(EndLoc);162    EndLoc = Expansion.getEnd();163    IsTokenRange = Expansion.isTokenRange();164  }165  if (IsTokenRange && EndLoc.isValid()) {166    unsigned Length =167        Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);168    EndLoc = EndLoc.getLocWithOffset(Length);169  }170 171  CXSourceRange Result = {172      {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};173  return Result;174}175 176CharSourceRange cxloc::translateCXRangeToCharRange(CXSourceRange R) {177  return CharSourceRange::getCharRange(178      SourceLocation::getFromRawEncoding(R.begin_int_data),179      SourceLocation::getFromRawEncoding(R.end_int_data));180}181 182//===----------------------------------------------------------------------===//183// Cursor visitor.184//===----------------------------------------------------------------------===//185 186static SourceRange getRawCursorExtent(CXCursor C);187static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);188 189RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {190  return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);191}192 193/// Visit the given cursor and, if requested by the visitor,194/// its children.195///196/// \param Cursor the cursor to visit.197///198/// \param CheckedRegionOfInterest if true, then the caller already checked199/// that this cursor is within the region of interest.200///201/// \returns true if the visitation should be aborted, false if it202/// should continue.203bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {204  if (clang_isInvalid(Cursor.kind))205    return false;206 207  if (clang_isDeclaration(Cursor.kind)) {208    const Decl *D = getCursorDecl(Cursor);209    if (!D) {210      assert(0 && "Invalid declaration cursor");211      return true; // abort.212    }213 214    // Ignore implicit declarations, unless it's an objc method because215    // currently we should report implicit methods for properties when indexing.216    if (D->isImplicit() && !isa<ObjCMethodDecl>(D))217      return false;218  }219 220  // If we have a range of interest, and this cursor doesn't intersect with it,221  // we're done.222  if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {223    SourceRange Range = getRawCursorExtent(Cursor);224    if (Range.isInvalid() || CompareRegionOfInterest(Range))225      return false;226  }227 228  switch (Visitor(Cursor, Parent, ClientData)) {229  case CXChildVisit_Break:230    return true;231 232  case CXChildVisit_Continue:233    return false;234 235  case CXChildVisit_Recurse: {236    bool ret = VisitChildren(Cursor);237    if (PostChildrenVisitor)238      if (PostChildrenVisitor(Cursor, ClientData))239        return true;240    return ret;241  }242  }243 244  llvm_unreachable("Invalid CXChildVisitResult!");245}246 247static bool visitPreprocessedEntitiesInRange(SourceRange R,248                                             PreprocessingRecord &PPRec,249                                             CursorVisitor &Visitor) {250  SourceManager &SM = Visitor.getASTUnit()->getSourceManager();251  FileID FID;252 253  if (!Visitor.shouldVisitIncludedEntities()) {254    // If the begin/end of the range lie in the same FileID, do the optimization255    // where we skip preprocessed entities that do not come from the same256    // FileID.257    FID = SM.getFileID(SM.getFileLoc(R.getBegin()));258    if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))259      FID = FileID();260  }261 262  const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);263  return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),264                                           PPRec, FID);265}266 267bool CursorVisitor::visitFileRegion() {268  if (RegionOfInterest.isInvalid())269    return false;270 271  ASTUnit *Unit = cxtu::getASTUnit(TU);272  SourceManager &SM = Unit->getSourceManager();273 274  FileIDAndOffset Begin = SM.getDecomposedLoc(275                      SM.getFileLoc(RegionOfInterest.getBegin())),276                  End = SM.getDecomposedLoc(277                      SM.getFileLoc(RegionOfInterest.getEnd()));278 279  if (End.first != Begin.first) {280    // If the end does not reside in the same file, try to recover by281    // picking the end of the file of begin location.282    End.first = Begin.first;283    End.second = SM.getFileIDSize(Begin.first);284  }285 286  assert(Begin.first == End.first);287  if (Begin.second > End.second)288    return false;289 290  FileID File = Begin.first;291  unsigned Offset = Begin.second;292  unsigned Length = End.second - Begin.second;293 294  if (!VisitDeclsOnly && !VisitPreprocessorLast)295    if (visitPreprocessedEntitiesInRegion())296      return true; // visitation break.297 298  if (visitDeclsFromFileRegion(File, Offset, Length))299    return true; // visitation break.300 301  if (!VisitDeclsOnly && VisitPreprocessorLast)302    return visitPreprocessedEntitiesInRegion();303 304  return false;305}306 307static bool isInLexicalContext(Decl *D, DeclContext *DC) {308  if (!DC)309    return false;310 311  for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;312       DeclDC = DeclDC->getLexicalParent()) {313    if (DeclDC == DC)314      return true;315  }316  return false;317}318 319bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,320                                             unsigned Length) {321  ASTUnit *Unit = cxtu::getASTUnit(TU);322  SourceManager &SM = Unit->getSourceManager();323  SourceRange Range = RegionOfInterest;324 325  SmallVector<Decl *, 16> Decls;326  Unit->findFileRegionDecls(File, Offset, Length, Decls);327 328  // If we didn't find any file level decls for the file, try looking at the329  // file that it was included from.330  while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {331    bool Invalid = false;332    const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);333    if (Invalid)334      return false;335 336    SourceLocation Outer;337    if (SLEntry.isFile())338      Outer = SLEntry.getFile().getIncludeLoc();339    else340      Outer = SLEntry.getExpansion().getExpansionLocStart();341    if (Outer.isInvalid())342      return false;343 344    std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);345    Length = 0;346    Unit->findFileRegionDecls(File, Offset, Length, Decls);347  }348 349  assert(!Decls.empty());350 351  bool VisitedAtLeastOnce = false;352  DeclContext *CurDC = nullptr;353  SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();354  for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {355    Decl *D = *DIt;356    if (D->getSourceRange().isInvalid())357      continue;358 359    if (isInLexicalContext(D, CurDC))360      continue;361 362    CurDC = dyn_cast<DeclContext>(D);363 364    if (TagDecl *TD = dyn_cast<TagDecl>(D))365      if (!TD->isFreeStanding())366        continue;367 368    RangeComparisonResult CompRes =369        RangeCompare(SM, D->getSourceRange(), Range);370    if (CompRes == RangeBefore)371      continue;372    if (CompRes == RangeAfter)373      break;374 375    assert(CompRes == RangeOverlap);376    VisitedAtLeastOnce = true;377 378    if (isa<ObjCContainerDecl>(D)) {379      FileDI_current = &DIt;380      FileDE_current = DE;381    } else {382      FileDI_current = nullptr;383    }384 385    if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))386      return true; // visitation break.387  }388 389  if (VisitedAtLeastOnce)390    return false;391 392  // No Decls overlapped with the range. Move up the lexical context until there393  // is a context that contains the range or we reach the translation unit394  // level.395  DeclContext *DC = DIt == Decls.begin()396                        ? (*DIt)->getLexicalDeclContext()397                        : (*(DIt - 1))->getLexicalDeclContext();398 399  while (DC && !DC->isTranslationUnit()) {400    Decl *D = cast<Decl>(DC);401    SourceRange CurDeclRange = D->getSourceRange();402    if (CurDeclRange.isInvalid())403      break;404 405    if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {406      if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))407        return true; // visitation break.408    }409 410    DC = D->getLexicalDeclContext();411  }412 413  return false;414}415 416bool CursorVisitor::visitPreprocessedEntitiesInRegion() {417  if (!AU->getPreprocessor().getPreprocessingRecord())418    return false;419 420  PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();421  SourceManager &SM = AU->getSourceManager();422 423  if (RegionOfInterest.isValid()) {424    SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);425    SourceLocation B = MappedRange.getBegin();426    SourceLocation E = MappedRange.getEnd();427 428    if (AU->isInPreambleFileID(B)) {429      if (SM.isLoadedSourceLocation(E))430        return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,431                                                *this);432 433      // Beginning of range lies in the preamble but it also extends beyond434      // it into the main file. Split the range into 2 parts, one covering435      // the preamble and another covering the main file. This allows subsequent436      // calls to visitPreprocessedEntitiesInRange to accept a source range that437      // lies in the same FileID, allowing it to skip preprocessed entities that438      // do not come from the same FileID.439      bool breaked = visitPreprocessedEntitiesInRange(440          SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);441      if (breaked)442        return true;443      return visitPreprocessedEntitiesInRange(444          SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);445    }446 447    return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);448  }449 450  bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();451 452  if (OnlyLocalDecls)453    return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),454                                     PPRec);455 456  return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);457}458 459template <typename InputIterator>460bool CursorVisitor::visitPreprocessedEntities(InputIterator First,461                                              InputIterator Last,462                                              PreprocessingRecord &PPRec,463                                              FileID FID) {464  for (; First != Last; ++First) {465    if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))466      continue;467 468    PreprocessedEntity *PPE = *First;469    if (!PPE)470      continue;471 472    if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {473      if (Visit(MakeMacroExpansionCursor(ME, TU)))474        return true;475 476      continue;477    }478 479    if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {480      if (Visit(MakeMacroDefinitionCursor(MD, TU)))481        return true;482 483      continue;484    }485 486    if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {487      if (Visit(MakeInclusionDirectiveCursor(ID, TU)))488        return true;489 490      continue;491    }492  }493 494  return false;495}496 497/// Visit the children of the given cursor.498///499/// \returns true if the visitation should be aborted, false if it500/// should continue.501bool CursorVisitor::VisitChildren(CXCursor Cursor) {502  if (clang_isReference(Cursor.kind) &&503      Cursor.kind != CXCursor_CXXBaseSpecifier) {504    // By definition, references have no children.505    return false;506  }507 508  // Set the Parent field to Cursor, then back to its old value once we're509  // done.510  SetParentRAII SetParent(Parent, StmtParent, Cursor);511 512  if (clang_isDeclaration(Cursor.kind)) {513    Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));514    if (!D)515      return false;516 517    return VisitAttributes(D) || Visit(D);518  }519 520  if (clang_isStatement(Cursor.kind)) {521    if (const Stmt *S = getCursorStmt(Cursor))522      return Visit(S);523 524    return false;525  }526 527  if (clang_isExpression(Cursor.kind)) {528    if (const Expr *E = getCursorExpr(Cursor))529      return Visit(E);530 531    return false;532  }533 534  if (clang_isTranslationUnit(Cursor.kind)) {535    CXTranslationUnit TU = getCursorTU(Cursor);536    ASTUnit *CXXUnit = cxtu::getASTUnit(TU);537 538    int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};539    for (unsigned I = 0; I != 2; ++I) {540      if (VisitOrder[I]) {541        if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&542            RegionOfInterest.isInvalid()) {543          for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),544                                           TLEnd = CXXUnit->top_level_end();545               TL != TLEnd; ++TL) {546            const std::optional<bool> V = handleDeclForVisitation(*TL);547            if (!V)548              continue;549            return *V;550          }551        } else if (VisitDeclContext(552                       CXXUnit->getASTContext().getTranslationUnitDecl()))553          return true;554        continue;555      }556 557      // Walk the preprocessing record.558      if (CXXUnit->getPreprocessor().getPreprocessingRecord())559        visitPreprocessedEntitiesInRegion();560    }561 562    return false;563  }564 565  if (Cursor.kind == CXCursor_CXXBaseSpecifier) {566    if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {567      if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {568        return Visit(BaseTSInfo->getTypeLoc());569      }570    }571  }572 573  if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {574    const IBOutletCollectionAttr *A =575        cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));576    if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())577      return Visit(cxcursor::MakeCursorObjCClassRef(578          ObjT->getInterface(),579          A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));580  }581 582  if (clang_isAttribute(Cursor.kind)) {583    if (const Attr *A = getCursorAttr(Cursor))584      return Visit(A);585 586    return false;587  }588 589  // If pointing inside a macro definition, check if the token is an identifier590  // that was ever defined as a macro. In such a case, create a "pseudo" macro591  // expansion cursor for that token.592  SourceLocation BeginLoc = RegionOfInterest.getBegin();593  if (Cursor.kind == CXCursor_MacroDefinition &&594      BeginLoc == RegionOfInterest.getEnd()) {595    SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);596    const MacroInfo *MI =597        getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);598    if (MacroDefinitionRecord *MacroDef =599            checkForMacroInMacroDefinition(MI, Loc, TU))600      return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));601  }602 603  // Nothing to visit at the moment.604  return false;605}606 607bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {608  if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())609    if (Visit(TSInfo->getTypeLoc()))610      return true;611 612  if (Stmt *Body = B->getBody())613    return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));614 615  return false;616}617 618std::optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {619  if (RegionOfInterest.isValid()) {620    SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());621    if (Range.isInvalid())622      return std::nullopt;623 624    switch (CompareRegionOfInterest(Range)) {625    case RangeBefore:626      // This declaration comes before the region of interest; skip it.627      return std::nullopt;628 629    case RangeAfter:630      // This declaration comes after the region of interest; we're done.631      return false;632 633    case RangeOverlap:634      // This declaration overlaps the region of interest; visit it.635      break;636    }637  }638  return true;639}640 641bool CursorVisitor::VisitDeclContext(DeclContext *DC) {642  DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();643 644  // FIXME: Eventually remove.  This part of a hack to support proper645  // iteration over all Decls contained lexically within an ObjC container.646  SaveAndRestore DI_saved(DI_current, &I);647  SaveAndRestore DE_saved(DE_current, E);648 649  for (; I != E; ++I) {650    Decl *D = *I;651    if (D->getLexicalDeclContext() != DC)652      continue;653    // Filter out synthesized property accessor redeclarations.654    if (isa<ObjCImplDecl>(DC))655      if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))656        if (OMD->isSynthesizedAccessorStub())657          continue;658    const std::optional<bool> V = handleDeclForVisitation(D);659    if (!V)660      continue;661    return *V;662  }663  return false;664}665 666std::optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {667  CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);668 669  // Ignore synthesized ivars here, otherwise if we have something like:670  //   @synthesize prop = _prop;671  // and '_prop' is not declared, we will encounter a '_prop' ivar before672  // encountering the 'prop' synthesize declaration and we will think that673  // we passed the region-of-interest.674  if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {675    if (ivarD->getSynthesize())676      return std::nullopt;677  }678 679  // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol680  // declarations is a mismatch with the compiler semantics.681  if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {682    auto *ID = cast<ObjCInterfaceDecl>(D);683    if (!ID->isThisDeclarationADefinition())684      Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);685 686  } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {687    auto *PD = cast<ObjCProtocolDecl>(D);688    if (!PD->isThisDeclarationADefinition())689      Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);690  }691 692  const std::optional<bool> V = shouldVisitCursor(Cursor);693  if (!V)694    return std::nullopt;695  if (!*V)696    return false;697  if (Visit(Cursor, true))698    return true;699  return std::nullopt;700}701 702bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {703  llvm_unreachable("Translation units are visited directly by Visit()");704}705 706bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {707  if (VisitTemplateParameters(D->getTemplateParameters()))708    return true;709 710  return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));711}712 713bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {714  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())715    return Visit(TSInfo->getTypeLoc());716 717  return false;718}719 720bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {721  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())722    return Visit(TSInfo->getTypeLoc());723 724  return false;725}726 727bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }728 729bool CursorVisitor::VisitClassTemplateSpecializationDecl(730    ClassTemplateSpecializationDecl *D) {731  bool ShouldVisitBody = false;732  switch (D->getSpecializationKind()) {733  case TSK_Undeclared:734  case TSK_ImplicitInstantiation:735    // Nothing to visit736    return false;737 738  case TSK_ExplicitInstantiationDeclaration:739  case TSK_ExplicitInstantiationDefinition:740    break;741 742  case TSK_ExplicitSpecialization:743    ShouldVisitBody = true;744    break;745  }746 747  // Visit the template arguments used in the specialization.748  if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) {749    for (const TemplateArgumentLoc &Arg : ArgsWritten->arguments())750      if (VisitTemplateArgumentLoc(Arg))751        return true;752  }753 754  return ShouldVisitBody && VisitCXXRecordDecl(D);755}756 757bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(758    ClassTemplatePartialSpecializationDecl *D) {759  // FIXME: Visit the "outer" template parameter lists on the TagDecl760  // before visiting these template parameters.761  if (VisitTemplateParameters(D->getTemplateParameters()))762    return true;763 764  // Visit the partial specialization arguments.765  const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();766  const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();767  for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)768    if (VisitTemplateArgumentLoc(TemplateArgs[I]))769      return true;770 771  return VisitCXXRecordDecl(D);772}773 774bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {775  if (const auto *TC = D->getTypeConstraint()) {776    if (VisitTypeConstraint(*TC))777      return true;778  }779 780  // Visit the default argument.781  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&782      VisitTemplateArgumentLoc(D->getDefaultArgument()))783    return true;784 785  return false;786}787 788bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {789  if (Expr *Init = D->getInitExpr())790    return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));791  return false;792}793 794bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {795  unsigned NumParamList = DD->getNumTemplateParameterLists();796  for (unsigned i = 0; i < NumParamList; i++) {797    TemplateParameterList *Params = DD->getTemplateParameterList(i);798    if (VisitTemplateParameters(Params))799      return true;800  }801 802  if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())803    if (Visit(TSInfo->getTypeLoc()))804      return true;805 806  // Visit the nested-name-specifier, if present.807  if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())808    if (VisitNestedNameSpecifierLoc(QualifierLoc))809      return true;810 811  return false;812}813 814static bool HasTrailingReturnType(FunctionDecl *ND) {815  const QualType Ty = ND->getType();816  if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {817    if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))818      return FT->hasTrailingReturn();819  }820 821  return false;822}823 824/// Compare two base or member initializers based on their source order.825static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,826                                      CXXCtorInitializer *const *Y) {827  return (*X)->getSourceOrder() - (*Y)->getSourceOrder();828}829 830bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {831  unsigned NumParamList = ND->getNumTemplateParameterLists();832  for (unsigned i = 0; i < NumParamList; i++) {833    TemplateParameterList *Params = ND->getTemplateParameterList(i);834    if (VisitTemplateParameters(Params))835      return true;836  }837 838  if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {839    // Visit the function declaration's syntactic components in the order840    // written. This requires a bit of work.841    TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();842    FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();843    const bool HasTrailingRT = HasTrailingReturnType(ND);844 845    // If we have a function declared directly (without the use of a typedef),846    // visit just the return type. Otherwise, just visit the function's type847    // now.848    if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&849         Visit(FTL.getReturnLoc())) ||850        (!FTL && Visit(TL)))851      return true;852 853    // Visit the nested-name-specifier, if present.854    if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())855      if (VisitNestedNameSpecifierLoc(QualifierLoc))856        return true;857 858    // Visit the declaration name.859    if (!isa<CXXDestructorDecl>(ND))860      if (VisitDeclarationNameInfo(ND->getNameInfo()))861        return true;862 863    // FIXME: Visit explicitly-specified template arguments!864 865    // Visit the function parameters, if we have a function type.866    if (FTL && VisitFunctionTypeLoc(FTL, true))867      return true;868 869    // Visit the function's trailing return type.870    if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))871      return true;872 873    // FIXME: Attributes?874  }875 876  if (auto *E = ND->getTrailingRequiresClause().ConstraintExpr) {877    if (Visit(E))878      return true;879  }880 881  if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {882    if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {883      // Find the initializers that were written in the source.884      SmallVector<CXXCtorInitializer *, 4> WrittenInits;885      for (auto *I : Constructor->inits()) {886        if (!I->isWritten())887          continue;888 889        WrittenInits.push_back(I);890      }891 892      // Sort the initializers in source order893      llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),894                           &CompareCXXCtorInitializers);895 896      // Visit the initializers in source order897      for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {898        CXXCtorInitializer *Init = WrittenInits[I];899        if (Init->isAnyMemberInitializer()) {900          if (Visit(MakeCursorMemberRef(Init->getAnyMember(),901                                        Init->getMemberLocation(), TU)))902            return true;903        } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {904          if (Visit(TInfo->getTypeLoc()))905            return true;906        }907 908        // Visit the initializer value.909        if (Expr *Initializer = Init->getInit())910          if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))911            return true;912      }913    }914 915    if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))916      return true;917  }918 919  return false;920}921 922bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {923  if (VisitDeclaratorDecl(D))924    return true;925 926  if (Expr *BitWidth = D->getBitWidth())927    return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));928 929  if (Expr *Init = D->getInClassInitializer())930    return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));931 932  return false;933}934 935bool CursorVisitor::VisitVarDecl(VarDecl *D) {936  if (VisitDeclaratorDecl(D))937    return true;938 939  if (Expr *Init = D->getInit())940    return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));941 942  return false;943}944 945bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {946  if (VisitDeclaratorDecl(D))947    return true;948 949  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())950    if (D->hasDefaultArgument() &&951        VisitTemplateArgumentLoc(D->getDefaultArgument()))952      return true;953 954  return false;955}956 957bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {958  // FIXME: Visit the "outer" template parameter lists on the FunctionDecl959  // before visiting these template parameters.960  if (VisitTemplateParameters(D->getTemplateParameters()))961    return true;962 963  auto *FD = D->getTemplatedDecl();964  return VisitAttributes(FD) || VisitFunctionDecl(FD);965}966 967bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {968  // FIXME: Visit the "outer" template parameter lists on the TagDecl969  // before visiting these template parameters.970  if (VisitTemplateParameters(D->getTemplateParameters()))971    return true;972 973  auto *CD = D->getTemplatedDecl();974  return VisitAttributes(CD) || VisitCXXRecordDecl(CD);975}976 977bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {978  if (VisitTemplateParameters(D->getTemplateParameters()))979    return true;980 981  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&982      VisitTemplateArgumentLoc(D->getDefaultArgument()))983    return true;984 985  return false;986}987 988bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {989  // Visit the bound, if it's explicit.990  if (D->hasExplicitBound()) {991    if (auto TInfo = D->getTypeSourceInfo()) {992      if (Visit(TInfo->getTypeLoc()))993        return true;994    }995  }996 997  return false;998}999 1000bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {1001  if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())1002    if (Visit(TSInfo->getTypeLoc()))1003      return true;1004 1005  for (const auto *P : ND->parameters()) {1006    if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))1007      return true;1008  }1009 1010  return ND->isThisDeclarationADefinition() &&1011         Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));1012}1013 1014template <typename DeclIt>1015static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,1016                                      SourceManager &SM, SourceLocation EndLoc,1017                                      SmallVectorImpl<Decl *> &Decls) {1018  DeclIt next = *DI_current;1019  while (++next != DE_current) {1020    Decl *D_next = *next;1021    if (!D_next)1022      break;1023    SourceLocation L = D_next->getBeginLoc();1024    if (!L.isValid())1025      break;1026    if (SM.isBeforeInTranslationUnit(L, EndLoc)) {1027      *DI_current = next;1028      Decls.push_back(D_next);1029      continue;1030    }1031    break;1032  }1033}1034 1035bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {1036  // FIXME: Eventually convert back to just 'VisitDeclContext()'.  Essentially1037  // an @implementation can lexically contain Decls that are not properly1038  // nested in the AST.  When we identify such cases, we need to retrofit1039  // this nesting here.1040  if (!DI_current && !FileDI_current)1041    return VisitDeclContext(D);1042 1043  // Scan the Decls that immediately come after the container1044  // in the current DeclContext.  If any fall within the1045  // container's lexical region, stash them into a vector1046  // for later processing.1047  SmallVector<Decl *, 24> DeclsInContainer;1048  SourceLocation EndLoc = D->getSourceRange().getEnd();1049  SourceManager &SM = AU->getSourceManager();1050  if (EndLoc.isValid()) {1051    if (DI_current) {1052      addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,1053                                DeclsInContainer);1054    } else {1055      addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,1056                                DeclsInContainer);1057    }1058  }1059 1060  // The common case.1061  if (DeclsInContainer.empty())1062    return VisitDeclContext(D);1063 1064  // Get all the Decls in the DeclContext, and sort them with the1065  // additional ones we've collected.  Then visit them.1066  for (auto *SubDecl : D->decls()) {1067    if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||1068        SubDecl->getBeginLoc().isInvalid())1069      continue;1070    DeclsInContainer.push_back(SubDecl);1071  }1072 1073  // Now sort the Decls so that they appear in lexical order.1074  llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {1075    SourceLocation L_A = A->getBeginLoc();1076    SourceLocation L_B = B->getBeginLoc();1077    return L_A != L_B1078               ? SM.isBeforeInTranslationUnit(L_A, L_B)1079               : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());1080  });1081 1082  // Now visit the decls.1083  for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),1084                                         E = DeclsInContainer.end();1085       I != E; ++I) {1086    CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);1087    const std::optional<bool> &V = shouldVisitCursor(Cursor);1088    if (!V)1089      continue;1090    if (!*V)1091      return false;1092    if (Visit(Cursor, true))1093      return true;1094  }1095  return false;1096}1097 1098bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {1099  if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),1100                                   TU)))1101    return true;1102 1103  if (VisitObjCTypeParamList(ND->getTypeParamList()))1104    return true;1105 1106  ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();1107  for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),1108                                           E = ND->protocol_end();1109       I != E; ++I, ++PL)1110    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))1111      return true;1112 1113  return VisitObjCContainerDecl(ND);1114}1115 1116bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {1117  if (!PID->isThisDeclarationADefinition())1118    return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));1119 1120  ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();1121  for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),1122                                           E = PID->protocol_end();1123       I != E; ++I, ++PL)1124    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))1125      return true;1126 1127  return VisitObjCContainerDecl(PID);1128}1129 1130bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {1131  if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))1132    return true;1133 1134  // FIXME: This implements a workaround with @property declarations also being1135  // installed in the DeclContext for the @interface.  Eventually this code1136  // should be removed.1137  ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());1138  if (!CDecl || !CDecl->IsClassExtension())1139    return false;1140 1141  ObjCInterfaceDecl *ID = CDecl->getClassInterface();1142  if (!ID)1143    return false;1144 1145  IdentifierInfo *PropertyId = PD->getIdentifier();1146  ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(1147      cast<DeclContext>(ID), PropertyId, PD->getQueryKind());1148 1149  if (!prevDecl)1150    return false;1151 1152  // Visit synthesized methods since they will be skipped when visiting1153  // the @interface.1154  if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())1155    if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)1156      if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))1157        return true;1158 1159  if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())1160    if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)1161      if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))1162        return true;1163 1164  return false;1165}1166 1167bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {1168  if (!typeParamList)1169    return false;1170 1171  for (auto *typeParam : *typeParamList) {1172    // Visit the type parameter.1173    if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))1174      return true;1175  }1176 1177  return false;1178}1179 1180bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {1181  if (!D->isThisDeclarationADefinition()) {1182    // Forward declaration is treated like a reference.1183    return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));1184  }1185 1186  // Objective-C type parameters.1187  if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))1188    return true;1189 1190  // Issue callbacks for super class.1191  if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(1192                                D->getSuperClass(), D->getSuperClassLoc(), TU)))1193    return true;1194 1195  if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())1196    if (Visit(SuperClassTInfo->getTypeLoc()))1197      return true;1198 1199  ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();1200  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),1201                                            E = D->protocol_end();1202       I != E; ++I, ++PL)1203    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))1204      return true;1205 1206  return VisitObjCContainerDecl(D);1207}1208 1209bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {1210  return VisitObjCContainerDecl(D);1211}1212 1213bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {1214  // 'ID' could be null when dealing with invalid code.1215  if (ObjCInterfaceDecl *ID = D->getClassInterface())1216    if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))1217      return true;1218 1219  return VisitObjCImplDecl(D);1220}1221 1222bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {1223#if 01224  // Issue callbacks for super class.1225  // FIXME: No source location information!1226  if (D->getSuperClass() &&1227      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),1228                                        D->getSuperClassLoc(),1229                                        TU)))1230    return true;1231#endif1232 1233  return VisitObjCImplDecl(D);1234}1235 1236bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {1237  if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())1238    if (PD->isIvarNameSpecified())1239      return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));1240 1241  return false;1242}1243 1244bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {1245  return VisitDeclContext(D);1246}1247 1248bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {1249  // Visit nested-name-specifier.1250  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())1251    if (VisitNestedNameSpecifierLoc(QualifierLoc))1252      return true;1253 1254  return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),1255                                      D->getTargetNameLoc(), TU));1256}1257 1258bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {1259  // Visit nested-name-specifier.1260  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {1261    if (VisitNestedNameSpecifierLoc(QualifierLoc))1262      return true;1263  }1264 1265  if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))1266    return true;1267 1268  return VisitDeclarationNameInfo(D->getNameInfo());1269}1270 1271bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {1272  // Visit nested-name-specifier.1273  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())1274    if (VisitNestedNameSpecifierLoc(QualifierLoc))1275      return true;1276 1277  return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),1278                                      D->getIdentLocation(), TU));1279}1280 1281bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {1282  // Visit nested-name-specifier.1283  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {1284    if (VisitNestedNameSpecifierLoc(QualifierLoc))1285      return true;1286  }1287 1288  return VisitDeclarationNameInfo(D->getNameInfo());1289}1290 1291bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(1292    UnresolvedUsingTypenameDecl *D) {1293  // Visit nested-name-specifier.1294  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())1295    if (VisitNestedNameSpecifierLoc(QualifierLoc))1296      return true;1297 1298  return false;1299}1300 1301bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {1302  if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))1303    return true;1304  if (auto *Message = D->getMessage())1305    if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))1306      return true;1307  return false;1308}1309 1310bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {1311  if (NamedDecl *FriendD = D->getFriendDecl()) {1312    if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))1313      return true;1314  } else if (TypeSourceInfo *TI = D->getFriendType()) {1315    if (Visit(TI->getTypeLoc()))1316      return true;1317  }1318  return false;1319}1320 1321bool CursorVisitor::VisitDecompositionDecl(DecompositionDecl *D) {1322  for (auto *B : D->bindings()) {1323    if (Visit(MakeCXCursor(B, TU, RegionOfInterest)))1324      return true;1325  }1326  return VisitVarDecl(D);1327}1328 1329bool CursorVisitor::VisitConceptDecl(ConceptDecl *D) {1330  if (VisitTemplateParameters(D->getTemplateParameters()))1331    return true;1332 1333  if (auto *E = D->getConstraintExpr()) {1334    if (Visit(MakeCXCursor(E, D, TU, RegionOfInterest)))1335      return true;1336  }1337  return false;1338}1339 1340bool CursorVisitor::VisitTypeConstraint(const TypeConstraint &TC) {1341  if (TC.getNestedNameSpecifierLoc()) {1342    if (VisitNestedNameSpecifierLoc(TC.getNestedNameSpecifierLoc()))1343      return true;1344  }1345  if (TC.getNamedConcept()) {1346    if (Visit(MakeCursorTemplateRef(TC.getNamedConcept(),1347                                    TC.getConceptNameLoc(), TU)))1348      return true;1349  }1350  if (auto Args = TC.getTemplateArgsAsWritten()) {1351    for (const auto &Arg : Args->arguments()) {1352      if (VisitTemplateArgumentLoc(Arg))1353        return true;1354    }1355  }1356  return false;1357}1358 1359bool CursorVisitor::VisitConceptRequirement(const concepts::Requirement &R) {1360  using namespace concepts;1361  switch (R.getKind()) {1362  case Requirement::RK_Type: {1363    const TypeRequirement &TR = cast<TypeRequirement>(R);1364    if (!TR.isSubstitutionFailure()) {1365      if (Visit(TR.getType()->getTypeLoc()))1366        return true;1367    }1368    break;1369  }1370  case Requirement::RK_Simple:1371  case Requirement::RK_Compound: {1372    const ExprRequirement &ER = cast<ExprRequirement>(R);1373    if (!ER.isExprSubstitutionFailure()) {1374      if (Visit(ER.getExpr()))1375        return true;1376    }1377    if (ER.getKind() == Requirement::RK_Compound) {1378      const auto &RTR = ER.getReturnTypeRequirement();1379      if (RTR.isTypeConstraint()) {1380        if (const auto *Cons = RTR.getTypeConstraint())1381          VisitTypeConstraint(*Cons);1382      }1383    }1384    break;1385  }1386  case Requirement::RK_Nested: {1387    const NestedRequirement &NR = cast<NestedRequirement>(R);1388    if (!NR.hasInvalidConstraint()) {1389      if (Visit(NR.getConstraintExpr()))1390        return true;1391    }1392    break;1393  }1394  }1395  return false;1396}1397 1398bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {1399  switch (Name.getName().getNameKind()) {1400  case clang::DeclarationName::Identifier:1401  case clang::DeclarationName::CXXLiteralOperatorName:1402  case clang::DeclarationName::CXXDeductionGuideName:1403  case clang::DeclarationName::CXXOperatorName:1404  case clang::DeclarationName::CXXUsingDirective:1405    return false;1406 1407  case clang::DeclarationName::CXXConstructorName:1408  case clang::DeclarationName::CXXDestructorName:1409  case clang::DeclarationName::CXXConversionFunctionName:1410    if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())1411      return Visit(TSInfo->getTypeLoc());1412    return false;1413 1414  case clang::DeclarationName::ObjCZeroArgSelector:1415  case clang::DeclarationName::ObjCOneArgSelector:1416  case clang::DeclarationName::ObjCMultiArgSelector:1417    // FIXME: Per-identifier location info?1418    return false;1419  }1420 1421  llvm_unreachable("Invalid DeclarationName::Kind!");1422}1423 1424bool CursorVisitor::VisitNestedNameSpecifierLoc(1425    NestedNameSpecifierLoc Qualifier) {1426  NestedNameSpecifier NNS = Qualifier.getNestedNameSpecifier();1427  switch (NNS.getKind()) {1428  case NestedNameSpecifier::Kind::Namespace: {1429    auto [Namespace, Prefix] = Qualifier.castAsNamespaceAndPrefix();1430    if (VisitNestedNameSpecifierLoc(Prefix))1431      return true;1432    return Visit(1433        MakeCursorNamespaceRef(Namespace, Qualifier.getLocalBeginLoc(), TU));1434  }1435  case NestedNameSpecifier::Kind::Type:1436    return Visit(Qualifier.castAsTypeLoc());1437  case NestedNameSpecifier::Kind::Null:1438  case NestedNameSpecifier::Kind::Global:1439  case NestedNameSpecifier::Kind::MicrosoftSuper:1440    return false;1441  }1442  llvm_unreachable("unexpected nested name specifier kind");1443}1444 1445bool CursorVisitor::VisitTemplateParameters(1446    const TemplateParameterList *Params) {1447  if (!Params)1448    return false;1449 1450  for (TemplateParameterList::const_iterator P = Params->begin(),1451                                             PEnd = Params->end();1452       P != PEnd; ++P) {1453    if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))1454      return true;1455  }1456 1457  if (const auto *E = Params->getRequiresClause()) {1458    if (Visit(MakeCXCursor(E, nullptr, TU, RegionOfInterest)))1459      return true;1460  }1461 1462  return false;1463}1464 1465bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation NameLoc,1466                                      NestedNameSpecifierLoc NNS) {1467  switch (Name.getKind()) {1468  case TemplateName::QualifiedTemplate: {1469    const QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName();1470    assert(QTN->getQualifier() == NNS.getNestedNameSpecifier());1471    if (VisitNestedNameSpecifierLoc(NNS))1472      return true;1473    return VisitTemplateName(QTN->getUnderlyingTemplate(), NameLoc, /*NNS=*/{});1474  }1475  case TemplateName::Template:1476  case TemplateName::UsingTemplate:1477    return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), NameLoc, TU));1478 1479  case TemplateName::OverloadedTemplate:1480    // Visit the overloaded template set.1481    if (Visit(MakeCursorOverloadedDeclRef(Name, NameLoc, TU)))1482      return true;1483 1484    return false;1485 1486  case TemplateName::AssumedTemplate:1487    // FIXME: Visit DeclarationName?1488    return false;1489 1490  case TemplateName::DependentTemplate: {1491    assert(Name.getAsDependentTemplateName()->getQualifier() ==1492           NNS.getNestedNameSpecifier());1493    return VisitNestedNameSpecifierLoc(NNS);1494  }1495 1496  case TemplateName::SubstTemplateTemplateParm:1497    return Visit(MakeCursorTemplateRef(1498        Name.getAsSubstTemplateTemplateParm()->getParameter(), NameLoc, TU));1499 1500  case TemplateName::SubstTemplateTemplateParmPack:1501    return Visit(MakeCursorTemplateRef(1502        Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), NameLoc,1503        TU));1504 1505  case TemplateName::DeducedTemplate:1506    llvm_unreachable("DeducedTemplate shouldn't appear in source");1507  }1508 1509  llvm_unreachable("Invalid TemplateName::Kind!");1510}1511 1512bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {1513  switch (TAL.getArgument().getKind()) {1514  case TemplateArgument::Null:1515  case TemplateArgument::Integral:1516  case TemplateArgument::Pack:1517    return false;1518 1519  case TemplateArgument::Type:1520    if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())1521      return Visit(TSInfo->getTypeLoc());1522    return false;1523 1524  case TemplateArgument::Declaration:1525    if (Expr *E = TAL.getSourceDeclExpression())1526      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));1527    return false;1528 1529  case TemplateArgument::StructuralValue:1530    if (Expr *E = TAL.getSourceStructuralValueExpression())1531      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));1532    return false;1533 1534  case TemplateArgument::NullPtr:1535    if (Expr *E = TAL.getSourceNullPtrExpression())1536      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));1537    return false;1538 1539  case TemplateArgument::Expression:1540    if (Expr *E = TAL.getSourceExpression())1541      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));1542    return false;1543 1544  case TemplateArgument::Template:1545  case TemplateArgument::TemplateExpansion:1546    return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),1547                             TAL.getTemplateNameLoc(),1548                             TAL.getTemplateQualifierLoc());1549  }1550 1551  llvm_unreachable("Invalid TemplateArgument::Kind!");1552}1553 1554bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {1555  return VisitDeclContext(D);1556}1557 1558bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {1559  return Visit(TL.getUnqualifiedLoc());1560}1561 1562bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {1563  ASTContext &Context = AU->getASTContext();1564 1565  // Some builtin types (such as Objective-C's "id", "sel", and1566  // "Class") have associated declarations. Create cursors for those.1567  QualType VisitType;1568  switch (TL.getTypePtr()->getKind()) {1569 1570  case BuiltinType::Void:1571  case BuiltinType::NullPtr:1572  case BuiltinType::Dependent:1573#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \1574  case BuiltinType::Id:1575#include "clang/Basic/OpenCLImageTypes.def"1576#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:1577#include "clang/Basic/OpenCLExtensionTypes.def"1578  case BuiltinType::OCLSampler:1579  case BuiltinType::OCLEvent:1580  case BuiltinType::OCLClkEvent:1581  case BuiltinType::OCLQueue:1582  case BuiltinType::OCLReserveID:1583#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:1584#include "clang/Basic/AArch64ACLETypes.def"1585#define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:1586#include "clang/Basic/PPCTypes.def"1587#define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:1588#include "clang/Basic/RISCVVTypes.def"1589#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:1590#include "clang/Basic/WebAssemblyReferenceTypes.def"1591#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:1592#include "clang/Basic/AMDGPUTypes.def"1593#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:1594#include "clang/Basic/HLSLIntangibleTypes.def"1595#define BUILTIN_TYPE(Id, SingletonId)1596#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:1597#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:1598#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:1599#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:1600#include "clang/AST/BuiltinTypes.def"1601    break;1602 1603  case BuiltinType::ObjCId:1604    VisitType = Context.getObjCIdType();1605    break;1606 1607  case BuiltinType::ObjCClass:1608    VisitType = Context.getObjCClassType();1609    break;1610 1611  case BuiltinType::ObjCSel:1612    VisitType = Context.getObjCSelType();1613    break;1614  }1615 1616  if (!VisitType.isNull()) {1617    if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())1618      return Visit(1619          MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));1620  }1621 1622  return false;1623}1624 1625bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {1626  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))1627    return true;1628 1629  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));1630}1631 1632bool CursorVisitor::VisitPredefinedSugarTypeLoc(PredefinedSugarTypeLoc TL) {1633  return false;1634}1635 1636bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {1637  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))1638    return true;1639 1640  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));1641}1642 1643bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {1644  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))1645    return true;1646 1647  if (TL.isDefinition())1648    return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));1649 1650  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));1651}1652 1653bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {1654  if (const auto *TC = TL.getDecl()->getTypeConstraint()) {1655    if (VisitTypeConstraint(*TC))1656      return true;1657  }1658 1659  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));1660}1661 1662bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {1663  return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));1664}1665 1666bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {1667  if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))1668    return true;1669  for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {1670    if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),1671                                        TU)))1672      return true;1673  }1674 1675  return false;1676}1677 1678bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {1679  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))1680    return true;1681 1682  for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {1683    if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))1684      return true;1685  }1686 1687  for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {1688    if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),1689                                        TU)))1690      return true;1691  }1692 1693  return false;1694}1695 1696bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {1697  return Visit(TL.getPointeeLoc());1698}1699 1700bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {1701  return Visit(TL.getInnerLoc());1702}1703 1704bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {1705  return Visit(TL.getInnerLoc());1706}1707 1708bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {1709  return Visit(TL.getPointeeLoc());1710}1711 1712bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {1713  return Visit(TL.getPointeeLoc());1714}1715 1716bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {1717  return Visit(TL.getPointeeLoc());1718}1719 1720bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {1721  return Visit(TL.getPointeeLoc());1722}1723 1724bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {1725  return Visit(TL.getPointeeLoc());1726}1727 1728bool CursorVisitor::VisitUsingTypeLoc(UsingTypeLoc TL) {1729  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))1730    return true;1731 1732  auto *underlyingDecl = TL.getTypePtr()->getAsTagDecl();1733  if (underlyingDecl) {1734    return Visit(MakeCursorTypeRef(underlyingDecl, TL.getNameLoc(), TU));1735  }1736  return false;1737}1738 1739bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {1740  return Visit(TL.getModifiedLoc());1741}1742 1743bool CursorVisitor::VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) {1744  return Visit(TL.getInnerLoc());1745}1746 1747bool CursorVisitor::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {1748  return Visit(TL.getWrappedLoc());1749}1750 1751bool CursorVisitor::VisitHLSLAttributedResourceTypeLoc(1752    HLSLAttributedResourceTypeLoc TL) {1753  return Visit(TL.getWrappedLoc());1754}1755 1756bool CursorVisitor::VisitHLSLInlineSpirvTypeLoc(HLSLInlineSpirvTypeLoc TL) {1757  // Nothing to do.1758  return false;1759}1760 1761bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,1762                                         bool SkipResultType) {1763  if (!SkipResultType && Visit(TL.getReturnLoc()))1764    return true;1765 1766  for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)1767    if (Decl *D = TL.getParam(I))1768      if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))1769        return true;1770 1771  return false;1772}1773 1774bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {1775  if (Visit(TL.getElementLoc()))1776    return true;1777 1778  if (Expr *Size = TL.getSizeExpr())1779    return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));1780 1781  return false;1782}1783 1784bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {1785  return Visit(TL.getOriginalLoc());1786}1787 1788bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {1789  return Visit(TL.getOriginalLoc());1790}1791 1792bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(1793    DeducedTemplateSpecializationTypeLoc TL) {1794  if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),1795                        TL.getTemplateNameLoc(), TL.getQualifierLoc()))1796    return true;1797 1798  return false;1799}1800 1801bool CursorVisitor::VisitTemplateSpecializationTypeLoc(1802    TemplateSpecializationTypeLoc TL) {1803  // Visit the template name.1804  if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),1805                        TL.getTemplateNameLoc(), TL.getQualifierLoc()))1806    return true;1807 1808  // Visit the template arguments.1809  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)1810    if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))1811      return true;1812 1813  return false;1814}1815 1816bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {1817  return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));1818}1819 1820bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {1821  if (TypeSourceInfo *TSInfo = TL.getUnmodifiedTInfo())1822    return Visit(TSInfo->getTypeLoc());1823 1824  return false;1825}1826 1827bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {1828  if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())1829    return Visit(TSInfo->getTypeLoc());1830 1831  return false;1832}1833 1834bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {1835  return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());1836}1837 1838bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {1839  return Visit(TL.getPatternLoc());1840}1841 1842bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {1843  if (Expr *E = TL.getUnderlyingExpr())1844    return Visit(MakeCXCursor(E, StmtParent, TU));1845 1846  return false;1847}1848 1849bool CursorVisitor::VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) {1850  if (Visit(TL.getPatternLoc()))1851    return true;1852  return Visit(MakeCXCursor(TL.getIndexExpr(), StmtParent, TU));1853}1854 1855bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {1856  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));1857}1858 1859bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {1860  return Visit(TL.getValueLoc());1861}1862 1863bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {1864  return Visit(TL.getValueLoc());1865}1866 1867#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT)                                    \1868  bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) {               \1869    return Visit##PARENT##Loc(TL);                                             \1870  }1871 1872DEFAULT_TYPELOC_IMPL(Complex, Type)1873DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)1874DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)1875DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)1876DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)1877DEFAULT_TYPELOC_IMPL(ArrayParameter, ConstantArrayType)1878DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)1879DEFAULT_TYPELOC_IMPL(DependentVector, Type)1880DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)1881DEFAULT_TYPELOC_IMPL(Vector, Type)1882DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)1883DEFAULT_TYPELOC_IMPL(ConstantMatrix, MatrixType)1884DEFAULT_TYPELOC_IMPL(DependentSizedMatrix, MatrixType)1885DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)1886DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)1887DEFAULT_TYPELOC_IMPL(Record, TagType)1888DEFAULT_TYPELOC_IMPL(Enum, TagType)1889DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)1890DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)1891DEFAULT_TYPELOC_IMPL(SubstBuiltinTemplatePack, Type)1892DEFAULT_TYPELOC_IMPL(Auto, Type)1893DEFAULT_TYPELOC_IMPL(BitInt, Type)1894DEFAULT_TYPELOC_IMPL(DependentBitInt, Type)1895 1896bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {1897  // Visit the nested-name-specifier, if present.1898  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())1899    if (VisitNestedNameSpecifierLoc(QualifierLoc))1900      return true;1901 1902  if (D->isCompleteDefinition()) {1903    for (const auto &I : D->bases()) {1904      if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))1905        return true;1906    }1907  }1908 1909  return VisitTagDecl(D);1910}1911 1912bool CursorVisitor::VisitAttributes(Decl *D) {1913  for (const auto *I : D->attrs())1914    if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||1915         !I->isImplicit()) &&1916        Visit(MakeCXCursor(I, D, TU)))1917      return true;1918 1919  return false;1920}1921 1922//===----------------------------------------------------------------------===//1923// Data-recursive visitor methods.1924//===----------------------------------------------------------------------===//1925 1926namespace {1927#define DEF_JOB(NAME, DATA, KIND)                                              \1928  class NAME : public VisitorJob {                                             \1929  public:                                                                      \1930    NAME(const DATA *d, CXCursor parent)                                       \1931        : VisitorJob(parent, VisitorJob::KIND, d) {}                           \1932    static bool classof(const VisitorJob *VJ) {                                \1933      return VJ->getKind() == KIND;                                            \1934    }                                                                          \1935    const DATA *get() const { return static_cast<const DATA *>(data[0]); }     \1936  };1937 1938DEF_JOB(StmtVisit, Stmt, StmtVisitKind)1939DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)1940DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)1941DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)1942DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)1943DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)1944DEF_JOB(ConceptSpecializationExprVisit, ConceptSpecializationExpr,1945        ConceptSpecializationExprVisitKind)1946DEF_JOB(RequiresExprVisit, RequiresExpr, RequiresExprVisitKind)1947DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)1948#undef DEF_JOB1949 1950class ExplicitTemplateArgsVisit : public VisitorJob {1951public:1952  ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,1953                            const TemplateArgumentLoc *End, CXCursor parent)1954      : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,1955                   End) {}1956  static bool classof(const VisitorJob *VJ) {1957    return VJ->getKind() == ExplicitTemplateArgsVisitKind;1958  }1959  const TemplateArgumentLoc *begin() const {1960    return static_cast<const TemplateArgumentLoc *>(data[0]);1961  }1962  const TemplateArgumentLoc *end() {1963    return static_cast<const TemplateArgumentLoc *>(data[1]);1964  }1965};1966class DeclVisit : public VisitorJob {1967public:1968  DeclVisit(const Decl *D, CXCursor parent, bool isFirst)1969      : VisitorJob(parent, VisitorJob::DeclVisitKind, D,1970                   isFirst ? (void *)1 : (void *)nullptr) {}1971  static bool classof(const VisitorJob *VJ) {1972    return VJ->getKind() == DeclVisitKind;1973  }1974  const Decl *get() const { return static_cast<const Decl *>(data[0]); }1975  bool isFirst() const { return data[1] != nullptr; }1976};1977class TypeLocVisit : public VisitorJob {1978public:1979  TypeLocVisit(TypeLoc tl, CXCursor parent)1980      : VisitorJob(parent, VisitorJob::TypeLocVisitKind,1981                   tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}1982 1983  static bool classof(const VisitorJob *VJ) {1984    return VJ->getKind() == TypeLocVisitKind;1985  }1986 1987  TypeLoc get() const {1988    QualType T = QualType::getFromOpaquePtr(data[0]);1989    return TypeLoc(T, const_cast<void *>(data[1]));1990  }1991};1992 1993class LabelRefVisit : public VisitorJob {1994public:1995  LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)1996      : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,1997                   labelLoc.getPtrEncoding()) {}1998 1999  static bool classof(const VisitorJob *VJ) {2000    return VJ->getKind() == VisitorJob::LabelRefVisitKind;2001  }2002  const LabelDecl *get() const {2003    return static_cast<const LabelDecl *>(data[0]);2004  }2005  SourceLocation getLoc() const {2006    return SourceLocation::getFromPtrEncoding(data[1]);2007  }2008};2009 2010class NestedNameSpecifierLocVisit : public VisitorJob {2011public:2012  NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)2013      : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,2014                   Qualifier.getNestedNameSpecifier().getAsVoidPointer(),2015                   Qualifier.getOpaqueData()) {}2016 2017  static bool classof(const VisitorJob *VJ) {2018    return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;2019  }2020 2021  NestedNameSpecifierLoc get() const {2022    return NestedNameSpecifierLoc(2023        NestedNameSpecifier::getFromVoidPointer(data[0]),2024        const_cast<void *>(data[1]));2025  }2026};2027 2028class DeclarationNameInfoVisit : public VisitorJob {2029public:2030  DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)2031      : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}2032  static bool classof(const VisitorJob *VJ) {2033    return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;2034  }2035  DeclarationNameInfo get() const {2036    const Stmt *S = static_cast<const Stmt *>(data[0]);2037    switch (S->getStmtClass()) {2038    default:2039      llvm_unreachable("Unhandled Stmt");2040    case clang::Stmt::MSDependentExistsStmtClass:2041      return cast<MSDependentExistsStmt>(S)->getNameInfo();2042    case Stmt::CXXDependentScopeMemberExprClass:2043      return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();2044    case Stmt::DependentScopeDeclRefExprClass:2045      return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();2046    case Stmt::OMPCriticalDirectiveClass:2047      return cast<OMPCriticalDirective>(S)->getDirectiveName();2048    }2049  }2050};2051class MemberRefVisit : public VisitorJob {2052public:2053  MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)2054      : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,2055                   L.getPtrEncoding()) {}2056  static bool classof(const VisitorJob *VJ) {2057    return VJ->getKind() == VisitorJob::MemberRefVisitKind;2058  }2059  const FieldDecl *get() const {2060    return static_cast<const FieldDecl *>(data[0]);2061  }2062  SourceLocation getLoc() const {2063    return SourceLocation::getFromRawEncoding(2064        (SourceLocation::UIntTy)(uintptr_t)data[1]);2065  }2066};2067class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void>,2068                       public ConstAttrVisitor<EnqueueVisitor, void> {2069  friend class OpenACCClauseEnqueue;2070  friend class OMPClauseEnqueue;2071  VisitorWorkList &WL;2072  CXCursor Parent;2073 2074public:2075  EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)2076      : WL(wl), Parent(parent) {}2077 2078  void VisitAddrLabelExpr(const AddrLabelExpr *E);2079  void VisitBlockExpr(const BlockExpr *B);2080  void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);2081  void VisitCompoundStmt(const CompoundStmt *S);2082  void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */2083  }2084  void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);2085  void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);2086  void VisitCXXNewExpr(const CXXNewExpr *E);2087  void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);2088  void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);2089  void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);2090  void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);2091  void VisitCXXTypeidExpr(const CXXTypeidExpr *E);2092  void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);2093  void VisitCXXUuidofExpr(const CXXUuidofExpr *E);2094  void VisitCXXCatchStmt(const CXXCatchStmt *S);2095  void VisitCXXForRangeStmt(const CXXForRangeStmt *S);2096  void VisitDeclRefExpr(const DeclRefExpr *D);2097  void VisitDeclStmt(const DeclStmt *S);2098  void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);2099  void VisitDesignatedInitExpr(const DesignatedInitExpr *E);2100  void VisitExplicitCastExpr(const ExplicitCastExpr *E);2101  void VisitForStmt(const ForStmt *FS);2102  void VisitGotoStmt(const GotoStmt *GS);2103  void VisitIfStmt(const IfStmt *If);2104  void VisitInitListExpr(const InitListExpr *IE);2105  void VisitMemberExpr(const MemberExpr *M);2106  void VisitOffsetOfExpr(const OffsetOfExpr *E);2107  void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);2108  void VisitObjCMessageExpr(const ObjCMessageExpr *M);2109  void VisitOverloadExpr(const OverloadExpr *E);2110  void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);2111  void VisitStmt(const Stmt *S);2112  void VisitSwitchStmt(const SwitchStmt *S);2113  void VisitWhileStmt(const WhileStmt *W);2114  void VisitTypeTraitExpr(const TypeTraitExpr *E);2115  void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);2116  void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);2117  void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);2118  void VisitVAArgExpr(const VAArgExpr *E);2119  void VisitSizeOfPackExpr(const SizeOfPackExpr *E);2120  void VisitPseudoObjectExpr(const PseudoObjectExpr *E);2121  void VisitOpaqueValueExpr(const OpaqueValueExpr *E);2122  void VisitLambdaExpr(const LambdaExpr *E);2123  void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);2124  void VisitRequiresExpr(const RequiresExpr *E);2125  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);2126  void VisitOpenACCComputeConstruct(const OpenACCComputeConstruct *D);2127  void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *D);2128  void VisitOpenACCCombinedConstruct(const OpenACCCombinedConstruct *D);2129  void VisitOpenACCDataConstruct(const OpenACCDataConstruct *D);2130  void VisitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct *D);2131  void VisitOpenACCExitDataConstruct(const OpenACCExitDataConstruct *D);2132  void VisitOpenACCHostDataConstruct(const OpenACCHostDataConstruct *D);2133  void VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *D);2134  void VisitOpenACCCacheConstruct(const OpenACCCacheConstruct *D);2135  void VisitOpenACCInitConstruct(const OpenACCInitConstruct *D);2136  void VisitOpenACCShutdownConstruct(const OpenACCShutdownConstruct *D);2137  void VisitOpenACCSetConstruct(const OpenACCSetConstruct *D);2138  void VisitOpenACCUpdateConstruct(const OpenACCUpdateConstruct *D);2139  void VisitOpenACCAtomicConstruct(const OpenACCAtomicConstruct *D);2140  void VisitOMPExecutableDirective(const OMPExecutableDirective *D);2141  void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);2142  void VisitOMPLoopDirective(const OMPLoopDirective *D);2143  void VisitOMPParallelDirective(const OMPParallelDirective *D);2144  void VisitOMPSimdDirective(const OMPSimdDirective *D);2145  void VisitOMPCanonicalLoopNestTransformationDirective(2146      const OMPCanonicalLoopNestTransformationDirective *D);2147  void VisitOMPTileDirective(const OMPTileDirective *D);2148  void VisitOMPStripeDirective(const OMPStripeDirective *D);2149  void VisitOMPUnrollDirective(const OMPUnrollDirective *D);2150  void VisitOMPReverseDirective(const OMPReverseDirective *D);2151  void VisitOMPInterchangeDirective(const OMPInterchangeDirective *D);2152  void VisitOMPCanonicalLoopSequenceTransformationDirective(2153      const OMPCanonicalLoopSequenceTransformationDirective *D);2154  void VisitOMPFuseDirective(const OMPFuseDirective *D);2155  void VisitOMPForDirective(const OMPForDirective *D);2156  void VisitOMPForSimdDirective(const OMPForSimdDirective *D);2157  void VisitOMPSectionsDirective(const OMPSectionsDirective *D);2158  void VisitOMPSectionDirective(const OMPSectionDirective *D);2159  void VisitOMPSingleDirective(const OMPSingleDirective *D);2160  void VisitOMPMasterDirective(const OMPMasterDirective *D);2161  void VisitOMPCriticalDirective(const OMPCriticalDirective *D);2162  void VisitOMPParallelForDirective(const OMPParallelForDirective *D);2163  void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);2164  void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);2165  void VisitOMPParallelMaskedDirective(const OMPParallelMaskedDirective *D);2166  void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);2167  void VisitOMPTaskDirective(const OMPTaskDirective *D);2168  void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);2169  void VisitOMPBarrierDirective(const OMPBarrierDirective *D);2170  void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);2171  void VisitOMPAssumeDirective(const OMPAssumeDirective *D);2172  void VisitOMPErrorDirective(const OMPErrorDirective *D);2173  void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);2174  void2175  VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);2176  void VisitOMPCancelDirective(const OMPCancelDirective *D);2177  void VisitOMPFlushDirective(const OMPFlushDirective *D);2178  void VisitOMPDepobjDirective(const OMPDepobjDirective *D);2179  void VisitOMPScanDirective(const OMPScanDirective *D);2180  void VisitOMPOrderedDirective(const OMPOrderedDirective *D);2181  void VisitOMPAtomicDirective(const OMPAtomicDirective *D);2182  void VisitOMPTargetDirective(const OMPTargetDirective *D);2183  void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);2184  void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);2185  void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);2186  void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);2187  void2188  VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);2189  void VisitOMPTeamsDirective(const OMPTeamsDirective *D);2190  void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);2191  void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);2192  void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);2193  void VisitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective *D);2194  void2195  VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);2196  void VisitOMPMaskedTaskLoopSimdDirective(2197      const OMPMaskedTaskLoopSimdDirective *D);2198  void VisitOMPParallelMasterTaskLoopDirective(2199      const OMPParallelMasterTaskLoopDirective *D);2200  void VisitOMPParallelMaskedTaskLoopDirective(2201      const OMPParallelMaskedTaskLoopDirective *D);2202  void VisitOMPParallelMasterTaskLoopSimdDirective(2203      const OMPParallelMasterTaskLoopSimdDirective *D);2204  void VisitOMPParallelMaskedTaskLoopSimdDirective(2205      const OMPParallelMaskedTaskLoopSimdDirective *D);2206  void VisitOMPDistributeDirective(const OMPDistributeDirective *D);2207  void VisitOMPDistributeParallelForDirective(2208      const OMPDistributeParallelForDirective *D);2209  void VisitOMPDistributeParallelForSimdDirective(2210      const OMPDistributeParallelForSimdDirective *D);2211  void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);2212  void VisitOMPTargetParallelForSimdDirective(2213      const OMPTargetParallelForSimdDirective *D);2214  void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);2215  void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);2216  void VisitOMPTeamsDistributeSimdDirective(2217      const OMPTeamsDistributeSimdDirective *D);2218  void VisitOMPTeamsDistributeParallelForSimdDirective(2219      const OMPTeamsDistributeParallelForSimdDirective *D);2220  void VisitOMPTeamsDistributeParallelForDirective(2221      const OMPTeamsDistributeParallelForDirective *D);2222  void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);2223  void VisitOMPTargetTeamsDistributeDirective(2224      const OMPTargetTeamsDistributeDirective *D);2225  void VisitOMPTargetTeamsDistributeParallelForDirective(2226      const OMPTargetTeamsDistributeParallelForDirective *D);2227  void VisitOMPTargetTeamsDistributeParallelForSimdDirective(2228      const OMPTargetTeamsDistributeParallelForSimdDirective *D);2229  void VisitOMPTargetTeamsDistributeSimdDirective(2230      const OMPTargetTeamsDistributeSimdDirective *D);2231 2232  // Attributes2233  void VisitAnnotateAttr(const AnnotateAttr *A);2234 2235private:2236  void AddDeclarationNameInfo(const Stmt *S);2237  void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);2238  void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,2239                               unsigned NumTemplateArgs);2240  void AddMemberRef(const FieldDecl *D, SourceLocation L);2241  void AddStmt(const Stmt *S);2242  void AddDecl(const Decl *D, bool isFirst = true);2243  void AddTypeLoc(TypeSourceInfo *TI);2244  void EnqueueChildren(const Stmt *S);2245  void EnqueueChildren(const OpenACCClause *S);2246  void EnqueueChildren(const OMPClause *S);2247  void EnqueueChildren(const AnnotateAttr *A);2248};2249} // namespace2250 2251void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {2252  // 'S' should always be non-null, since it comes from the2253  // statement we are visiting.2254  WL.push_back(DeclarationNameInfoVisit(S, Parent));2255}2256 2257void EnqueueVisitor::AddNestedNameSpecifierLoc(2258    NestedNameSpecifierLoc Qualifier) {2259  if (Qualifier)2260    WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));2261}2262 2263void EnqueueVisitor::AddStmt(const Stmt *S) {2264  if (S)2265    WL.push_back(StmtVisit(S, Parent));2266}2267void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {2268  if (D)2269    WL.push_back(DeclVisit(D, Parent, isFirst));2270}2271void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,2272                                             unsigned NumTemplateArgs) {2273  WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));2274}2275void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {2276  if (D)2277    WL.push_back(MemberRefVisit(D, L, Parent));2278}2279void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {2280  if (TI)2281    WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));2282}2283void EnqueueVisitor::EnqueueChildren(const Stmt *S) {2284  unsigned size = WL.size();2285  for (const Stmt *SubStmt : S->children()) {2286    AddStmt(SubStmt);2287  }2288  if (size == WL.size())2289    return;2290  // Now reverse the entries we just added.  This will match the DFS2291  // ordering performed by the worklist.2292  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();2293  std::reverse(I, E);2294}2295namespace {2296class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {2297  EnqueueVisitor *Visitor;2298  /// Process clauses with list of variables.2299  template <typename T> void VisitOMPClauseList(T *Node);2300 2301public:2302  OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}2303#define GEN_CLANG_CLAUSE_CLASS2304#define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);2305#include "llvm/Frontend/OpenMP/OMP.inc"2306  void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);2307  void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);2308};2309 2310void OMPClauseEnqueue::VisitOMPClauseWithPreInit(2311    const OMPClauseWithPreInit *C) {2312  Visitor->AddStmt(C->getPreInitStmt());2313}2314 2315void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(2316    const OMPClauseWithPostUpdate *C) {2317  VisitOMPClauseWithPreInit(C);2318  Visitor->AddStmt(C->getPostUpdateExpr());2319}2320 2321void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {2322  VisitOMPClauseWithPreInit(C);2323  Visitor->AddStmt(C->getCondition());2324}2325 2326void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {2327  Visitor->AddStmt(C->getCondition());2328}2329 2330void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {2331  VisitOMPClauseWithPreInit(C);2332  Visitor->AddStmt(C->getNumThreads());2333}2334 2335void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {2336  Visitor->AddStmt(C->getSafelen());2337}2338 2339void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {2340  Visitor->AddStmt(C->getSimdlen());2341}2342 2343void OMPClauseEnqueue::VisitOMPSizesClause(const OMPSizesClause *C) {2344  for (auto E : C->getSizesRefs())2345    Visitor->AddStmt(E);2346}2347 2348void OMPClauseEnqueue::VisitOMPPermutationClause(2349    const OMPPermutationClause *C) {2350  for (auto E : C->getArgsRefs())2351    Visitor->AddStmt(E);2352}2353 2354void OMPClauseEnqueue::VisitOMPFullClause(const OMPFullClause *C) {}2355 2356void OMPClauseEnqueue::VisitOMPPartialClause(const OMPPartialClause *C) {2357  Visitor->AddStmt(C->getFactor());2358}2359 2360void OMPClauseEnqueue::VisitOMPLoopRangeClause(const OMPLoopRangeClause *C) {2361  Visitor->AddStmt(C->getFirst());2362  Visitor->AddStmt(C->getCount());2363}2364 2365void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {2366  Visitor->AddStmt(C->getAllocator());2367}2368 2369void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {2370  Visitor->AddStmt(C->getNumForLoops());2371}2372 2373void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}2374 2375void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}2376 2377void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {2378  VisitOMPClauseWithPreInit(C);2379  Visitor->AddStmt(C->getChunkSize());2380}2381 2382void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {2383  Visitor->AddStmt(C->getNumForLoops());2384}2385 2386void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {2387  Visitor->AddStmt(C->getEventHandler());2388}2389 2390void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *C) {2391  Visitor->AddStmt(C->getCondition());2392}2393 2394void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}2395 2396void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}2397 2398void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}2399 2400void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}2401 2402void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}2403 2404void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}2405 2406void OMPClauseEnqueue::VisitOMPCompareClause(const OMPCompareClause *) {}2407 2408void OMPClauseEnqueue::VisitOMPFailClause(const OMPFailClause *) {}2409 2410void OMPClauseEnqueue::VisitOMPThreadsetClause(const OMPThreadsetClause *) {}2411 2412void OMPClauseEnqueue::VisitOMPAbsentClause(const OMPAbsentClause *) {}2413 2414void OMPClauseEnqueue::VisitOMPHoldsClause(const OMPHoldsClause *) {}2415 2416void OMPClauseEnqueue::VisitOMPContainsClause(const OMPContainsClause *) {}2417 2418void OMPClauseEnqueue::VisitOMPNoOpenMPClause(const OMPNoOpenMPClause *) {}2419 2420void OMPClauseEnqueue::VisitOMPNoOpenMPRoutinesClause(2421    const OMPNoOpenMPRoutinesClause *) {}2422 2423void OMPClauseEnqueue::VisitOMPNoOpenMPConstructsClause(2424    const OMPNoOpenMPConstructsClause *) {}2425 2426void OMPClauseEnqueue::VisitOMPNoParallelismClause(2427    const OMPNoParallelismClause *) {}2428 2429void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}2430 2431void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}2432 2433void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}2434 2435void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}2436 2437void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}2438 2439void OMPClauseEnqueue::VisitOMPWeakClause(const OMPWeakClause *) {}2440 2441void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}2442 2443void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}2444 2445void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}2446 2447void OMPClauseEnqueue::VisitOMPInitClause(const OMPInitClause *C) {2448  VisitOMPClauseList(C);2449}2450 2451void OMPClauseEnqueue::VisitOMPUseClause(const OMPUseClause *C) {2452  Visitor->AddStmt(C->getInteropVar());2453}2454 2455void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *C) {2456  if (C->getInteropVar())2457    Visitor->AddStmt(C->getInteropVar());2458}2459 2460void OMPClauseEnqueue::VisitOMPNovariantsClause(const OMPNovariantsClause *C) {2461  Visitor->AddStmt(C->getCondition());2462}2463 2464void OMPClauseEnqueue::VisitOMPNocontextClause(const OMPNocontextClause *C) {2465  Visitor->AddStmt(C->getCondition());2466}2467 2468void OMPClauseEnqueue::VisitOMPFilterClause(const OMPFilterClause *C) {2469  VisitOMPClauseWithPreInit(C);2470  Visitor->AddStmt(C->getThreadID());2471}2472 2473void OMPClauseEnqueue::VisitOMPAlignClause(const OMPAlignClause *C) {2474  Visitor->AddStmt(C->getAlignment());2475}2476 2477void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(2478    const OMPUnifiedAddressClause *) {}2479 2480void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(2481    const OMPUnifiedSharedMemoryClause *) {}2482 2483void OMPClauseEnqueue::VisitOMPReverseOffloadClause(2484    const OMPReverseOffloadClause *) {}2485 2486void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(2487    const OMPDynamicAllocatorsClause *) {}2488 2489void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(2490    const OMPAtomicDefaultMemOrderClause *) {}2491 2492void OMPClauseEnqueue::VisitOMPSelfMapsClause(const OMPSelfMapsClause *) {}2493 2494void OMPClauseEnqueue::VisitOMPAtClause(const OMPAtClause *) {}2495 2496void OMPClauseEnqueue::VisitOMPSeverityClause(const OMPSeverityClause *) {}2497 2498void OMPClauseEnqueue::VisitOMPMessageClause(const OMPMessageClause *) {}2499 2500void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {2501  Visitor->AddStmt(C->getDevice());2502}2503 2504void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {2505  VisitOMPClauseList(C);2506  VisitOMPClauseWithPreInit(C);2507}2508 2509void OMPClauseEnqueue::VisitOMPThreadLimitClause(2510    const OMPThreadLimitClause *C) {2511  VisitOMPClauseList(C);2512  VisitOMPClauseWithPreInit(C);2513}2514 2515void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {2516  Visitor->AddStmt(C->getPriority());2517}2518 2519void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {2520  Visitor->AddStmt(C->getGrainsize());2521}2522 2523void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {2524  Visitor->AddStmt(C->getNumTasks());2525}2526 2527void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {2528  Visitor->AddStmt(C->getHint());2529}2530 2531template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {2532  for (const auto *I : Node->varlist()) {2533    Visitor->AddStmt(I);2534  }2535}2536 2537void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {2538  VisitOMPClauseList(C);2539}2540void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {2541  VisitOMPClauseList(C);2542}2543void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {2544  VisitOMPClauseList(C);2545  Visitor->AddStmt(C->getAllocator());2546}2547void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {2548  VisitOMPClauseList(C);2549  for (const auto *E : C->private_copies()) {2550    Visitor->AddStmt(E);2551  }2552}2553void OMPClauseEnqueue::VisitOMPFirstprivateClause(2554    const OMPFirstprivateClause *C) {2555  VisitOMPClauseList(C);2556  VisitOMPClauseWithPreInit(C);2557  for (const auto *E : C->private_copies()) {2558    Visitor->AddStmt(E);2559  }2560  for (const auto *E : C->inits()) {2561    Visitor->AddStmt(E);2562  }2563}2564void OMPClauseEnqueue::VisitOMPLastprivateClause(2565    const OMPLastprivateClause *C) {2566  VisitOMPClauseList(C);2567  VisitOMPClauseWithPostUpdate(C);2568  for (auto *E : C->private_copies()) {2569    Visitor->AddStmt(E);2570  }2571  for (auto *E : C->source_exprs()) {2572    Visitor->AddStmt(E);2573  }2574  for (auto *E : C->destination_exprs()) {2575    Visitor->AddStmt(E);2576  }2577  for (auto *E : C->assignment_ops()) {2578    Visitor->AddStmt(E);2579  }2580}2581void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {2582  VisitOMPClauseList(C);2583}2584void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {2585  VisitOMPClauseList(C);2586  VisitOMPClauseWithPostUpdate(C);2587  for (auto *E : C->privates()) {2588    Visitor->AddStmt(E);2589  }2590  for (auto *E : C->lhs_exprs()) {2591    Visitor->AddStmt(E);2592  }2593  for (auto *E : C->rhs_exprs()) {2594    Visitor->AddStmt(E);2595  }2596  for (auto *E : C->reduction_ops()) {2597    Visitor->AddStmt(E);2598  }2599  if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {2600    for (auto *E : C->copy_ops()) {2601      Visitor->AddStmt(E);2602    }2603    for (auto *E : C->copy_array_temps()) {2604      Visitor->AddStmt(E);2605    }2606    for (auto *E : C->copy_array_elems()) {2607      Visitor->AddStmt(E);2608    }2609  }2610}2611void OMPClauseEnqueue::VisitOMPTaskReductionClause(2612    const OMPTaskReductionClause *C) {2613  VisitOMPClauseList(C);2614  VisitOMPClauseWithPostUpdate(C);2615  for (auto *E : C->privates()) {2616    Visitor->AddStmt(E);2617  }2618  for (auto *E : C->lhs_exprs()) {2619    Visitor->AddStmt(E);2620  }2621  for (auto *E : C->rhs_exprs()) {2622    Visitor->AddStmt(E);2623  }2624  for (auto *E : C->reduction_ops()) {2625    Visitor->AddStmt(E);2626  }2627}2628void OMPClauseEnqueue::VisitOMPInReductionClause(2629    const OMPInReductionClause *C) {2630  VisitOMPClauseList(C);2631  VisitOMPClauseWithPostUpdate(C);2632  for (auto *E : C->privates()) {2633    Visitor->AddStmt(E);2634  }2635  for (auto *E : C->lhs_exprs()) {2636    Visitor->AddStmt(E);2637  }2638  for (auto *E : C->rhs_exprs()) {2639    Visitor->AddStmt(E);2640  }2641  for (auto *E : C->reduction_ops()) {2642    Visitor->AddStmt(E);2643  }2644  for (auto *E : C->taskgroup_descriptors())2645    Visitor->AddStmt(E);2646}2647void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {2648  VisitOMPClauseList(C);2649  VisitOMPClauseWithPostUpdate(C);2650  for (const auto *E : C->privates()) {2651    Visitor->AddStmt(E);2652  }2653  for (const auto *E : C->inits()) {2654    Visitor->AddStmt(E);2655  }2656  for (const auto *E : C->updates()) {2657    Visitor->AddStmt(E);2658  }2659  for (const auto *E : C->finals()) {2660    Visitor->AddStmt(E);2661  }2662  Visitor->AddStmt(C->getStep());2663  Visitor->AddStmt(C->getCalcStep());2664}2665void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {2666  VisitOMPClauseList(C);2667  Visitor->AddStmt(C->getAlignment());2668}2669void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {2670  VisitOMPClauseList(C);2671  for (auto *E : C->source_exprs()) {2672    Visitor->AddStmt(E);2673  }2674  for (auto *E : C->destination_exprs()) {2675    Visitor->AddStmt(E);2676  }2677  for (auto *E : C->assignment_ops()) {2678    Visitor->AddStmt(E);2679  }2680}2681void OMPClauseEnqueue::VisitOMPCopyprivateClause(2682    const OMPCopyprivateClause *C) {2683  VisitOMPClauseList(C);2684  for (auto *E : C->source_exprs()) {2685    Visitor->AddStmt(E);2686  }2687  for (auto *E : C->destination_exprs()) {2688    Visitor->AddStmt(E);2689  }2690  for (auto *E : C->assignment_ops()) {2691    Visitor->AddStmt(E);2692  }2693}2694void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {2695  VisitOMPClauseList(C);2696}2697void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {2698  Visitor->AddStmt(C->getDepobj());2699}2700void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {2701  VisitOMPClauseList(C);2702}2703void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {2704  VisitOMPClauseList(C);2705}2706void OMPClauseEnqueue::VisitOMPDistScheduleClause(2707    const OMPDistScheduleClause *C) {2708  VisitOMPClauseWithPreInit(C);2709  Visitor->AddStmt(C->getChunkSize());2710}2711void OMPClauseEnqueue::VisitOMPDefaultmapClause(2712    const OMPDefaultmapClause * /*C*/) {}2713void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {2714  VisitOMPClauseList(C);2715}2716void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {2717  VisitOMPClauseList(C);2718}2719void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(2720    const OMPUseDevicePtrClause *C) {2721  VisitOMPClauseList(C);2722}2723void OMPClauseEnqueue::VisitOMPUseDeviceAddrClause(2724    const OMPUseDeviceAddrClause *C) {2725  VisitOMPClauseList(C);2726}2727void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(2728    const OMPIsDevicePtrClause *C) {2729  VisitOMPClauseList(C);2730}2731void OMPClauseEnqueue::VisitOMPHasDeviceAddrClause(2732    const OMPHasDeviceAddrClause *C) {2733  VisitOMPClauseList(C);2734}2735void OMPClauseEnqueue::VisitOMPNontemporalClause(2736    const OMPNontemporalClause *C) {2737  VisitOMPClauseList(C);2738  for (const auto *E : C->private_refs())2739    Visitor->AddStmt(E);2740}2741void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}2742void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(2743    const OMPUsesAllocatorsClause *C) {2744  for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {2745    const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);2746    Visitor->AddStmt(D.Allocator);2747    Visitor->AddStmt(D.AllocatorTraits);2748  }2749}2750void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) {2751  Visitor->AddStmt(C->getModifier());2752  for (const Expr *E : C->varlist())2753    Visitor->AddStmt(E);2754}2755void OMPClauseEnqueue::VisitOMPBindClause(const OMPBindClause *C) {}2756void OMPClauseEnqueue::VisitOMPXDynCGroupMemClause(2757    const OMPXDynCGroupMemClause *C) {2758  VisitOMPClauseWithPreInit(C);2759  Visitor->AddStmt(C->getSize());2760}2761void OMPClauseEnqueue::VisitOMPDynGroupprivateClause(2762    const OMPDynGroupprivateClause *C) {2763  VisitOMPClauseWithPreInit(C);2764  Visitor->AddStmt(C->getSize());2765}2766void OMPClauseEnqueue::VisitOMPDoacrossClause(const OMPDoacrossClause *C) {2767  VisitOMPClauseList(C);2768}2769void OMPClauseEnqueue::VisitOMPXAttributeClause(const OMPXAttributeClause *C) {2770}2771void OMPClauseEnqueue::VisitOMPXBareClause(const OMPXBareClause *C) {}2772 2773} // namespace2774 2775void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {2776  unsigned size = WL.size();2777  OMPClauseEnqueue Visitor(this);2778  Visitor.Visit(S);2779  if (size == WL.size())2780    return;2781  // Now reverse the entries we just added.  This will match the DFS2782  // ordering performed by the worklist.2783  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();2784  std::reverse(I, E);2785}2786 2787namespace {2788class OpenACCClauseEnqueue : public OpenACCClauseVisitor<OpenACCClauseEnqueue> {2789  EnqueueVisitor &Visitor;2790 2791public:2792  OpenACCClauseEnqueue(EnqueueVisitor &V) : Visitor(V) {}2793 2794  void VisitVarList(const OpenACCClauseWithVarList &C) {2795    for (Expr *Var : C.getVarList())2796      Visitor.AddStmt(Var);2797  }2798 2799#define VISIT_CLAUSE(CLAUSE_NAME)                                              \2800  void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &C);2801#include "clang/Basic/OpenACCClauses.def"2802};2803 2804void OpenACCClauseEnqueue::VisitDefaultClause(const OpenACCDefaultClause &C) {}2805void OpenACCClauseEnqueue::VisitIfClause(const OpenACCIfClause &C) {2806  Visitor.AddStmt(C.getConditionExpr());2807}2808void OpenACCClauseEnqueue::VisitSelfClause(const OpenACCSelfClause &C) {2809  if (C.isConditionExprClause()) {2810    if (C.hasConditionExpr())2811      Visitor.AddStmt(C.getConditionExpr());2812  } else {2813    for (Expr *Var : C.getVarList())2814      Visitor.AddStmt(Var);2815  }2816}2817void OpenACCClauseEnqueue::VisitNumWorkersClause(2818    const OpenACCNumWorkersClause &C) {2819  Visitor.AddStmt(C.getIntExpr());2820}2821void OpenACCClauseEnqueue::VisitDeviceNumClause(2822    const OpenACCDeviceNumClause &C) {2823  Visitor.AddStmt(C.getIntExpr());2824}2825void OpenACCClauseEnqueue::VisitDefaultAsyncClause(2826    const OpenACCDefaultAsyncClause &C) {2827  Visitor.AddStmt(C.getIntExpr());2828}2829void OpenACCClauseEnqueue::VisitVectorLengthClause(2830    const OpenACCVectorLengthClause &C) {2831  Visitor.AddStmt(C.getIntExpr());2832}2833void OpenACCClauseEnqueue::VisitNumGangsClause(const OpenACCNumGangsClause &C) {2834  for (Expr *IE : C.getIntExprs())2835    Visitor.AddStmt(IE);2836}2837 2838void OpenACCClauseEnqueue::VisitTileClause(const OpenACCTileClause &C) {2839  for (Expr *IE : C.getSizeExprs())2840    Visitor.AddStmt(IE);2841}2842 2843void OpenACCClauseEnqueue::VisitPrivateClause(const OpenACCPrivateClause &C) {2844  VisitVarList(C);2845  for (const OpenACCPrivateRecipe &R : C.getInitRecipes())2846    Visitor.AddDecl(R.AllocaDecl);2847}2848 2849void OpenACCClauseEnqueue::VisitHostClause(const OpenACCHostClause &C) {2850  VisitVarList(C);2851}2852 2853void OpenACCClauseEnqueue::VisitDeviceClause(const OpenACCDeviceClause &C) {2854  VisitVarList(C);2855}2856 2857void OpenACCClauseEnqueue::VisitFirstPrivateClause(2858    const OpenACCFirstPrivateClause &C) {2859  VisitVarList(C);2860  for (const OpenACCFirstPrivateRecipe &R : C.getInitRecipes()) {2861    Visitor.AddDecl(R.AllocaDecl);2862    Visitor.AddDecl(R.InitFromTemporary);2863  }2864}2865 2866void OpenACCClauseEnqueue::VisitPresentClause(const OpenACCPresentClause &C) {2867  VisitVarList(C);2868}2869void OpenACCClauseEnqueue::VisitNoCreateClause(const OpenACCNoCreateClause &C) {2870  VisitVarList(C);2871}2872void OpenACCClauseEnqueue::VisitCopyClause(const OpenACCCopyClause &C) {2873  VisitVarList(C);2874}2875void OpenACCClauseEnqueue::VisitLinkClause(const OpenACCLinkClause &C) {2876  VisitVarList(C);2877}2878void OpenACCClauseEnqueue::VisitDeviceResidentClause(2879    const OpenACCDeviceResidentClause &C) {2880  VisitVarList(C);2881}2882void OpenACCClauseEnqueue::VisitCopyInClause(const OpenACCCopyInClause &C) {2883  VisitVarList(C);2884}2885void OpenACCClauseEnqueue::VisitCopyOutClause(const OpenACCCopyOutClause &C) {2886  VisitVarList(C);2887}2888void OpenACCClauseEnqueue::VisitCreateClause(const OpenACCCreateClause &C) {2889  VisitVarList(C);2890}2891void OpenACCClauseEnqueue::VisitAttachClause(const OpenACCAttachClause &C) {2892  VisitVarList(C);2893}2894 2895void OpenACCClauseEnqueue::VisitDetachClause(const OpenACCDetachClause &C) {2896  VisitVarList(C);2897}2898void OpenACCClauseEnqueue::VisitDeleteClause(const OpenACCDeleteClause &C) {2899  VisitVarList(C);2900}2901 2902void OpenACCClauseEnqueue::VisitUseDeviceClause(2903    const OpenACCUseDeviceClause &C) {2904  VisitVarList(C);2905}2906 2907void OpenACCClauseEnqueue::VisitDevicePtrClause(2908    const OpenACCDevicePtrClause &C) {2909  VisitVarList(C);2910}2911void OpenACCClauseEnqueue::VisitAsyncClause(const OpenACCAsyncClause &C) {2912  if (C.hasIntExpr())2913    Visitor.AddStmt(C.getIntExpr());2914}2915 2916void OpenACCClauseEnqueue::VisitWorkerClause(const OpenACCWorkerClause &C) {2917  if (C.hasIntExpr())2918    Visitor.AddStmt(C.getIntExpr());2919}2920 2921void OpenACCClauseEnqueue::VisitVectorClause(const OpenACCVectorClause &C) {2922  if (C.hasIntExpr())2923    Visitor.AddStmt(C.getIntExpr());2924}2925 2926void OpenACCClauseEnqueue::VisitWaitClause(const OpenACCWaitClause &C) {2927  if (const Expr *DevNumExpr = C.getDevNumExpr())2928    Visitor.AddStmt(DevNumExpr);2929  for (Expr *QE : C.getQueueIdExprs())2930    Visitor.AddStmt(QE);2931}2932void OpenACCClauseEnqueue::VisitDeviceTypeClause(2933    const OpenACCDeviceTypeClause &C) {}2934void OpenACCClauseEnqueue::VisitReductionClause(2935    const OpenACCReductionClause &C) {2936  VisitVarList(C);2937  for (const OpenACCReductionRecipe &R : C.getRecipes())2938    Visitor.AddDecl(R.AllocaDecl);2939}2940void OpenACCClauseEnqueue::VisitAutoClause(const OpenACCAutoClause &C) {}2941void OpenACCClauseEnqueue::VisitIndependentClause(2942    const OpenACCIndependentClause &C) {}2943void OpenACCClauseEnqueue::VisitSeqClause(const OpenACCSeqClause &C) {}2944void OpenACCClauseEnqueue::VisitNoHostClause(const OpenACCNoHostClause &C) {}2945void OpenACCClauseEnqueue::VisitBindClause(const OpenACCBindClause &C) { }2946void OpenACCClauseEnqueue::VisitFinalizeClause(const OpenACCFinalizeClause &C) {2947}2948void OpenACCClauseEnqueue::VisitIfPresentClause(2949    const OpenACCIfPresentClause &C) {}2950void OpenACCClauseEnqueue::VisitCollapseClause(const OpenACCCollapseClause &C) {2951  Visitor.AddStmt(C.getLoopCount());2952}2953void OpenACCClauseEnqueue::VisitGangClause(const OpenACCGangClause &C) {2954  for (unsigned I = 0; I < C.getNumExprs(); ++I) {2955    Visitor.AddStmt(C.getExpr(I).second);2956  }2957}2958} // namespace2959 2960void EnqueueVisitor::EnqueueChildren(const OpenACCClause *C) {2961  unsigned size = WL.size();2962  OpenACCClauseEnqueue Visitor(*this);2963  Visitor.Visit(C);2964 2965  if (size == WL.size())2966    return;2967  // Now reverse the entries we just added.  This will match the DFS2968  // ordering performed by the worklist.2969  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();2970  std::reverse(I, E);2971}2972 2973void EnqueueVisitor::EnqueueChildren(const AnnotateAttr *A) {2974  unsigned size = WL.size();2975  for (const Expr *Arg : A->args()) {2976    VisitStmt(Arg);2977  }2978  if (size == WL.size())2979    return;2980  // Now reverse the entries we just added.  This will match the DFS2981  // ordering performed by the worklist.2982  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();2983  std::reverse(I, E);2984}2985 2986void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {2987  WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));2988}2989void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {2990  AddDecl(B->getBlockDecl());2991}2992void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {2993  EnqueueChildren(E);2994  AddTypeLoc(E->getTypeSourceInfo());2995}2996void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {2997  for (auto &I : llvm::reverse(S->body()))2998    AddStmt(I);2999}3000void EnqueueVisitor::VisitMSDependentExistsStmt(3001    const MSDependentExistsStmt *S) {3002  AddStmt(S->getSubStmt());3003  AddDeclarationNameInfo(S);3004  if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())3005    AddNestedNameSpecifierLoc(QualifierLoc);3006}3007 3008void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(3009    const CXXDependentScopeMemberExpr *E) {3010  if (E->hasExplicitTemplateArgs())3011    AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());3012  AddDeclarationNameInfo(E);3013  if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())3014    AddNestedNameSpecifierLoc(QualifierLoc);3015  if (!E->isImplicitAccess())3016    AddStmt(E->getBase());3017}3018void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {3019  // Enqueue the initializer , if any.3020  AddStmt(E->getInitializer());3021  // Enqueue the array size, if any.3022  AddStmt(E->getArraySize().value_or(nullptr));3023  // Enqueue the allocated type.3024  AddTypeLoc(E->getAllocatedTypeSourceInfo());3025  // Enqueue the placement arguments.3026  for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)3027    AddStmt(E->getPlacementArg(I - 1));3028}3029void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {3030  for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)3031    AddStmt(CE->getArg(I - 1));3032  AddStmt(CE->getCallee());3033  AddStmt(CE->getArg(0));3034}3035void EnqueueVisitor::VisitCXXPseudoDestructorExpr(3036    const CXXPseudoDestructorExpr *E) {3037  // Visit the name of the type being destroyed.3038  AddTypeLoc(E->getDestroyedTypeInfo());3039  // Visit the scope type that looks disturbingly like the nested-name-specifier3040  // but isn't.3041  AddTypeLoc(E->getScopeTypeInfo());3042  // Visit the nested-name-specifier.3043  if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())3044    AddNestedNameSpecifierLoc(QualifierLoc);3045  // Visit base expression.3046  AddStmt(E->getBase());3047}3048void EnqueueVisitor::VisitCXXScalarValueInitExpr(3049    const CXXScalarValueInitExpr *E) {3050  AddTypeLoc(E->getTypeSourceInfo());3051}3052void EnqueueVisitor::VisitCXXTemporaryObjectExpr(3053    const CXXTemporaryObjectExpr *E) {3054  EnqueueChildren(E);3055  AddTypeLoc(E->getTypeSourceInfo());3056}3057void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {3058  EnqueueChildren(E);3059  if (E->isTypeOperand())3060    AddTypeLoc(E->getTypeOperandSourceInfo());3061}3062 3063void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(3064    const CXXUnresolvedConstructExpr *E) {3065  EnqueueChildren(E);3066  AddTypeLoc(E->getTypeSourceInfo());3067}3068void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {3069  EnqueueChildren(E);3070  if (E->isTypeOperand())3071    AddTypeLoc(E->getTypeOperandSourceInfo());3072}3073 3074void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {3075  EnqueueChildren(S);3076  AddDecl(S->getExceptionDecl());3077}3078 3079void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {3080  AddStmt(S->getBody());3081  AddStmt(S->getRangeInit());3082  AddDecl(S->getLoopVariable());3083}3084 3085void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {3086  if (DR->hasExplicitTemplateArgs())3087    AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());3088  WL.push_back(DeclRefExprParts(DR, Parent));3089}3090void EnqueueVisitor::VisitDependentScopeDeclRefExpr(3091    const DependentScopeDeclRefExpr *E) {3092  if (E->hasExplicitTemplateArgs())3093    AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());3094  AddDeclarationNameInfo(E);3095  AddNestedNameSpecifierLoc(E->getQualifierLoc());3096}3097void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {3098  unsigned size = WL.size();3099  bool isFirst = true;3100  for (const auto *D : S->decls()) {3101    AddDecl(D, isFirst);3102    isFirst = false;3103  }3104  if (size == WL.size())3105    return;3106  // Now reverse the entries we just added.  This will match the DFS3107  // ordering performed by the worklist.3108  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();3109  std::reverse(I, E);3110}3111void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {3112  AddStmt(E->getInit());3113  for (const DesignatedInitExpr::Designator &D :3114       llvm::reverse(E->designators())) {3115    if (D.isFieldDesignator()) {3116      if (const FieldDecl *Field = D.getFieldDecl())3117        AddMemberRef(Field, D.getFieldLoc());3118      continue;3119    }3120    if (D.isArrayDesignator()) {3121      AddStmt(E->getArrayIndex(D));3122      continue;3123    }3124    assert(D.isArrayRangeDesignator() && "Unknown designator kind");3125    AddStmt(E->getArrayRangeEnd(D));3126    AddStmt(E->getArrayRangeStart(D));3127  }3128}3129void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {3130  EnqueueChildren(E);3131  AddTypeLoc(E->getTypeInfoAsWritten());3132}3133void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {3134  AddStmt(FS->getBody());3135  AddStmt(FS->getInc());3136  AddStmt(FS->getCond());3137  AddDecl(FS->getConditionVariable());3138  AddStmt(FS->getInit());3139}3140void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {3141  WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));3142}3143void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {3144  AddStmt(If->getElse());3145  AddStmt(If->getThen());3146  AddStmt(If->getCond());3147  AddStmt(If->getInit());3148  AddDecl(If->getConditionVariable());3149}3150void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {3151  // We care about the syntactic form of the initializer list, only.3152  if (InitListExpr *Syntactic = IE->getSyntacticForm())3153    IE = Syntactic;3154  EnqueueChildren(IE);3155}3156void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {3157  WL.push_back(MemberExprParts(M, Parent));3158 3159  // If the base of the member access expression is an implicit 'this', don't3160  // visit it.3161  // FIXME: If we ever want to show these implicit accesses, this will be3162  // unfortunate. However, clang_getCursor() relies on this behavior.3163  if (M->isImplicitAccess())3164    return;3165 3166  // Ignore base anonymous struct/union fields, otherwise they will shadow the3167  // real field that we are interested in.3168  if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {3169    if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {3170      if (FD->isAnonymousStructOrUnion()) {3171        AddStmt(SubME->getBase());3172        return;3173      }3174    }3175  }3176 3177  AddStmt(M->getBase());3178}3179void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {3180  AddTypeLoc(E->getEncodedTypeSourceInfo());3181}3182void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {3183  EnqueueChildren(M);3184  AddTypeLoc(M->getClassReceiverTypeInfo());3185}3186void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {3187  // Visit the components of the offsetof expression.3188  for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {3189    const OffsetOfNode &Node = E->getComponent(I - 1);3190    switch (Node.getKind()) {3191    case OffsetOfNode::Array:3192      AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));3193      break;3194    case OffsetOfNode::Field:3195      AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());3196      break;3197    case OffsetOfNode::Identifier:3198    case OffsetOfNode::Base:3199      continue;3200    }3201  }3202  // Visit the type into which we're computing the offset.3203  AddTypeLoc(E->getTypeSourceInfo());3204}3205void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {3206  if (E->hasExplicitTemplateArgs())3207    AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());3208  WL.push_back(OverloadExprParts(E, Parent));3209}3210void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(3211    const UnaryExprOrTypeTraitExpr *E) {3212  EnqueueChildren(E);3213  if (E->isArgumentType())3214    AddTypeLoc(E->getArgumentTypeInfo());3215}3216void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }3217void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {3218  AddStmt(S->getBody());3219  AddStmt(S->getCond());3220  AddDecl(S->getConditionVariable());3221}3222 3223void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {3224  AddStmt(W->getBody());3225  AddStmt(W->getCond());3226  AddDecl(W->getConditionVariable());3227}3228 3229void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {3230  for (unsigned I = E->getNumArgs(); I > 0; --I)3231    AddTypeLoc(E->getArg(I - 1));3232}3233 3234void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {3235  AddTypeLoc(E->getQueriedTypeSourceInfo());3236}3237 3238void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {3239  EnqueueChildren(E);3240}3241 3242void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {3243  VisitOverloadExpr(U);3244  if (!U->isImplicitAccess())3245    AddStmt(U->getBase());3246}3247void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {3248  AddStmt(E->getSubExpr());3249  AddTypeLoc(E->getWrittenTypeInfo());3250}3251void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {3252  WL.push_back(SizeOfPackExprParts(E, Parent));3253}3254void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {3255  // If the opaque value has a source expression, just transparently3256  // visit that.  This is useful for (e.g.) pseudo-object expressions.3257  if (Expr *SourceExpr = E->getSourceExpr())3258    return ConstStmtVisitor::Visit(SourceExpr);3259}3260void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {3261  AddStmt(E->getBody());3262  WL.push_back(LambdaExprParts(E, Parent));3263}3264void EnqueueVisitor::VisitConceptSpecializationExpr(3265    const ConceptSpecializationExpr *E) {3266  WL.push_back(ConceptSpecializationExprVisit(E, Parent));3267}3268void EnqueueVisitor::VisitRequiresExpr(const RequiresExpr *E) {3269  WL.push_back(RequiresExprVisit(E, Parent));3270  for (ParmVarDecl *VD : E->getLocalParameters())3271    AddDecl(VD);3272}3273void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {3274  EnqueueChildren(E);3275}3276void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {3277  // Treat the expression like its syntactic form.3278  ConstStmtVisitor::Visit(E->getSyntacticForm());3279}3280 3281void EnqueueVisitor::VisitOMPExecutableDirective(3282    const OMPExecutableDirective *D) {3283  EnqueueChildren(D);3284  for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),3285                                       E = D->clauses().end();3286       I != E; ++I)3287    EnqueueChildren(*I);3288}3289 3290void EnqueueVisitor::VisitOMPLoopBasedDirective(3291    const OMPLoopBasedDirective *D) {3292  VisitOMPExecutableDirective(D);3293}3294 3295void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {3296  VisitOMPLoopBasedDirective(D);3297}3298 3299void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {3300  VisitOMPExecutableDirective(D);3301}3302 3303void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {3304  VisitOMPLoopDirective(D);3305}3306 3307void EnqueueVisitor::VisitOMPCanonicalLoopNestTransformationDirective(3308    const OMPCanonicalLoopNestTransformationDirective *D) {3309  VisitOMPLoopBasedDirective(D);3310}3311 3312void EnqueueVisitor::VisitOMPTileDirective(const OMPTileDirective *D) {3313  VisitOMPCanonicalLoopNestTransformationDirective(D);3314}3315 3316void EnqueueVisitor::VisitOMPStripeDirective(const OMPStripeDirective *D) {3317  VisitOMPCanonicalLoopNestTransformationDirective(D);3318}3319 3320void EnqueueVisitor::VisitOMPUnrollDirective(const OMPUnrollDirective *D) {3321  VisitOMPCanonicalLoopNestTransformationDirective(D);3322}3323 3324void EnqueueVisitor::VisitOMPReverseDirective(const OMPReverseDirective *D) {3325  VisitOMPCanonicalLoopNestTransformationDirective(D);3326}3327 3328void EnqueueVisitor::VisitOMPInterchangeDirective(3329    const OMPInterchangeDirective *D) {3330  VisitOMPCanonicalLoopNestTransformationDirective(D);3331}3332 3333void EnqueueVisitor::VisitOMPCanonicalLoopSequenceTransformationDirective(3334    const OMPCanonicalLoopSequenceTransformationDirective *D) {3335  VisitOMPExecutableDirective(D);3336}3337 3338void EnqueueVisitor::VisitOMPFuseDirective(const OMPFuseDirective *D) {3339  VisitOMPCanonicalLoopSequenceTransformationDirective(D);3340}3341 3342void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {3343  VisitOMPLoopDirective(D);3344}3345 3346void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {3347  VisitOMPLoopDirective(D);3348}3349 3350void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {3351  VisitOMPExecutableDirective(D);3352}3353 3354void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {3355  VisitOMPExecutableDirective(D);3356}3357 3358void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {3359  VisitOMPExecutableDirective(D);3360}3361 3362void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {3363  VisitOMPExecutableDirective(D);3364}3365 3366void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {3367  VisitOMPExecutableDirective(D);3368  AddDeclarationNameInfo(D);3369}3370 3371void EnqueueVisitor::VisitOMPParallelForDirective(3372    const OMPParallelForDirective *D) {3373  VisitOMPLoopDirective(D);3374}3375 3376void EnqueueVisitor::VisitOMPParallelForSimdDirective(3377    const OMPParallelForSimdDirective *D) {3378  VisitOMPLoopDirective(D);3379}3380 3381void EnqueueVisitor::VisitOMPParallelMasterDirective(3382    const OMPParallelMasterDirective *D) {3383  VisitOMPExecutableDirective(D);3384}3385 3386void EnqueueVisitor::VisitOMPParallelMaskedDirective(3387    const OMPParallelMaskedDirective *D) {3388  VisitOMPExecutableDirective(D);3389}3390 3391void EnqueueVisitor::VisitOMPParallelSectionsDirective(3392    const OMPParallelSectionsDirective *D) {3393  VisitOMPExecutableDirective(D);3394}3395 3396void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {3397  VisitOMPExecutableDirective(D);3398}3399 3400void EnqueueVisitor::VisitOMPTaskyieldDirective(3401    const OMPTaskyieldDirective *D) {3402  VisitOMPExecutableDirective(D);3403}3404 3405void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {3406  VisitOMPExecutableDirective(D);3407}3408 3409void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {3410  VisitOMPExecutableDirective(D);3411}3412 3413void EnqueueVisitor::VisitOMPAssumeDirective(const OMPAssumeDirective *D) {3414  VisitOMPExecutableDirective(D);3415}3416 3417void EnqueueVisitor::VisitOMPErrorDirective(const OMPErrorDirective *D) {3418  VisitOMPExecutableDirective(D);3419}3420 3421void EnqueueVisitor::VisitOMPTaskgroupDirective(3422    const OMPTaskgroupDirective *D) {3423  VisitOMPExecutableDirective(D);3424  if (const Expr *E = D->getReductionRef())3425    VisitStmt(E);3426}3427 3428void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {3429  VisitOMPExecutableDirective(D);3430}3431 3432void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {3433  VisitOMPExecutableDirective(D);3434}3435 3436void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {3437  VisitOMPExecutableDirective(D);3438}3439 3440void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {3441  VisitOMPExecutableDirective(D);3442}3443 3444void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {3445  VisitOMPExecutableDirective(D);3446}3447 3448void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {3449  VisitOMPExecutableDirective(D);3450}3451 3452void EnqueueVisitor::VisitOMPTargetDataDirective(3453    const OMPTargetDataDirective *D) {3454  VisitOMPExecutableDirective(D);3455}3456 3457void EnqueueVisitor::VisitOMPTargetEnterDataDirective(3458    const OMPTargetEnterDataDirective *D) {3459  VisitOMPExecutableDirective(D);3460}3461 3462void EnqueueVisitor::VisitOMPTargetExitDataDirective(3463    const OMPTargetExitDataDirective *D) {3464  VisitOMPExecutableDirective(D);3465}3466 3467void EnqueueVisitor::VisitOMPTargetParallelDirective(3468    const OMPTargetParallelDirective *D) {3469  VisitOMPExecutableDirective(D);3470}3471 3472void EnqueueVisitor::VisitOMPTargetParallelForDirective(3473    const OMPTargetParallelForDirective *D) {3474  VisitOMPLoopDirective(D);3475}3476 3477void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {3478  VisitOMPExecutableDirective(D);3479}3480 3481void EnqueueVisitor::VisitOMPCancellationPointDirective(3482    const OMPCancellationPointDirective *D) {3483  VisitOMPExecutableDirective(D);3484}3485 3486void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {3487  VisitOMPExecutableDirective(D);3488}3489 3490void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {3491  VisitOMPLoopDirective(D);3492}3493 3494void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(3495    const OMPTaskLoopSimdDirective *D) {3496  VisitOMPLoopDirective(D);3497}3498 3499void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(3500    const OMPMasterTaskLoopDirective *D) {3501  VisitOMPLoopDirective(D);3502}3503 3504void EnqueueVisitor::VisitOMPMaskedTaskLoopDirective(3505    const OMPMaskedTaskLoopDirective *D) {3506  VisitOMPLoopDirective(D);3507}3508 3509void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(3510    const OMPMasterTaskLoopSimdDirective *D) {3511  VisitOMPLoopDirective(D);3512}3513 3514void EnqueueVisitor::VisitOMPMaskedTaskLoopSimdDirective(3515    const OMPMaskedTaskLoopSimdDirective *D) {3516  VisitOMPLoopDirective(D);3517}3518 3519void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(3520    const OMPParallelMasterTaskLoopDirective *D) {3521  VisitOMPLoopDirective(D);3522}3523 3524void EnqueueVisitor::VisitOMPParallelMaskedTaskLoopDirective(3525    const OMPParallelMaskedTaskLoopDirective *D) {3526  VisitOMPLoopDirective(D);3527}3528 3529void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(3530    const OMPParallelMasterTaskLoopSimdDirective *D) {3531  VisitOMPLoopDirective(D);3532}3533 3534void EnqueueVisitor::VisitOMPParallelMaskedTaskLoopSimdDirective(3535    const OMPParallelMaskedTaskLoopSimdDirective *D) {3536  VisitOMPLoopDirective(D);3537}3538 3539void EnqueueVisitor::VisitOMPDistributeDirective(3540    const OMPDistributeDirective *D) {3541  VisitOMPLoopDirective(D);3542}3543 3544void EnqueueVisitor::VisitOMPDistributeParallelForDirective(3545    const OMPDistributeParallelForDirective *D) {3546  VisitOMPLoopDirective(D);3547}3548 3549void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(3550    const OMPDistributeParallelForSimdDirective *D) {3551  VisitOMPLoopDirective(D);3552}3553 3554void EnqueueVisitor::VisitOMPDistributeSimdDirective(3555    const OMPDistributeSimdDirective *D) {3556  VisitOMPLoopDirective(D);3557}3558 3559void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(3560    const OMPTargetParallelForSimdDirective *D) {3561  VisitOMPLoopDirective(D);3562}3563 3564void EnqueueVisitor::VisitOMPTargetSimdDirective(3565    const OMPTargetSimdDirective *D) {3566  VisitOMPLoopDirective(D);3567}3568 3569void EnqueueVisitor::VisitOMPTeamsDistributeDirective(3570    const OMPTeamsDistributeDirective *D) {3571  VisitOMPLoopDirective(D);3572}3573 3574void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(3575    const OMPTeamsDistributeSimdDirective *D) {3576  VisitOMPLoopDirective(D);3577}3578 3579void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(3580    const OMPTeamsDistributeParallelForSimdDirective *D) {3581  VisitOMPLoopDirective(D);3582}3583 3584void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(3585    const OMPTeamsDistributeParallelForDirective *D) {3586  VisitOMPLoopDirective(D);3587}3588 3589void EnqueueVisitor::VisitOMPTargetTeamsDirective(3590    const OMPTargetTeamsDirective *D) {3591  VisitOMPExecutableDirective(D);3592}3593 3594void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(3595    const OMPTargetTeamsDistributeDirective *D) {3596  VisitOMPLoopDirective(D);3597}3598 3599void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(3600    const OMPTargetTeamsDistributeParallelForDirective *D) {3601  VisitOMPLoopDirective(D);3602}3603 3604void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(3605    const OMPTargetTeamsDistributeParallelForSimdDirective *D) {3606  VisitOMPLoopDirective(D);3607}3608 3609void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(3610    const OMPTargetTeamsDistributeSimdDirective *D) {3611  VisitOMPLoopDirective(D);3612}3613 3614void EnqueueVisitor::VisitOpenACCComputeConstruct(3615    const OpenACCComputeConstruct *C) {3616  EnqueueChildren(C);3617  for (auto *Clause : C->clauses())3618    EnqueueChildren(Clause);3619}3620 3621void EnqueueVisitor::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *C) {3622  EnqueueChildren(C);3623  for (auto *Clause : C->clauses())3624    EnqueueChildren(Clause);3625}3626 3627void EnqueueVisitor::VisitOpenACCCombinedConstruct(3628    const OpenACCCombinedConstruct *C) {3629  EnqueueChildren(C);3630  for (auto *Clause : C->clauses())3631    EnqueueChildren(Clause);3632}3633void EnqueueVisitor::VisitOpenACCDataConstruct(const OpenACCDataConstruct *C) {3634  EnqueueChildren(C);3635  for (auto *Clause : C->clauses())3636    EnqueueChildren(Clause);3637}3638void EnqueueVisitor::VisitOpenACCEnterDataConstruct(3639    const OpenACCEnterDataConstruct *C) {3640  EnqueueChildren(C);3641  for (auto *Clause : C->clauses())3642    EnqueueChildren(Clause);3643}3644void EnqueueVisitor::VisitOpenACCExitDataConstruct(3645    const OpenACCExitDataConstruct *C) {3646  EnqueueChildren(C);3647  for (auto *Clause : C->clauses())3648    EnqueueChildren(Clause);3649}3650void EnqueueVisitor::VisitOpenACCHostDataConstruct(3651    const OpenACCHostDataConstruct *C) {3652  EnqueueChildren(C);3653  for (auto *Clause : C->clauses())3654    EnqueueChildren(Clause);3655}3656 3657void EnqueueVisitor::VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *C) {3658  EnqueueChildren(C);3659  for (auto *Clause : C->clauses())3660    EnqueueChildren(Clause);3661}3662 3663void EnqueueVisitor::VisitOpenACCCacheConstruct(3664    const OpenACCCacheConstruct *C) {3665  EnqueueChildren(C);3666}3667 3668void EnqueueVisitor::VisitOpenACCInitConstruct(const OpenACCInitConstruct *C) {3669  EnqueueChildren(C);3670  for (auto *Clause : C->clauses())3671    EnqueueChildren(Clause);3672}3673 3674void EnqueueVisitor::VisitOpenACCShutdownConstruct(3675    const OpenACCShutdownConstruct *C) {3676  EnqueueChildren(C);3677  for (auto *Clause : C->clauses())3678    EnqueueChildren(Clause);3679}3680 3681void EnqueueVisitor::VisitOpenACCSetConstruct(const OpenACCSetConstruct *C) {3682  EnqueueChildren(C);3683  for (auto *Clause : C->clauses())3684    EnqueueChildren(Clause);3685}3686 3687void EnqueueVisitor::VisitOpenACCUpdateConstruct(3688    const OpenACCUpdateConstruct *C) {3689  EnqueueChildren(C);3690  for (auto *Clause : C->clauses())3691    EnqueueChildren(Clause);3692}3693 3694void EnqueueVisitor::VisitOpenACCAtomicConstruct(3695    const OpenACCAtomicConstruct *C) {3696  EnqueueChildren(C);3697  for (auto *Clause : C->clauses())3698    EnqueueChildren(Clause);3699}3700 3701void EnqueueVisitor::VisitAnnotateAttr(const AnnotateAttr *A) {3702  EnqueueChildren(A);3703}3704 3705void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {3706  EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))3707      .ConstStmtVisitor::Visit(S);3708}3709 3710void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Attr *A) {3711  // Parent is the attribute itself when this is indirectly called from3712  // VisitChildren. Because we need to make a CXCursor for A, we need *its*3713  // parent.3714  auto AttrCursor = Parent;3715 3716  // Get the attribute's parent as stored in3717  // cxcursor::MakeCXCursor(const Attr *A, const Decl *Parent, CXTranslationUnit3718  // TU)3719  const Decl *AttrParent = static_cast<const Decl *>(AttrCursor.data[1]);3720 3721  EnqueueVisitor(WL, MakeCXCursor(A, AttrParent, TU))3722      .ConstAttrVisitor::Visit(A);3723}3724 3725bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {3726  if (RegionOfInterest.isValid()) {3727    SourceRange Range = getRawCursorExtent(C);3728    if (Range.isInvalid() || CompareRegionOfInterest(Range))3729      return false;3730  }3731  return true;3732}3733 3734bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {3735  while (!WL.empty()) {3736    // Dequeue the worklist item.3737    VisitorJob LI = WL.pop_back_val();3738 3739    // Set the Parent field, then back to its old value once we're done.3740    SetParentRAII SetParent(Parent, StmtParent, LI.getParent());3741 3742    switch (LI.getKind()) {3743    case VisitorJob::DeclVisitKind: {3744      const Decl *D = cast<DeclVisit>(&LI)->get();3745      if (!D)3746        continue;3747 3748      // For now, perform default visitation for Decls.3749      if (Visit(MakeCXCursor(D, TU, RegionOfInterest,3750                             cast<DeclVisit>(&LI)->isFirst())))3751        return true;3752 3753      continue;3754    }3755    case VisitorJob::ExplicitTemplateArgsVisitKind: {3756      for (const TemplateArgumentLoc &Arg :3757           *cast<ExplicitTemplateArgsVisit>(&LI)) {3758        if (VisitTemplateArgumentLoc(Arg))3759          return true;3760      }3761      continue;3762    }3763    case VisitorJob::TypeLocVisitKind: {3764      // Perform default visitation for TypeLocs.3765      if (Visit(cast<TypeLocVisit>(&LI)->get()))3766        return true;3767      continue;3768    }3769    case VisitorJob::LabelRefVisitKind: {3770      const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();3771      if (LabelStmt *stmt = LS->getStmt()) {3772        if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),3773                                     TU))) {3774          return true;3775        }3776      }3777      continue;3778    }3779 3780    case VisitorJob::NestedNameSpecifierLocVisitKind: {3781      NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);3782      if (VisitNestedNameSpecifierLoc(V->get()))3783        return true;3784      continue;3785    }3786 3787    case VisitorJob::DeclarationNameInfoVisitKind: {3788      if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))3789        return true;3790      continue;3791    }3792    case VisitorJob::MemberRefVisitKind: {3793      MemberRefVisit *V = cast<MemberRefVisit>(&LI);3794      if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))3795        return true;3796      continue;3797    }3798    case VisitorJob::StmtVisitKind: {3799      const Stmt *S = cast<StmtVisit>(&LI)->get();3800      if (!S)3801        continue;3802 3803      // Update the current cursor.3804      CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);3805      if (!IsInRegionOfInterest(Cursor))3806        continue;3807      switch (Visitor(Cursor, Parent, ClientData)) {3808      case CXChildVisit_Break:3809        return true;3810      case CXChildVisit_Continue:3811        break;3812      case CXChildVisit_Recurse:3813        if (PostChildrenVisitor)3814          WL.push_back(PostChildrenVisit(nullptr, Cursor));3815        EnqueueWorkList(WL, S);3816        break;3817      }3818      continue;3819    }3820    case VisitorJob::MemberExprPartsKind: {3821      // Handle the other pieces in the MemberExpr besides the base.3822      const MemberExpr *M = cast<MemberExprParts>(&LI)->get();3823 3824      // Visit the nested-name-specifier3825      if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())3826        if (VisitNestedNameSpecifierLoc(QualifierLoc))3827          return true;3828 3829      // Visit the declaration name.3830      if (VisitDeclarationNameInfo(M->getMemberNameInfo()))3831        return true;3832 3833      // Visit the explicitly-specified template arguments, if any.3834      if (M->hasExplicitTemplateArgs()) {3835        for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),3836                                       *ArgEnd = Arg + M->getNumTemplateArgs();3837             Arg != ArgEnd; ++Arg) {3838          if (VisitTemplateArgumentLoc(*Arg))3839            return true;3840        }3841      }3842      continue;3843    }3844    case VisitorJob::DeclRefExprPartsKind: {3845      const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();3846      // Visit nested-name-specifier, if present.3847      if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())3848        if (VisitNestedNameSpecifierLoc(QualifierLoc))3849          return true;3850      // Visit declaration name.3851      if (VisitDeclarationNameInfo(DR->getNameInfo()))3852        return true;3853      continue;3854    }3855    case VisitorJob::OverloadExprPartsKind: {3856      const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();3857      // Visit the nested-name-specifier.3858      if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())3859        if (VisitNestedNameSpecifierLoc(QualifierLoc))3860          return true;3861      // Visit the declaration name.3862      if (VisitDeclarationNameInfo(O->getNameInfo()))3863        return true;3864      // Visit the overloaded declaration reference.3865      if (Visit(MakeCursorOverloadedDeclRef(O, TU)))3866        return true;3867      continue;3868    }3869    case VisitorJob::SizeOfPackExprPartsKind: {3870      const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();3871      NamedDecl *Pack = E->getPack();3872      if (isa<TemplateTypeParmDecl>(Pack)) {3873        if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),3874                                    E->getPackLoc(), TU)))3875          return true;3876 3877        continue;3878      }3879 3880      if (isa<TemplateTemplateParmDecl>(Pack)) {3881        if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),3882                                        E->getPackLoc(), TU)))3883          return true;3884 3885        continue;3886      }3887 3888      // Non-type template parameter packs and function parameter packs are3889      // treated like DeclRefExpr cursors.3890      continue;3891    }3892 3893    case VisitorJob::LambdaExprPartsKind: {3894      // Visit non-init captures.3895      const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();3896      for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),3897                                        CEnd = E->explicit_capture_end();3898           C != CEnd; ++C) {3899        if (!C->capturesVariable())3900          continue;3901        // TODO: handle structured bindings here ?3902        if (!isa<VarDecl>(C->getCapturedVar()))3903          continue;3904        if (Visit(MakeCursorVariableRef(cast<VarDecl>(C->getCapturedVar()),3905                                        C->getLocation(), TU)))3906          return true;3907      }3908      // Visit init captures3909      for (auto InitExpr : E->capture_inits()) {3910        if (InitExpr && Visit(InitExpr))3911          return true;3912      }3913 3914      TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();3915      // Visit parameters and return type, if present.3916      if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {3917        if (E->hasExplicitParameters()) {3918          // Visit parameters.3919          for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)3920            if (Visit(MakeCXCursor(Proto.getParam(I), TU)))3921              return true;3922        }3923        if (E->hasExplicitResultType()) {3924          // Visit result type.3925          if (Visit(Proto.getReturnLoc()))3926            return true;3927        }3928      }3929      break;3930    }3931 3932    case VisitorJob::ConceptSpecializationExprVisitKind: {3933      const ConceptSpecializationExpr *E =3934          cast<ConceptSpecializationExprVisit>(&LI)->get();3935      if (NestedNameSpecifierLoc QualifierLoc =3936              E->getNestedNameSpecifierLoc()) {3937        if (VisitNestedNameSpecifierLoc(QualifierLoc))3938          return true;3939      }3940 3941      if (E->getNamedConcept() &&3942          Visit(MakeCursorTemplateRef(E->getNamedConcept(),3943                                      E->getConceptNameLoc(), TU)))3944        return true;3945 3946      if (auto Args = E->getTemplateArgsAsWritten()) {3947        for (const auto &Arg : Args->arguments()) {3948          if (VisitTemplateArgumentLoc(Arg))3949            return true;3950        }3951      }3952      break;3953    }3954 3955    case VisitorJob::RequiresExprVisitKind: {3956      const RequiresExpr *E = cast<RequiresExprVisit>(&LI)->get();3957      for (const concepts::Requirement *R : E->getRequirements())3958        VisitConceptRequirement(*R);3959      break;3960    }3961 3962    case VisitorJob::PostChildrenVisitKind:3963      if (PostChildrenVisitor(Parent, ClientData))3964        return true;3965      break;3966    }3967  }3968  return false;3969}3970 3971bool CursorVisitor::Visit(const Stmt *S) {3972  VisitorWorkList *WL = nullptr;3973  if (!WorkListFreeList.empty()) {3974    WL = WorkListFreeList.back();3975    WL->clear();3976    WorkListFreeList.pop_back();3977  } else {3978    WL = new VisitorWorkList();3979    WorkListCache.push_back(WL);3980  }3981  EnqueueWorkList(*WL, S);3982  bool result = RunVisitorWorkList(*WL);3983  WorkListFreeList.push_back(WL);3984  return result;3985}3986 3987bool CursorVisitor::Visit(const Attr *A) {3988  VisitorWorkList *WL = nullptr;3989  if (!WorkListFreeList.empty()) {3990    WL = WorkListFreeList.back();3991    WL->clear();3992    WorkListFreeList.pop_back();3993  } else {3994    WL = new VisitorWorkList();3995    WorkListCache.push_back(WL);3996  }3997  EnqueueWorkList(*WL, A);3998  bool result = RunVisitorWorkList(*WL);3999  WorkListFreeList.push_back(WL);4000  return result;4001}4002 4003namespace {4004typedef SmallVector<SourceRange, 4> RefNamePieces;4005RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,4006                          const DeclarationNameInfo &NI, SourceRange QLoc,4007                          const SourceRange *TemplateArgsLoc = nullptr) {4008  const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;4009  const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;4010  const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;4011 4012  const DeclarationName::NameKind Kind = NI.getName().getNameKind();4013 4014  RefNamePieces Pieces;4015 4016  if (WantQualifier && QLoc.isValid())4017    Pieces.push_back(QLoc);4018 4019  if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)4020    Pieces.push_back(NI.getLoc());4021 4022  if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())4023    Pieces.push_back(*TemplateArgsLoc);4024 4025  if (Kind == DeclarationName::CXXOperatorName) {4026    Pieces.push_back(NI.getInfo().getCXXOperatorNameBeginLoc());4027    Pieces.push_back(NI.getInfo().getCXXOperatorNameEndLoc());4028  }4029 4030  if (WantSinglePiece) {4031    SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());4032    Pieces.clear();4033    Pieces.push_back(R);4034  }4035 4036  return Pieces;4037}4038} // namespace4039 4040//===----------------------------------------------------------------------===//4041// Misc. API hooks.4042//===----------------------------------------------------------------------===//4043 4044namespace {4045struct RegisterFatalErrorHandler {4046  RegisterFatalErrorHandler() {4047    clang_install_aborting_llvm_fatal_error_handler();4048  }4049};4050} // namespace4051 4052static llvm::ManagedStatic<RegisterFatalErrorHandler>4053    RegisterFatalErrorHandlerOnce;4054 4055static CIndexer *clang_createIndex_Impl(4056    int excludeDeclarationsFromPCH, int displayDiagnostics,4057    unsigned char threadBackgroundPriorityForIndexing = CXChoice_Default,4058    unsigned char threadBackgroundPriorityForEditing = CXChoice_Default) {4059  // We use crash recovery to make some of our APIs more reliable, implicitly4060  // enable it.4061  if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))4062    llvm::CrashRecoveryContext::Enable();4063 4064  // Look through the managed static to trigger construction of the managed4065  // static which registers our fatal error handler. This ensures it is only4066  // registered once.4067  (void)*RegisterFatalErrorHandlerOnce;4068 4069  // Initialize targets for clang module support.4070  llvm::InitializeAllTargets();4071  llvm::InitializeAllTargetMCs();4072  llvm::InitializeAllAsmPrinters();4073  llvm::InitializeAllAsmParsers();4074 4075  CIndexer *CIdxr = new CIndexer();4076 4077  if (excludeDeclarationsFromPCH)4078    CIdxr->setOnlyLocalDecls();4079  if (displayDiagnostics)4080    CIdxr->setDisplayDiagnostics();4081 4082  unsigned GlobalOptions = CIdxr->getCXGlobalOptFlags();4083  const auto updateGlobalOption =4084      [&GlobalOptions](unsigned char Policy, CXGlobalOptFlags Flag,4085                       const char *EnvironmentVariableName) {4086        switch (Policy) {4087        case CXChoice_Enabled:4088          GlobalOptions |= Flag;4089          break;4090        case CXChoice_Disabled:4091          GlobalOptions &= ~Flag;4092          break;4093        case CXChoice_Default:4094        default: // Fall back to default behavior if Policy is unsupported.4095          if (getenv(EnvironmentVariableName))4096            GlobalOptions |= Flag;4097        }4098      };4099  updateGlobalOption(threadBackgroundPriorityForIndexing,4100                     CXGlobalOpt_ThreadBackgroundPriorityForIndexing,4101                     "LIBCLANG_BGPRIO_INDEX");4102  updateGlobalOption(threadBackgroundPriorityForEditing,4103                     CXGlobalOpt_ThreadBackgroundPriorityForEditing,4104                     "LIBCLANG_BGPRIO_EDIT");4105  CIdxr->setCXGlobalOptFlags(GlobalOptions);4106 4107  return CIdxr;4108}4109 4110CXIndex clang_createIndex(int excludeDeclarationsFromPCH,4111                          int displayDiagnostics) {4112  return clang_createIndex_Impl(excludeDeclarationsFromPCH, displayDiagnostics);4113}4114 4115void clang_disposeIndex(CXIndex CIdx) {4116  if (CIdx)4117    delete static_cast<CIndexer *>(CIdx);4118}4119 4120CXIndex clang_createIndexWithOptions(const CXIndexOptions *options) {4121  // Adding new options to struct CXIndexOptions:4122  // 1. If no other new option has been added in the same libclang version,4123  // sizeof(CXIndexOptions) must increase for versioning purposes.4124  // 2. Options should be added at the end of the struct in order to seamlessly4125  // support older struct versions. If options->Size < sizeof(CXIndexOptions),4126  // don't attempt to read the missing options and rely on the default values of4127  // recently added options being reasonable. For example:4128  // if (options->Size >= offsetof(CXIndexOptions, RecentlyAddedMember))4129  //   do_something(options->RecentlyAddedMember);4130 4131  // An exception: if a new option is small enough, it can be squeezed into the4132  // /*Reserved*/ bits in CXIndexOptions. Since the default value of each option4133  // is guaranteed to be 0 and the callers are advised to zero out the struct,4134  // programs built against older libclang versions would implicitly set the new4135  // options to default values, which should keep the behavior of previous4136  // libclang versions and thus be backward-compatible.4137 4138  // If options->Size > sizeof(CXIndexOptions), the user may have set an option4139  // we can't handle, in which case we return nullptr to report failure.4140  // Replace `!=` with `>` here to support older struct versions. `!=` has the4141  // advantage of catching more usage bugs and no disadvantages while there is a4142  // single supported struct version (the initial version).4143  if (options->Size != sizeof(CXIndexOptions))4144    return nullptr;4145  CIndexer *const CIdxr = clang_createIndex_Impl(4146      options->ExcludeDeclarationsFromPCH, options->DisplayDiagnostics,4147      options->ThreadBackgroundPriorityForIndexing,4148      options->ThreadBackgroundPriorityForEditing);4149  CIdxr->setStorePreamblesInMemory(options->StorePreamblesInMemory);4150  CIdxr->setPreambleStoragePath(options->PreambleStoragePath);4151  CIdxr->setInvocationEmissionPath(options->InvocationEmissionPath);4152  return CIdxr;4153}4154 4155void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {4156  if (CIdx)4157    static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);4158}4159 4160unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {4161  if (CIdx)4162    return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();4163  return 0;4164}4165 4166void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,4167                                                   const char *Path) {4168  if (CIdx)4169    static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");4170}4171 4172void clang_toggleCrashRecovery(unsigned isEnabled) {4173  if (isEnabled)4174    llvm::CrashRecoveryContext::Enable();4175  else4176    llvm::CrashRecoveryContext::Disable();4177}4178 4179CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,4180                                              const char *ast_filename) {4181  CXTranslationUnit TU;4182  enum CXErrorCode Result =4183      clang_createTranslationUnit2(CIdx, ast_filename, &TU);4184  (void)Result;4185  assert((TU && Result == CXError_Success) ||4186         (!TU && Result != CXError_Success));4187  return TU;4188}4189 4190enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,4191                                              const char *ast_filename,4192                                              CXTranslationUnit *out_TU) {4193  if (out_TU)4194    *out_TU = nullptr;4195 4196  if (!CIdx || !ast_filename || !out_TU)4197    return CXError_InvalidArguments;4198 4199  LOG_FUNC_SECTION { *Log << ast_filename; }4200 4201  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);4202  FileSystemOptions FileSystemOpts;4203  HeaderSearchOptions HSOpts;4204 4205  auto VFS = llvm::vfs::getRealFileSystem();4206 4207  auto DiagOpts = std::make_shared<DiagnosticOptions>();4208  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =4209      CompilerInstance::createDiagnostics(*VFS, *DiagOpts);4210  std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(4211      ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),4212      ASTUnit::LoadEverything, VFS, DiagOpts, Diags, FileSystemOpts, HSOpts,4213      /*LangOpts=*/nullptr, CXXIdx->getOnlyLocalDecls(), CaptureDiagsKind::All,4214      /*AllowASTWithCompilerErrors=*/true,4215      /*UserFilesAreVolatile=*/true);4216  *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));4217  return *out_TU ? CXError_Success : CXError_Failure;4218}4219 4220unsigned clang_defaultEditingTranslationUnitOptions() {4221  return CXTranslationUnit_PrecompiledPreamble |4222         CXTranslationUnit_CacheCompletionResults;4223}4224 4225CXTranslationUnit clang_createTranslationUnitFromSourceFile(4226    CXIndex CIdx, const char *source_filename, int num_command_line_args,4227    const char *const *command_line_args, unsigned num_unsaved_files,4228    struct CXUnsavedFile *unsaved_files) {4229  unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;4230  return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,4231                                    num_command_line_args, unsaved_files,4232                                    num_unsaved_files, Options);4233}4234 4235static CXErrorCode4236clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,4237                                const char *const *command_line_args,4238                                int num_command_line_args,4239                                ArrayRef<CXUnsavedFile> unsaved_files,4240                                unsigned options, CXTranslationUnit *out_TU) {4241  // Set up the initial return values.4242  if (out_TU)4243    *out_TU = nullptr;4244 4245  // Check arguments.4246  if (!CIdx || !out_TU)4247    return CXError_InvalidArguments;4248 4249  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);4250 4251  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))4252    setThreadBackgroundPriority();4253 4254  bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;4255  bool CreatePreambleOnFirstParse =4256      options & CXTranslationUnit_CreatePreambleOnFirstParse;4257  // FIXME: Add a flag for modules.4258  TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |4259                                           CXTranslationUnit_SingleFileParse))4260                                   ? TU_Prefix4261                                   : TU_Complete;4262  bool CacheCodeCompletionResults =4263      options & CXTranslationUnit_CacheCompletionResults;4264  bool IncludeBriefCommentsInCodeCompletion =4265      options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;4266  bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;4267  bool ForSerialization = options & CXTranslationUnit_ForSerialization;4268  bool RetainExcludedCB =4269      options & CXTranslationUnit_RetainExcludedConditionalBlocks;4270  SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;4271  if (options & CXTranslationUnit_SkipFunctionBodies) {4272    SkipFunctionBodies =4273        (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)4274            ? SkipFunctionBodiesScope::Preamble4275            : SkipFunctionBodiesScope::PreambleAndMainFile;4276  }4277 4278  // Configure the diagnostics.4279  std::shared_ptr<DiagnosticOptions> DiagOpts = CreateAndPopulateDiagOpts(4280      llvm::ArrayRef(command_line_args, num_command_line_args));4281  IntrusiveRefCntPtr<DiagnosticsEngine> Diags(4282      CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),4283                                          *DiagOpts));4284 4285  if (options & CXTranslationUnit_KeepGoing)4286    Diags->setFatalsAsError(true);4287 4288  CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;4289  if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)4290    CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;4291 4292  // Recover resources if we crash before exiting this function.4293  llvm::CrashRecoveryContextCleanupRegistrar<4294      DiagnosticsEngine,4295      llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>4296      DiagCleanup(Diags.get());4297 4298  std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(4299      new std::vector<ASTUnit::RemappedFile>());4300 4301  // Recover resources if we crash before exiting this function.4302  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>4303      RemappedCleanup(RemappedFiles.get());4304 4305  for (auto &UF : unsaved_files) {4306    std::unique_ptr<llvm::MemoryBuffer> MB =4307        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);4308    RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));4309  }4310 4311  std::unique_ptr<std::vector<const char *>> Args(4312      new std::vector<const char *>());4313 4314  // Recover resources if we crash before exiting this method.4315  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>4316      ArgsCleanup(Args.get());4317 4318  // Since the Clang C library is primarily used by batch tools dealing with4319  // (often very broken) source code, where spell-checking can have a4320  // significant negative impact on performance (particularly when4321  // precompiled headers are involved), we disable it by default.4322  // Only do this if we haven't found a spell-checking-related argument.4323  bool FoundSpellCheckingArgument = false;4324  for (int I = 0; I != num_command_line_args; ++I) {4325    if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||4326        strcmp(command_line_args[I], "-fspell-checking") == 0) {4327      FoundSpellCheckingArgument = true;4328      break;4329    }4330  }4331  Args->insert(Args->end(), command_line_args,4332               command_line_args + num_command_line_args);4333 4334  if (!FoundSpellCheckingArgument)4335    Args->insert(Args->begin() + 1, "-fno-spell-checking");4336 4337  // The 'source_filename' argument is optional.  If the caller does not4338  // specify it then it is assumed that the source file is specified4339  // in the actual argument list.4340  // Put the source file after command_line_args otherwise if '-x' flag is4341  // present it will be unused.4342  if (source_filename)4343    Args->push_back(source_filename);4344 4345  // Do we need the detailed preprocessing record?4346  if (options & CXTranslationUnit_DetailedPreprocessingRecord) {4347    Args->push_back("-Xclang");4348    Args->push_back("-detailed-preprocessing-record");4349  }4350 4351  // Suppress any editor placeholder diagnostics.4352  Args->push_back("-fallow-editor-placeholders");4353 4354  unsigned NumErrors = Diags->getClient()->getNumErrors();4355  std::unique_ptr<ASTUnit> ErrUnit;4356  // Unless the user specified that they want the preamble on the first parse4357  // set it up to be created on the first reparse. This makes the first parse4358  // faster, trading for a slower (first) reparse.4359  unsigned PrecompilePreambleAfterNParses =4360      !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;4361 4362  LibclangInvocationReporter InvocationReporter(4363      *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,4364      options, llvm::ArrayRef(*Args), /*InvocationArgs=*/{}, unsaved_files);4365  std::unique_ptr<ASTUnit> Unit = CreateASTUnitFromCommandLine(4366      Args->data(), Args->data() + Args->size(),4367      CXXIdx->getPCHContainerOperations(), DiagOpts, Diags,4368      CXXIdx->getClangResourcesPath(), CXXIdx->getStorePreamblesInMemory(),4369      CXXIdx->getPreambleStoragePath(), CXXIdx->getOnlyLocalDecls(),4370      CaptureDiagnostics, *RemappedFiles,4371      /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,4372      TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,4373      /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,4374      /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,4375      CXXIdx->getPCHContainerOperations()->getRawReader().getFormats().front(),4376      &ErrUnit);4377 4378  // Early failures in LoadFromCommandLine may return with ErrUnit unset.4379  if (!Unit && !ErrUnit)4380    return CXError_ASTReadError;4381 4382  if (NumErrors != Diags->getClient()->getNumErrors()) {4383    // Make sure to check that 'Unit' is non-NULL.4384    if (CXXIdx->getDisplayDiagnostics())4385      printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());4386  }4387 4388  if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))4389    return CXError_ASTReadError;4390 4391  *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));4392  if (CXTranslationUnitImpl *TU = *out_TU) {4393    TU->ParsingOptions = options;4394    TU->Arguments.reserve(Args->size());4395    for (const char *Arg : *Args)4396      TU->Arguments.push_back(Arg);4397    return CXError_Success;4398  }4399  return CXError_Failure;4400}4401 4402CXTranslationUnit4403clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,4404                           const char *const *command_line_args,4405                           int num_command_line_args,4406                           struct CXUnsavedFile *unsaved_files,4407                           unsigned num_unsaved_files, unsigned options) {4408  CXTranslationUnit TU;4409  enum CXErrorCode Result = clang_parseTranslationUnit2(4410      CIdx, source_filename, command_line_args, num_command_line_args,4411      unsaved_files, num_unsaved_files, options, &TU);4412  (void)Result;4413  assert((TU && Result == CXError_Success) ||4414         (!TU && Result != CXError_Success));4415  return TU;4416}4417 4418enum CXErrorCode clang_parseTranslationUnit2(4419    CXIndex CIdx, const char *source_filename,4420    const char *const *command_line_args, int num_command_line_args,4421    struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,4422    unsigned options, CXTranslationUnit *out_TU) {4423  noteBottomOfStack();4424  SmallVector<const char *, 4> Args;4425  Args.push_back("clang");4426  Args.append(command_line_args, command_line_args + num_command_line_args);4427  return clang_parseTranslationUnit2FullArgv(4428      CIdx, source_filename, Args.data(), Args.size(), unsaved_files,4429      num_unsaved_files, options, out_TU);4430}4431 4432enum CXErrorCode clang_parseTranslationUnit2FullArgv(4433    CXIndex CIdx, const char *source_filename,4434    const char *const *command_line_args, int num_command_line_args,4435    struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,4436    unsigned options, CXTranslationUnit *out_TU) {4437  LOG_FUNC_SECTION {4438    *Log << source_filename << ": ";4439    for (int i = 0; i != num_command_line_args; ++i)4440      *Log << command_line_args[i] << " ";4441  }4442 4443  if (num_unsaved_files && !unsaved_files)4444    return CXError_InvalidArguments;4445 4446  CXErrorCode result = CXError_Failure;4447  auto ParseTranslationUnitImpl = [=, &result] {4448    noteBottomOfStack();4449    result = clang_parseTranslationUnit_Impl(4450        CIdx, source_filename, command_line_args, num_command_line_args,4451        llvm::ArrayRef(unsaved_files, num_unsaved_files), options, out_TU);4452  };4453 4454  llvm::CrashRecoveryContext CRC;4455 4456  if (!RunSafely(CRC, ParseTranslationUnitImpl)) {4457    fprintf(stderr, "libclang: crash detected during parsing: {\n");4458    fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);4459    fprintf(stderr, "  'command_line_args' : [");4460    for (int i = 0; i != num_command_line_args; ++i) {4461      if (i)4462        fprintf(stderr, ", ");4463      fprintf(stderr, "'%s'", command_line_args[i]);4464    }4465    fprintf(stderr, "],\n");4466    fprintf(stderr, "  'unsaved_files' : [");4467    for (unsigned i = 0; i != num_unsaved_files; ++i) {4468      if (i)4469        fprintf(stderr, ", ");4470      fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,4471              unsaved_files[i].Length);4472    }4473    fprintf(stderr, "],\n");4474    fprintf(stderr, "  'options' : %d,\n", options);4475    fprintf(stderr, "}\n");4476 4477    return CXError_Crashed;4478  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {4479    if (CXTranslationUnit *TU = out_TU)4480      PrintLibclangResourceUsage(*TU);4481  }4482 4483  return result;4484}4485 4486CXString clang_Type_getObjCEncoding(CXType CT) {4487  CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);4488  ASTContext &Ctx = getASTUnit(tu)->getASTContext();4489  std::string encoding;4490  Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);4491 4492  return cxstring::createDup(encoding);4493}4494 4495static const IdentifierInfo *getMacroIdentifier(CXCursor C) {4496  if (C.kind == CXCursor_MacroDefinition) {4497    if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))4498      return MDR->getName();4499  } else if (C.kind == CXCursor_MacroExpansion) {4500    MacroExpansionCursor ME = getCursorMacroExpansion(C);4501    return ME.getName();4502  }4503  return nullptr;4504}4505 4506unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {4507  const IdentifierInfo *II = getMacroIdentifier(C);4508  if (!II) {4509    return false;4510  }4511  ASTUnit *ASTU = getCursorASTUnit(C);4512  Preprocessor &PP = ASTU->getPreprocessor();4513  if (const MacroInfo *MI = PP.getMacroInfo(II))4514    return MI->isFunctionLike();4515  return false;4516}4517 4518unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {4519  const IdentifierInfo *II = getMacroIdentifier(C);4520  if (!II) {4521    return false;4522  }4523  ASTUnit *ASTU = getCursorASTUnit(C);4524  Preprocessor &PP = ASTU->getPreprocessor();4525  if (const MacroInfo *MI = PP.getMacroInfo(II))4526    return MI->isBuiltinMacro();4527  return false;4528}4529 4530unsigned clang_Cursor_isFunctionInlined(CXCursor C) {4531  const Decl *D = getCursorDecl(C);4532  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);4533  if (!FD) {4534    return false;4535  }4536  return FD->isInlined();4537}4538 4539static StringLiteral *getCFSTR_value(CallExpr *callExpr) {4540  if (callExpr->getNumArgs() != 1) {4541    return nullptr;4542  }4543 4544  StringLiteral *S = nullptr;4545  auto *arg = callExpr->getArg(0);4546  if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {4547    ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);4548    auto *subExpr = I->getSubExprAsWritten();4549 4550    if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {4551      return nullptr;4552    }4553 4554    S = static_cast<StringLiteral *>(I->getSubExprAsWritten());4555  } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {4556    S = static_cast<StringLiteral *>(callExpr->getArg(0));4557  } else {4558    return nullptr;4559  }4560  return S;4561}4562 4563struct ExprEvalResult {4564  CXEvalResultKind EvalType;4565  union {4566    unsigned long long unsignedVal;4567    long long intVal;4568    double floatVal;4569    char *stringVal;4570  } EvalData;4571  bool IsUnsignedInt;4572  ~ExprEvalResult() {4573    if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&4574        EvalType != CXEval_Int) {4575      delete[] EvalData.stringVal;4576    }4577  }4578};4579 4580void clang_EvalResult_dispose(CXEvalResult E) {4581  delete static_cast<ExprEvalResult *>(E);4582}4583 4584CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {4585  if (!E) {4586    return CXEval_UnExposed;4587  }4588  return ((ExprEvalResult *)E)->EvalType;4589}4590 4591int clang_EvalResult_getAsInt(CXEvalResult E) {4592  return clang_EvalResult_getAsLongLong(E);4593}4594 4595long long clang_EvalResult_getAsLongLong(CXEvalResult E) {4596  if (!E) {4597    return 0;4598  }4599  ExprEvalResult *Result = (ExprEvalResult *)E;4600  if (Result->IsUnsignedInt)4601    return Result->EvalData.unsignedVal;4602  return Result->EvalData.intVal;4603}4604 4605unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {4606  return ((ExprEvalResult *)E)->IsUnsignedInt;4607}4608 4609unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {4610  if (!E) {4611    return 0;4612  }4613 4614  ExprEvalResult *Result = (ExprEvalResult *)E;4615  if (Result->IsUnsignedInt)4616    return Result->EvalData.unsignedVal;4617  return Result->EvalData.intVal;4618}4619 4620double clang_EvalResult_getAsDouble(CXEvalResult E) {4621  if (!E) {4622    return 0;4623  }4624  return ((ExprEvalResult *)E)->EvalData.floatVal;4625}4626 4627const char *clang_EvalResult_getAsStr(CXEvalResult E) {4628  if (!E) {4629    return nullptr;4630  }4631  return ((ExprEvalResult *)E)->EvalData.stringVal;4632}4633 4634static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {4635  Expr::EvalResult ER;4636  ASTContext &ctx = getCursorContext(C);4637  if (!expr)4638    return nullptr;4639 4640  expr = expr->IgnoreParens();4641  if (expr->isValueDependent())4642    return nullptr;4643  if (!expr->EvaluateAsRValue(ER, ctx))4644    return nullptr;4645 4646  QualType rettype;4647  CallExpr *callExpr;4648  auto result = std::make_unique<ExprEvalResult>();4649  result->EvalType = CXEval_UnExposed;4650  result->IsUnsignedInt = false;4651 4652  if (ER.Val.isInt()) {4653    result->EvalType = CXEval_Int;4654 4655    auto &val = ER.Val.getInt();4656    if (val.isUnsigned()) {4657      result->IsUnsignedInt = true;4658      result->EvalData.unsignedVal = val.getZExtValue();4659    } else {4660      result->EvalData.intVal = val.getExtValue();4661    }4662 4663    return result.release();4664  }4665 4666  if (ER.Val.isFloat()) {4667    llvm::SmallVector<char, 100> Buffer;4668    ER.Val.getFloat().toString(Buffer);4669    result->EvalType = CXEval_Float;4670    bool ignored;4671    llvm::APFloat apFloat = ER.Val.getFloat();4672    apFloat.convert(llvm::APFloat::IEEEdouble(),4673                    llvm::APFloat::rmNearestTiesToEven, &ignored);4674    result->EvalData.floatVal = apFloat.convertToDouble();4675    return result.release();4676  }4677 4678  if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {4679    const auto *I = cast<ImplicitCastExpr>(expr);4680    auto *subExpr = I->getSubExprAsWritten();4681    if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||4682        subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {4683      const StringLiteral *StrE = nullptr;4684      const ObjCStringLiteral *ObjCExpr;4685      ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);4686 4687      if (ObjCExpr) {4688        StrE = ObjCExpr->getString();4689        result->EvalType = CXEval_ObjCStrLiteral;4690      } else {4691        StrE = cast<StringLiteral>(I->getSubExprAsWritten());4692        result->EvalType = CXEval_StrLiteral;4693      }4694 4695      std::string strRef(StrE->getString().str());4696      result->EvalData.stringVal = new char[strRef.size() + 1];4697      strncpy(result->EvalData.stringVal, strRef.c_str(), strRef.size());4698      result->EvalData.stringVal[strRef.size()] = '\0';4699      return result.release();4700    }4701  } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||4702             expr->getStmtClass() == Stmt::StringLiteralClass) {4703    const StringLiteral *StrE = nullptr;4704    const ObjCStringLiteral *ObjCExpr;4705    ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);4706 4707    if (ObjCExpr) {4708      StrE = ObjCExpr->getString();4709      result->EvalType = CXEval_ObjCStrLiteral;4710    } else {4711      StrE = cast<StringLiteral>(expr);4712      result->EvalType = CXEval_StrLiteral;4713    }4714 4715    std::string strRef(StrE->getString().str());4716    result->EvalData.stringVal = new char[strRef.size() + 1];4717    strncpy(result->EvalData.stringVal, strRef.c_str(), strRef.size());4718    result->EvalData.stringVal[strRef.size()] = '\0';4719    return result.release();4720  }4721 4722  if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {4723    CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);4724 4725    rettype = CC->getType();4726    if (rettype.getAsString() == "CFStringRef" &&4727        CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {4728 4729      callExpr = static_cast<CallExpr *>(CC->getSubExpr());4730      StringLiteral *S = getCFSTR_value(callExpr);4731      if (S) {4732        std::string strLiteral(S->getString().str());4733        result->EvalType = CXEval_CFStr;4734 4735        result->EvalData.stringVal = new char[strLiteral.size() + 1];4736        strncpy(result->EvalData.stringVal, strLiteral.c_str(),4737                strLiteral.size());4738        result->EvalData.stringVal[strLiteral.size()] = '\0';4739        return result.release();4740      }4741    }4742 4743  } else if (expr->getStmtClass() == Stmt::CallExprClass) {4744    callExpr = static_cast<CallExpr *>(expr);4745    rettype = callExpr->getCallReturnType(ctx);4746 4747    if (rettype->isVectorType() || callExpr->getNumArgs() > 1)4748      return nullptr;4749 4750    if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {4751      if (callExpr->getNumArgs() == 1 &&4752          !callExpr->getArg(0)->getType()->isIntegralType(ctx))4753        return nullptr;4754    } else if (rettype.getAsString() == "CFStringRef") {4755 4756      StringLiteral *S = getCFSTR_value(callExpr);4757      if (S) {4758        std::string strLiteral(S->getString().str());4759        result->EvalType = CXEval_CFStr;4760        result->EvalData.stringVal = new char[strLiteral.size() + 1];4761        strncpy(result->EvalData.stringVal, strLiteral.c_str(),4762                strLiteral.size());4763        result->EvalData.stringVal[strLiteral.size()] = '\0';4764        return result.release();4765      }4766    }4767  } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {4768    DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);4769    ValueDecl *V = D->getDecl();4770    if (V->getKind() == Decl::Function) {4771      std::string strName = V->getNameAsString();4772      result->EvalType = CXEval_Other;4773      result->EvalData.stringVal = new char[strName.size() + 1];4774      strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());4775      result->EvalData.stringVal[strName.size()] = '\0';4776      return result.release();4777    }4778  }4779 4780  return nullptr;4781}4782 4783static const Expr *evaluateDeclExpr(const Decl *D) {4784  if (!D)4785    return nullptr;4786  if (auto *Var = dyn_cast<VarDecl>(D))4787    return Var->getInit();4788  else if (auto *Field = dyn_cast<FieldDecl>(D))4789    return Field->getInClassInitializer();4790  return nullptr;4791}4792 4793static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {4794  assert(CS && "invalid compound statement");4795  for (auto *bodyIterator : CS->body()) {4796    if (const auto *E = dyn_cast<Expr>(bodyIterator))4797      return E;4798  }4799  return nullptr;4800}4801 4802CXEvalResult clang_Cursor_Evaluate(CXCursor C) {4803  const Expr *E = nullptr;4804  if (clang_getCursorKind(C) == CXCursor_CompoundStmt)4805    E = evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)));4806  else if (clang_isDeclaration(C.kind))4807    E = evaluateDeclExpr(getCursorDecl(C));4808  else if (clang_isExpression(C.kind))4809    E = getCursorExpr(C);4810  if (E)4811    return const_cast<CXEvalResult>(4812        reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));4813  return nullptr;4814}4815 4816unsigned clang_Cursor_hasAttrs(CXCursor C) {4817  const Decl *D = getCursorDecl(C);4818  if (!D) {4819    return 0;4820  }4821 4822  if (D->hasAttrs()) {4823    return 1;4824  }4825 4826  return 0;4827}4828unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {4829  return CXSaveTranslationUnit_None;4830}4831 4832static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,4833                                                  const char *FileName,4834                                                  unsigned options) {4835  CIndexer *CXXIdx = TU->CIdx;4836  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))4837    setThreadBackgroundPriority();4838 4839  bool hadError = cxtu::getASTUnit(TU)->Save(FileName);4840  return hadError ? CXSaveError_Unknown : CXSaveError_None;4841}4842 4843int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,4844                              unsigned options) {4845  LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }4846 4847  if (isNotUsableTU(TU)) {4848    LOG_BAD_TU(TU);4849    return CXSaveError_InvalidTU;4850  }4851 4852  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);4853  ASTUnit::ConcurrencyCheck Check(*CXXUnit);4854  if (!CXXUnit->hasSema())4855    return CXSaveError_InvalidTU;4856 4857  CXSaveError result;4858  auto SaveTranslationUnitImpl = [=, &result]() {4859    result = clang_saveTranslationUnit_Impl(TU, FileName, options);4860  };4861 4862  if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {4863    SaveTranslationUnitImpl();4864 4865    if (getenv("LIBCLANG_RESOURCE_USAGE"))4866      PrintLibclangResourceUsage(TU);4867 4868    return result;4869  }4870 4871  // We have an AST that has invalid nodes due to compiler errors.4872  // Use a crash recovery thread for protection.4873 4874  llvm::CrashRecoveryContext CRC;4875 4876  if (!RunSafely(CRC, SaveTranslationUnitImpl)) {4877    fprintf(stderr, "libclang: crash detected during AST saving: {\n");4878    fprintf(stderr, "  'filename' : '%s'\n", FileName);4879    fprintf(stderr, "  'options' : %d,\n", options);4880    fprintf(stderr, "}\n");4881 4882    return CXSaveError_Unknown;4883 4884  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {4885    PrintLibclangResourceUsage(TU);4886  }4887 4888  return result;4889}4890 4891void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {4892  if (CTUnit) {4893    // If the translation unit has been marked as unsafe to free, just discard4894    // it.4895    ASTUnit *Unit = cxtu::getASTUnit(CTUnit);4896    if (Unit && Unit->isUnsafeToFree())4897      return;4898 4899    delete cxtu::getASTUnit(CTUnit);4900    delete CTUnit->StringPool;4901    delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);4902    disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);4903    delete CTUnit->CommentToXML;4904    delete CTUnit;4905  }4906}4907 4908unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {4909  if (CTUnit) {4910    ASTUnit *Unit = cxtu::getASTUnit(CTUnit);4911 4912    if (Unit && Unit->isUnsafeToFree())4913      return false;4914 4915    Unit->ResetForParse();4916    return true;4917  }4918 4919  return false;4920}4921 4922unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {4923  return CXReparse_None;4924}4925 4926static CXErrorCode4927clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,4928                                  ArrayRef<CXUnsavedFile> unsaved_files,4929                                  unsigned options) {4930  // Check arguments.4931  if (isNotUsableTU(TU)) {4932    LOG_BAD_TU(TU);4933    return CXError_InvalidArguments;4934  }4935 4936  // Reset the associated diagnostics.4937  delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);4938  TU->Diagnostics = nullptr;4939 4940  CIndexer *CXXIdx = TU->CIdx;4941  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))4942    setThreadBackgroundPriority();4943 4944  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);4945  ASTUnit::ConcurrencyCheck Check(*CXXUnit);4946 4947  std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(4948      new std::vector<ASTUnit::RemappedFile>());4949 4950  // Recover resources if we crash before exiting this function.4951  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>4952      RemappedCleanup(RemappedFiles.get());4953 4954  for (auto &UF : unsaved_files) {4955    std::unique_ptr<llvm::MemoryBuffer> MB =4956        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);4957    RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));4958  }4959 4960  if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(), *RemappedFiles))4961    return CXError_Success;4962  if (isASTReadError(CXXUnit))4963    return CXError_ASTReadError;4964  return CXError_Failure;4965}4966 4967int clang_reparseTranslationUnit(CXTranslationUnit TU,4968                                 unsigned num_unsaved_files,4969                                 struct CXUnsavedFile *unsaved_files,4970                                 unsigned options) {4971  LOG_FUNC_SECTION { *Log << TU; }4972 4973  if (num_unsaved_files && !unsaved_files)4974    return CXError_InvalidArguments;4975 4976  CXErrorCode result;4977  auto ReparseTranslationUnitImpl = [=, &result]() {4978    result = clang_reparseTranslationUnit_Impl(4979        TU, llvm::ArrayRef(unsaved_files, num_unsaved_files), options);4980  };4981 4982  llvm::CrashRecoveryContext CRC;4983 4984  if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {4985    fprintf(stderr, "libclang: crash detected during reparsing\n");4986    cxtu::getASTUnit(TU)->setUnsafeToFree(true);4987    return CXError_Crashed;4988  } else if (getenv("LIBCLANG_RESOURCE_USAGE"))4989    PrintLibclangResourceUsage(TU);4990 4991  return result;4992}4993 4994CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {4995  if (isNotUsableTU(CTUnit)) {4996    LOG_BAD_TU(CTUnit);4997    return cxstring::createEmpty();4998  }4999 5000  ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);5001  return cxstring::createDup(CXXUnit->getOriginalSourceFileName());5002}5003 5004CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {5005  if (isNotUsableTU(TU)) {5006    LOG_BAD_TU(TU);5007    return clang_getNullCursor();5008  }5009 5010  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);5011  return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);5012}5013 5014CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {5015  if (isNotUsableTU(CTUnit)) {5016    LOG_BAD_TU(CTUnit);5017    return nullptr;5018  }5019 5020  CXTargetInfoImpl *impl = new CXTargetInfoImpl();5021  impl->TranslationUnit = CTUnit;5022  return impl;5023}5024 5025CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {5026  if (!TargetInfo)5027    return cxstring::createEmpty();5028 5029  CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;5030  assert(!isNotUsableTU(CTUnit) &&5031         "Unexpected unusable translation unit in TargetInfo");5032 5033  ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);5034  std::string Triple =5035      CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();5036  return cxstring::createDup(Triple);5037}5038 5039int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {5040  if (!TargetInfo)5041    return -1;5042 5043  CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;5044  assert(!isNotUsableTU(CTUnit) &&5045         "Unexpected unusable translation unit in TargetInfo");5046 5047  ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);5048  return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();5049}5050 5051void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {5052  if (!TargetInfo)5053    return;5054 5055  delete TargetInfo;5056}5057 5058//===----------------------------------------------------------------------===//5059// CXFile Operations.5060//===----------------------------------------------------------------------===//5061 5062CXString clang_getFileName(CXFile SFile) {5063  if (!SFile)5064    return cxstring::createNull();5065 5066  FileEntryRef FEnt = *cxfile::getFileEntryRef(SFile);5067  return cxstring::createRef(FEnt.getName());5068}5069 5070time_t clang_getFileTime(CXFile SFile) {5071  if (!SFile)5072    return 0;5073 5074  FileEntryRef FEnt = *cxfile::getFileEntryRef(SFile);5075  return FEnt.getModificationTime();5076}5077 5078CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {5079  if (isNotUsableTU(TU)) {5080    LOG_BAD_TU(TU);5081    return nullptr;5082  }5083 5084  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);5085 5086  FileManager &FMgr = CXXUnit->getFileManager();5087  return cxfile::makeCXFile(FMgr.getOptionalFileRef(file_name));5088}5089 5090const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,5091                                  size_t *size) {5092  if (isNotUsableTU(TU)) {5093    LOG_BAD_TU(TU);5094    return nullptr;5095  }5096 5097  const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();5098  FileID fid = SM.translateFile(*cxfile::getFileEntryRef(file));5099  std::optional<llvm::MemoryBufferRef> buf = SM.getBufferOrNone(fid);5100  if (!buf) {5101    if (size)5102      *size = 0;5103    return nullptr;5104  }5105  if (size)5106    *size = buf->getBufferSize();5107  return buf->getBufferStart();5108}5109 5110unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {5111  if (isNotUsableTU(TU)) {5112    LOG_BAD_TU(TU);5113    return 0;5114  }5115 5116  if (!file)5117    return 0;5118 5119  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);5120  FileEntryRef FEnt = *cxfile::getFileEntryRef(file);5121  return CXXUnit->getPreprocessor()5122      .getHeaderSearchInfo()5123      .isFileMultipleIncludeGuarded(FEnt);5124}5125 5126int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {5127  if (!file || !outID)5128    return 1;5129 5130  FileEntryRef FEnt = *cxfile::getFileEntryRef(file);5131  const llvm::sys::fs::UniqueID &ID = FEnt.getUniqueID();5132  outID->data[0] = ID.getDevice();5133  outID->data[1] = ID.getFile();5134  outID->data[2] = FEnt.getModificationTime();5135  return 0;5136}5137 5138int clang_File_isEqual(CXFile file1, CXFile file2) {5139  if (file1 == file2)5140    return true;5141 5142  if (!file1 || !file2)5143    return false;5144 5145  FileEntryRef FEnt1 = *cxfile::getFileEntryRef(file1);5146  FileEntryRef FEnt2 = *cxfile::getFileEntryRef(file2);5147  return FEnt1 == FEnt2;5148}5149 5150CXString clang_File_tryGetRealPathName(CXFile SFile) {5151  if (!SFile)5152    return cxstring::createNull();5153 5154  FileEntryRef FEnt = *cxfile::getFileEntryRef(SFile);5155  return cxstring::createRef(FEnt.getFileEntry().tryGetRealPathName());5156}5157 5158//===----------------------------------------------------------------------===//5159// CXCursor Operations.5160//===----------------------------------------------------------------------===//5161 5162static const Decl *getDeclFromExpr(const Stmt *E) {5163  if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))5164    return getDeclFromExpr(CE->getSubExpr());5165 5166  if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))5167    return RefExpr->getDecl();5168  if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))5169    return ME->getMemberDecl();5170  if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))5171    return RE->getDecl();5172  if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {5173    if (PRE->isExplicitProperty())5174      return PRE->getExplicitProperty();5175    // It could be messaging both getter and setter as in:5176    // ++myobj.myprop;5177    // in which case prefer to associate the setter since it is less obvious5178    // from inspecting the source that the setter is going to get called.5179    if (PRE->isMessagingSetter())5180      return PRE->getImplicitPropertySetter();5181    return PRE->getImplicitPropertyGetter();5182  }5183  if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))5184    return getDeclFromExpr(POE->getSyntacticForm());5185  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))5186    if (Expr *Src = OVE->getSourceExpr())5187      return getDeclFromExpr(Src);5188 5189  if (const CallExpr *CE = dyn_cast<CallExpr>(E))5190    return getDeclFromExpr(CE->getCallee());5191  if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))5192    if (!CE->isElidable())5193      return CE->getConstructor();5194  if (const CXXInheritedCtorInitExpr *CE =5195          dyn_cast<CXXInheritedCtorInitExpr>(E))5196    return CE->getConstructor();5197  if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))5198    return OME->getMethodDecl();5199 5200  if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))5201    return PE->getProtocol();5202  if (const SubstNonTypeTemplateParmPackExpr *NTTP =5203          dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))5204    return NTTP->getParameterPack();5205  if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))5206    if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||5207        isa<ParmVarDecl>(SizeOfPack->getPack()))5208      return SizeOfPack->getPack();5209 5210  return nullptr;5211}5212 5213static SourceLocation getLocationFromExpr(const Expr *E) {5214  if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))5215    return getLocationFromExpr(CE->getSubExpr());5216 5217  if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))5218    return /*FIXME:*/ Msg->getLeftLoc();5219  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))5220    return DRE->getLocation();5221  if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))5222    return Member->getMemberLoc();5223  if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))5224    return Ivar->getLocation();5225  if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))5226    return SizeOfPack->getPackLoc();5227  if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))5228    return PropRef->getLocation();5229 5230  return E->getBeginLoc();5231}5232 5233extern "C" {5234 5235unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,5236                             CXClientData client_data) {5237  CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,5238                          /*VisitPreprocessorLast=*/false);5239  return CursorVis.VisitChildren(parent);5240}5241 5242#ifndef __has_feature5243#define __has_feature(x) 05244#endif5245#if __has_feature(blocks)5246typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,5247                                                        CXCursor parent);5248 5249static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,5250                                              CXClientData client_data) {5251  CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;5252  return block(cursor, parent);5253}5254#else5255// If we are compiled with a compiler that doesn't have native blocks support,5256// define and call the block manually, so the5257typedef struct _CXChildVisitResult {5258  void *isa;5259  int flags;5260  int reserved;5261  enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,5262                                    CXCursor);5263} * CXCursorVisitorBlock;5264 5265static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,5266                                              CXClientData client_data) {5267  CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;5268  return block->invoke(block, cursor, parent);5269}5270#endif5271 5272unsigned clang_visitChildrenWithBlock(CXCursor parent,5273                                      CXCursorVisitorBlock block) {5274  return clang_visitChildren(parent, visitWithBlock, block);5275}5276 5277static CXString getDeclSpelling(const Decl *D) {5278  if (!D)5279    return cxstring::createEmpty();5280 5281  const NamedDecl *ND = dyn_cast<NamedDecl>(D);5282  if (!ND) {5283    if (const ObjCPropertyImplDecl *PropImpl =5284            dyn_cast<ObjCPropertyImplDecl>(D))5285      if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())5286        return cxstring::createDup(Property->getIdentifier()->getName());5287 5288    if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))5289      if (Module *Mod = ImportD->getImportedModule())5290        return cxstring::createDup(Mod->getFullModuleName());5291 5292    return cxstring::createEmpty();5293  }5294 5295  if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))5296    return cxstring::createDup(OMD->getSelector().getAsString());5297 5298  if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))5299    // No, this isn't the same as the code below. getIdentifier() is non-virtual5300    // and returns different names. NamedDecl returns the class name and5301    // ObjCCategoryImplDecl returns the category name.5302    return cxstring::createRef(CIMP->getIdentifier()->getNameStart());5303 5304  if (isa<UsingDirectiveDecl>(D))5305    return cxstring::createEmpty();5306 5307  SmallString<1024> S;5308  llvm::raw_svector_ostream os(S);5309  ND->printName(os);5310 5311  return cxstring::createDup(os.str());5312}5313 5314CXString clang_getCursorSpelling(CXCursor C) {5315  if (clang_isTranslationUnit(C.kind))5316    return clang_getTranslationUnitSpelling(getCursorTU(C));5317 5318  if (clang_isReference(C.kind)) {5319    switch (C.kind) {5320    case CXCursor_ObjCSuperClassRef: {5321      const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;5322      return cxstring::createRef(Super->getIdentifier()->getNameStart());5323    }5324    case CXCursor_ObjCClassRef: {5325      const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;5326      return cxstring::createRef(Class->getIdentifier()->getNameStart());5327    }5328    case CXCursor_ObjCProtocolRef: {5329      const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;5330      assert(OID && "getCursorSpelling(): Missing protocol decl");5331      return cxstring::createRef(OID->getIdentifier()->getNameStart());5332    }5333    case CXCursor_CXXBaseSpecifier: {5334      const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);5335      return cxstring::createDup(B->getType().getAsString());5336    }5337    case CXCursor_TypeRef: {5338      const TypeDecl *Type = getCursorTypeRef(C).first;5339      assert(Type && "Missing type decl");5340      const ASTContext &Ctx = getCursorContext(C);5341      QualType T = Ctx.getTypeDeclType(Type);5342 5343      PrintingPolicy Policy = Ctx.getPrintingPolicy();5344      Policy.FullyQualifiedName = true;5345      Policy.SuppressTagKeyword = false;5346      return cxstring::createDup(T.getAsString(Policy));5347    }5348    case CXCursor_TemplateRef: {5349      const TemplateDecl *Template = getCursorTemplateRef(C).first;5350      assert(Template && "Missing template decl");5351 5352      return cxstring::createDup(Template->getNameAsString());5353    }5354 5355    case CXCursor_NamespaceRef: {5356      const NamedDecl *NS = getCursorNamespaceRef(C).first;5357      assert(NS && "Missing namespace decl");5358 5359      return cxstring::createDup(NS->getNameAsString());5360    }5361 5362    case CXCursor_MemberRef: {5363      const FieldDecl *Field = getCursorMemberRef(C).first;5364      assert(Field && "Missing member decl");5365 5366      return cxstring::createDup(Field->getNameAsString());5367    }5368 5369    case CXCursor_LabelRef: {5370      const LabelStmt *Label = getCursorLabelRef(C).first;5371      assert(Label && "Missing label");5372 5373      return cxstring::createRef(Label->getName());5374    }5375 5376    case CXCursor_OverloadedDeclRef: {5377      OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;5378      if (const Decl *D = dyn_cast<const Decl *>(Storage)) {5379        if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))5380          return cxstring::createDup(ND->getNameAsString());5381        return cxstring::createEmpty();5382      }5383      if (const OverloadExpr *E = dyn_cast<const OverloadExpr *>(Storage))5384        return cxstring::createDup(E->getName().getAsString());5385      OverloadedTemplateStorage *Ovl =5386          cast<OverloadedTemplateStorage *>(Storage);5387      if (Ovl->size() == 0)5388        return cxstring::createEmpty();5389      return cxstring::createDup((*Ovl->begin())->getNameAsString());5390    }5391 5392    case CXCursor_VariableRef: {5393      const VarDecl *Var = getCursorVariableRef(C).first;5394      assert(Var && "Missing variable decl");5395 5396      return cxstring::createDup(Var->getNameAsString());5397    }5398 5399    default:5400      return cxstring::createRef("<not implemented>");5401    }5402  }5403 5404  if (clang_isExpression(C.kind)) {5405    const Expr *E = getCursorExpr(C);5406 5407    if (C.kind == CXCursor_ObjCStringLiteral ||5408        C.kind == CXCursor_StringLiteral) {5409      const StringLiteral *SLit;5410      if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {5411        SLit = OSL->getString();5412      } else {5413        SLit = cast<StringLiteral>(E);5414      }5415      SmallString<256> Buf;5416      llvm::raw_svector_ostream OS(Buf);5417      SLit->outputString(OS);5418      return cxstring::createDup(OS.str());5419    }5420 5421    if (C.kind == CXCursor_BinaryOperator ||5422        C.kind == CXCursor_CompoundAssignOperator) {5423      return clang_getBinaryOperatorKindSpelling(5424          clang_getCursorBinaryOperatorKind(C));5425    }5426 5427    const Decl *D = getDeclFromExpr(getCursorExpr(C));5428    if (D)5429      return getDeclSpelling(D);5430    return cxstring::createEmpty();5431  }5432 5433  if (clang_isStatement(C.kind)) {5434    const Stmt *S = getCursorStmt(C);5435    if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))5436      return cxstring::createRef(Label->getName());5437 5438    return cxstring::createEmpty();5439  }5440 5441  if (C.kind == CXCursor_MacroExpansion)5442    return cxstring::createRef(5443        getCursorMacroExpansion(C).getName()->getNameStart());5444 5445  if (C.kind == CXCursor_MacroDefinition)5446    return cxstring::createRef(5447        getCursorMacroDefinition(C)->getName()->getNameStart());5448 5449  if (C.kind == CXCursor_InclusionDirective)5450    return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());5451 5452  if (clang_isDeclaration(C.kind))5453    return getDeclSpelling(getCursorDecl(C));5454 5455  if (C.kind == CXCursor_AnnotateAttr) {5456    const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));5457    return cxstring::createDup(AA->getAnnotation());5458  }5459 5460  if (C.kind == CXCursor_AsmLabelAttr) {5461    const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));5462    return cxstring::createDup(AA->getLabel());5463  }5464 5465  if (C.kind == CXCursor_PackedAttr) {5466    return cxstring::createRef("packed");5467  }5468 5469  if (C.kind == CXCursor_VisibilityAttr) {5470    const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));5471    switch (AA->getVisibility()) {5472    case VisibilityAttr::VisibilityType::Default:5473      return cxstring::createRef("default");5474    case VisibilityAttr::VisibilityType::Hidden:5475      return cxstring::createRef("hidden");5476    case VisibilityAttr::VisibilityType::Protected:5477      return cxstring::createRef("protected");5478    }5479    llvm_unreachable("unknown visibility type");5480  }5481 5482  return cxstring::createEmpty();5483}5484 5485CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,5486                                                unsigned options) {5487  if (clang_Cursor_isNull(C))5488    return clang_getNullRange();5489 5490  ASTContext &Ctx = getCursorContext(C);5491 5492  if (clang_isStatement(C.kind)) {5493    const Stmt *S = getCursorStmt(C);5494    if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {5495      if (pieceIndex > 0)5496        return clang_getNullRange();5497      return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());5498    }5499 5500    return clang_getNullRange();5501  }5502 5503  if (C.kind == CXCursor_ObjCMessageExpr) {5504    if (const ObjCMessageExpr *ME =5505            dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {5506      if (pieceIndex >= ME->getNumSelectorLocs())5507        return clang_getNullRange();5508      return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));5509    }5510  }5511 5512  if (C.kind == CXCursor_ObjCInstanceMethodDecl ||5513      C.kind == CXCursor_ObjCClassMethodDecl) {5514    if (const ObjCMethodDecl *MD =5515            dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {5516      if (pieceIndex >= MD->getNumSelectorLocs())5517        return clang_getNullRange();5518      return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));5519    }5520  }5521 5522  if (C.kind == CXCursor_ObjCCategoryDecl ||5523      C.kind == CXCursor_ObjCCategoryImplDecl) {5524    if (pieceIndex > 0)5525      return clang_getNullRange();5526    if (const ObjCCategoryDecl *CD =5527            dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))5528      return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());5529    if (const ObjCCategoryImplDecl *CID =5530            dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))5531      return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());5532  }5533 5534  if (C.kind == CXCursor_ModuleImportDecl) {5535    if (pieceIndex > 0)5536      return clang_getNullRange();5537    if (const ImportDecl *ImportD =5538            dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {5539      ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();5540      if (!Locs.empty())5541        return cxloc::translateSourceRange(5542            Ctx, SourceRange(Locs.front(), Locs.back()));5543    }5544    return clang_getNullRange();5545  }5546 5547  if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||5548      C.kind == CXCursor_ConversionFunction ||5549      C.kind == CXCursor_FunctionDecl) {5550    if (pieceIndex > 0)5551      return clang_getNullRange();5552    if (const FunctionDecl *FD =5553            dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {5554      DeclarationNameInfo FunctionName = FD->getNameInfo();5555      return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());5556    }5557    return clang_getNullRange();5558  }5559 5560  // FIXME: A CXCursor_InclusionDirective should give the location of the5561  // filename, but we don't keep track of this.5562 5563  // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation5564  // but we don't keep track of this.5565 5566  // FIXME: A CXCursor_AsmLabelAttr should give the location of the label5567  // but we don't keep track of this.5568 5569  // Default handling, give the location of the cursor.5570 5571  if (pieceIndex > 0)5572    return clang_getNullRange();5573 5574  CXSourceLocation CXLoc = clang_getCursorLocation(C);5575  SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);5576  return cxloc::translateSourceRange(Ctx, Loc);5577}5578 5579CXString clang_Cursor_getMangling(CXCursor C) {5580  if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))5581    return cxstring::createEmpty();5582 5583  // Mangling only works for functions and variables.5584  const Decl *D = getCursorDecl(C);5585  if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))5586    return cxstring::createEmpty();5587 5588  ASTContext &Ctx = D->getASTContext();5589  ASTNameGenerator ASTNameGen(Ctx);5590  return cxstring::createDup(ASTNameGen.getName(D));5591}5592 5593CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {5594  if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))5595    return nullptr;5596 5597  const Decl *D = getCursorDecl(C);5598  if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))5599    return nullptr;5600 5601  ASTContext &Ctx = D->getASTContext();5602  ASTNameGenerator ASTNameGen(Ctx);5603  std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);5604  return cxstring::createSet(Manglings);5605}5606 5607CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {5608  if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))5609    return nullptr;5610 5611  const Decl *D = getCursorDecl(C);5612  if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))5613    return nullptr;5614 5615  ASTContext &Ctx = D->getASTContext();5616  ASTNameGenerator ASTNameGen(Ctx);5617  std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);5618  return cxstring::createSet(Manglings);5619}5620 5621CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {5622  if (clang_Cursor_isNull(C))5623    return nullptr;5624  return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());5625}5626 5627void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {5628  if (Policy)5629    delete static_cast<PrintingPolicy *>(Policy);5630}5631 5632unsigned5633clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,5634                                 enum CXPrintingPolicyProperty Property) {5635  if (!Policy)5636    return 0;5637 5638  PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);5639  switch (Property) {5640  case CXPrintingPolicy_Indentation:5641    return P->Indentation;5642  case CXPrintingPolicy_SuppressSpecifiers:5643    return P->SuppressSpecifiers;5644  case CXPrintingPolicy_SuppressTagKeyword:5645    return P->SuppressTagKeyword;5646  case CXPrintingPolicy_IncludeTagDefinition:5647    return P->IncludeTagDefinition;5648  case CXPrintingPolicy_SuppressScope:5649    return P->SuppressScope;5650  case CXPrintingPolicy_SuppressUnwrittenScope:5651    return P->SuppressUnwrittenScope;5652  case CXPrintingPolicy_SuppressInitializers:5653    return P->SuppressInitializers;5654  case CXPrintingPolicy_ConstantArraySizeAsWritten:5655    return P->ConstantArraySizeAsWritten;5656  case CXPrintingPolicy_AnonymousTagLocations:5657    return P->AnonymousTagLocations;5658  case CXPrintingPolicy_SuppressStrongLifetime:5659    return P->SuppressStrongLifetime;5660  case CXPrintingPolicy_SuppressLifetimeQualifiers:5661    return P->SuppressLifetimeQualifiers;5662  case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:5663    return P->SuppressTemplateArgsInCXXConstructors;5664  case CXPrintingPolicy_Bool:5665    return P->Bool;5666  case CXPrintingPolicy_Restrict:5667    return P->Restrict;5668  case CXPrintingPolicy_Alignof:5669    return P->Alignof;5670  case CXPrintingPolicy_UnderscoreAlignof:5671    return P->UnderscoreAlignof;5672  case CXPrintingPolicy_UseVoidForZeroParams:5673    return P->UseVoidForZeroParams;5674  case CXPrintingPolicy_TerseOutput:5675    return P->TerseOutput;5676  case CXPrintingPolicy_PolishForDeclaration:5677    return P->PolishForDeclaration;5678  case CXPrintingPolicy_Half:5679    return P->Half;5680  case CXPrintingPolicy_MSWChar:5681    return P->MSWChar;5682  case CXPrintingPolicy_IncludeNewlines:5683    return P->IncludeNewlines;5684  case CXPrintingPolicy_MSVCFormatting:5685    return P->MSVCFormatting;5686  case CXPrintingPolicy_ConstantsAsWritten:5687    return P->ConstantsAsWritten;5688  case CXPrintingPolicy_SuppressImplicitBase:5689    return P->SuppressImplicitBase;5690  case CXPrintingPolicy_FullyQualifiedName:5691    return P->FullyQualifiedName;5692  }5693 5694  assert(false && "Invalid CXPrintingPolicyProperty");5695  return 0;5696}5697 5698void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,5699                                      enum CXPrintingPolicyProperty Property,5700                                      unsigned Value) {5701  if (!Policy)5702    return;5703 5704  PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);5705  switch (Property) {5706  case CXPrintingPolicy_Indentation:5707    P->Indentation = Value;5708    return;5709  case CXPrintingPolicy_SuppressSpecifiers:5710    P->SuppressSpecifiers = Value;5711    return;5712  case CXPrintingPolicy_SuppressTagKeyword:5713    P->SuppressTagKeyword = Value;5714    return;5715  case CXPrintingPolicy_IncludeTagDefinition:5716    P->IncludeTagDefinition = Value;5717    return;5718  case CXPrintingPolicy_SuppressScope:5719    P->SuppressScope = Value;5720    return;5721  case CXPrintingPolicy_SuppressUnwrittenScope:5722    P->SuppressUnwrittenScope = Value;5723    return;5724  case CXPrintingPolicy_SuppressInitializers:5725    P->SuppressInitializers = Value;5726    return;5727  case CXPrintingPolicy_ConstantArraySizeAsWritten:5728    P->ConstantArraySizeAsWritten = Value;5729    return;5730  case CXPrintingPolicy_AnonymousTagLocations:5731    P->AnonymousTagLocations = Value;5732    return;5733  case CXPrintingPolicy_SuppressStrongLifetime:5734    P->SuppressStrongLifetime = Value;5735    return;5736  case CXPrintingPolicy_SuppressLifetimeQualifiers:5737    P->SuppressLifetimeQualifiers = Value;5738    return;5739  case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:5740    P->SuppressTemplateArgsInCXXConstructors = Value;5741    return;5742  case CXPrintingPolicy_Bool:5743    P->Bool = Value;5744    return;5745  case CXPrintingPolicy_Restrict:5746    P->Restrict = Value;5747    return;5748  case CXPrintingPolicy_Alignof:5749    P->Alignof = Value;5750    return;5751  case CXPrintingPolicy_UnderscoreAlignof:5752    P->UnderscoreAlignof = Value;5753    return;5754  case CXPrintingPolicy_UseVoidForZeroParams:5755    P->UseVoidForZeroParams = Value;5756    return;5757  case CXPrintingPolicy_TerseOutput:5758    P->TerseOutput = Value;5759    return;5760  case CXPrintingPolicy_PolishForDeclaration:5761    P->PolishForDeclaration = Value;5762    return;5763  case CXPrintingPolicy_Half:5764    P->Half = Value;5765    return;5766  case CXPrintingPolicy_MSWChar:5767    P->MSWChar = Value;5768    return;5769  case CXPrintingPolicy_IncludeNewlines:5770    P->IncludeNewlines = Value;5771    return;5772  case CXPrintingPolicy_MSVCFormatting:5773    P->MSVCFormatting = Value;5774    return;5775  case CXPrintingPolicy_ConstantsAsWritten:5776    P->ConstantsAsWritten = Value;5777    return;5778  case CXPrintingPolicy_SuppressImplicitBase:5779    P->SuppressImplicitBase = Value;5780    return;5781  case CXPrintingPolicy_FullyQualifiedName:5782    P->FullyQualifiedName = Value;5783    return;5784  }5785 5786  assert(false && "Invalid CXPrintingPolicyProperty");5787}5788 5789CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {5790  if (clang_Cursor_isNull(C))5791    return cxstring::createEmpty();5792 5793  if (clang_isDeclaration(C.kind)) {5794    const Decl *D = getCursorDecl(C);5795    if (!D)5796      return cxstring::createEmpty();5797 5798    SmallString<128> Str;5799    llvm::raw_svector_ostream OS(Str);5800    PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);5801    D->print(OS, UserPolicy ? *UserPolicy5802                            : getCursorContext(C).getPrintingPolicy());5803 5804    return cxstring::createDup(OS.str());5805  }5806 5807  return cxstring::createEmpty();5808}5809 5810CXString clang_getCursorDisplayName(CXCursor C) {5811  if (!clang_isDeclaration(C.kind))5812    return clang_getCursorSpelling(C);5813 5814  const Decl *D = getCursorDecl(C);5815  if (!D)5816    return cxstring::createEmpty();5817 5818  PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();5819  if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))5820    D = FunTmpl->getTemplatedDecl();5821 5822  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {5823    SmallString<64> Str;5824    llvm::raw_svector_ostream OS(Str);5825    OS << *Function;5826    if (Function->getPrimaryTemplate())5827      OS << "<>";5828    OS << "(";5829    for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {5830      if (I)5831        OS << ", ";5832      OS << Function->getParamDecl(I)->getType().getAsString(Policy);5833    }5834 5835    if (Function->isVariadic()) {5836      if (Function->getNumParams())5837        OS << ", ";5838      OS << "...";5839    }5840    OS << ")";5841    return cxstring::createDup(OS.str());5842  }5843 5844  if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {5845    SmallString<64> Str;5846    llvm::raw_svector_ostream OS(Str);5847    OS << *ClassTemplate;5848    OS << "<";5849    TemplateParameterList *Params = ClassTemplate->getTemplateParameters();5850    for (unsigned I = 0, N = Params->size(); I != N; ++I) {5851      if (I)5852        OS << ", ";5853 5854      NamedDecl *Param = Params->getParam(I);5855      if (Param->getIdentifier()) {5856        OS << Param->getIdentifier()->getName();5857        continue;5858      }5859 5860      // There is no parameter name, which makes this tricky. Try to come up5861      // with something useful that isn't too long.5862      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))5863        if (const auto *TC = TTP->getTypeConstraint()) {5864          TC->getConceptNameInfo().printName(OS, Policy);5865          if (TC->hasExplicitTemplateArgs())5866            OS << "<...>";5867        } else5868          OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");5869      else if (NonTypeTemplateParmDecl *NTTP =5870                   dyn_cast<NonTypeTemplateParmDecl>(Param))5871        OS << NTTP->getType().getAsString(Policy);5872      else5873        OS << "template<...> class";5874    }5875 5876    OS << ">";5877    return cxstring::createDup(OS.str());5878  }5879 5880  if (const ClassTemplateSpecializationDecl *ClassSpec =5881          dyn_cast<ClassTemplateSpecializationDecl>(D)) {5882    SmallString<128> Str;5883    llvm::raw_svector_ostream OS(Str);5884    OS << *ClassSpec;5885    // If the template arguments were written explicitly, use them..5886    if (const auto *ArgsWritten = ClassSpec->getTemplateArgsAsWritten()) {5887      printTemplateArgumentList(5888          OS, ArgsWritten->arguments(), Policy,5889          ClassSpec->getSpecializedTemplate()->getTemplateParameters());5890    } else {5891      printTemplateArgumentList(5892          OS, ClassSpec->getTemplateArgs().asArray(), Policy,5893          ClassSpec->getSpecializedTemplate()->getTemplateParameters());5894    }5895    return cxstring::createDup(OS.str());5896  }5897 5898  return clang_getCursorSpelling(C);5899}5900 5901CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {5902  switch (Kind) {5903  case CXCursor_FunctionDecl:5904    return cxstring::createRef("FunctionDecl");5905  case CXCursor_TypedefDecl:5906    return cxstring::createRef("TypedefDecl");5907  case CXCursor_EnumDecl:5908    return cxstring::createRef("EnumDecl");5909  case CXCursor_EnumConstantDecl:5910    return cxstring::createRef("EnumConstantDecl");5911  case CXCursor_StructDecl:5912    return cxstring::createRef("StructDecl");5913  case CXCursor_UnionDecl:5914    return cxstring::createRef("UnionDecl");5915  case CXCursor_ClassDecl:5916    return cxstring::createRef("ClassDecl");5917  case CXCursor_FieldDecl:5918    return cxstring::createRef("FieldDecl");5919  case CXCursor_VarDecl:5920    return cxstring::createRef("VarDecl");5921  case CXCursor_ParmDecl:5922    return cxstring::createRef("ParmDecl");5923  case CXCursor_ObjCInterfaceDecl:5924    return cxstring::createRef("ObjCInterfaceDecl");5925  case CXCursor_ObjCCategoryDecl:5926    return cxstring::createRef("ObjCCategoryDecl");5927  case CXCursor_ObjCProtocolDecl:5928    return cxstring::createRef("ObjCProtocolDecl");5929  case CXCursor_ObjCPropertyDecl:5930    return cxstring::createRef("ObjCPropertyDecl");5931  case CXCursor_ObjCIvarDecl:5932    return cxstring::createRef("ObjCIvarDecl");5933  case CXCursor_ObjCInstanceMethodDecl:5934    return cxstring::createRef("ObjCInstanceMethodDecl");5935  case CXCursor_ObjCClassMethodDecl:5936    return cxstring::createRef("ObjCClassMethodDecl");5937  case CXCursor_ObjCImplementationDecl:5938    return cxstring::createRef("ObjCImplementationDecl");5939  case CXCursor_ObjCCategoryImplDecl:5940    return cxstring::createRef("ObjCCategoryImplDecl");5941  case CXCursor_CXXMethod:5942    return cxstring::createRef("CXXMethod");5943  case CXCursor_UnexposedDecl:5944    return cxstring::createRef("UnexposedDecl");5945  case CXCursor_ObjCSuperClassRef:5946    return cxstring::createRef("ObjCSuperClassRef");5947  case CXCursor_ObjCProtocolRef:5948    return cxstring::createRef("ObjCProtocolRef");5949  case CXCursor_ObjCClassRef:5950    return cxstring::createRef("ObjCClassRef");5951  case CXCursor_TypeRef:5952    return cxstring::createRef("TypeRef");5953  case CXCursor_TemplateRef:5954    return cxstring::createRef("TemplateRef");5955  case CXCursor_NamespaceRef:5956    return cxstring::createRef("NamespaceRef");5957  case CXCursor_MemberRef:5958    return cxstring::createRef("MemberRef");5959  case CXCursor_LabelRef:5960    return cxstring::createRef("LabelRef");5961  case CXCursor_OverloadedDeclRef:5962    return cxstring::createRef("OverloadedDeclRef");5963  case CXCursor_VariableRef:5964    return cxstring::createRef("VariableRef");5965  case CXCursor_IntegerLiteral:5966    return cxstring::createRef("IntegerLiteral");5967  case CXCursor_FixedPointLiteral:5968    return cxstring::createRef("FixedPointLiteral");5969  case CXCursor_FloatingLiteral:5970    return cxstring::createRef("FloatingLiteral");5971  case CXCursor_ImaginaryLiteral:5972    return cxstring::createRef("ImaginaryLiteral");5973  case CXCursor_StringLiteral:5974    return cxstring::createRef("StringLiteral");5975  case CXCursor_CharacterLiteral:5976    return cxstring::createRef("CharacterLiteral");5977  case CXCursor_ParenExpr:5978    return cxstring::createRef("ParenExpr");5979  case CXCursor_UnaryOperator:5980    return cxstring::createRef("UnaryOperator");5981  case CXCursor_ArraySubscriptExpr:5982    return cxstring::createRef("ArraySubscriptExpr");5983  case CXCursor_ArraySectionExpr:5984    return cxstring::createRef("ArraySectionExpr");5985  case CXCursor_OMPArrayShapingExpr:5986    return cxstring::createRef("OMPArrayShapingExpr");5987  case CXCursor_OMPIteratorExpr:5988    return cxstring::createRef("OMPIteratorExpr");5989  case CXCursor_BinaryOperator:5990    return cxstring::createRef("BinaryOperator");5991  case CXCursor_CompoundAssignOperator:5992    return cxstring::createRef("CompoundAssignOperator");5993  case CXCursor_ConditionalOperator:5994    return cxstring::createRef("ConditionalOperator");5995  case CXCursor_CStyleCastExpr:5996    return cxstring::createRef("CStyleCastExpr");5997  case CXCursor_CompoundLiteralExpr:5998    return cxstring::createRef("CompoundLiteralExpr");5999  case CXCursor_InitListExpr:6000    return cxstring::createRef("InitListExpr");6001  case CXCursor_AddrLabelExpr:6002    return cxstring::createRef("AddrLabelExpr");6003  case CXCursor_StmtExpr:6004    return cxstring::createRef("StmtExpr");6005  case CXCursor_GenericSelectionExpr:6006    return cxstring::createRef("GenericSelectionExpr");6007  case CXCursor_GNUNullExpr:6008    return cxstring::createRef("GNUNullExpr");6009  case CXCursor_CXXStaticCastExpr:6010    return cxstring::createRef("CXXStaticCastExpr");6011  case CXCursor_CXXDynamicCastExpr:6012    return cxstring::createRef("CXXDynamicCastExpr");6013  case CXCursor_CXXReinterpretCastExpr:6014    return cxstring::createRef("CXXReinterpretCastExpr");6015  case CXCursor_CXXConstCastExpr:6016    return cxstring::createRef("CXXConstCastExpr");6017  case CXCursor_CXXFunctionalCastExpr:6018    return cxstring::createRef("CXXFunctionalCastExpr");6019  case CXCursor_CXXAddrspaceCastExpr:6020    return cxstring::createRef("CXXAddrspaceCastExpr");6021  case CXCursor_CXXTypeidExpr:6022    return cxstring::createRef("CXXTypeidExpr");6023  case CXCursor_CXXBoolLiteralExpr:6024    return cxstring::createRef("CXXBoolLiteralExpr");6025  case CXCursor_CXXNullPtrLiteralExpr:6026    return cxstring::createRef("CXXNullPtrLiteralExpr");6027  case CXCursor_CXXThisExpr:6028    return cxstring::createRef("CXXThisExpr");6029  case CXCursor_CXXThrowExpr:6030    return cxstring::createRef("CXXThrowExpr");6031  case CXCursor_CXXNewExpr:6032    return cxstring::createRef("CXXNewExpr");6033  case CXCursor_CXXDeleteExpr:6034    return cxstring::createRef("CXXDeleteExpr");6035  case CXCursor_UnaryExpr:6036    return cxstring::createRef("UnaryExpr");6037  case CXCursor_ObjCStringLiteral:6038    return cxstring::createRef("ObjCStringLiteral");6039  case CXCursor_ObjCBoolLiteralExpr:6040    return cxstring::createRef("ObjCBoolLiteralExpr");6041  case CXCursor_ObjCAvailabilityCheckExpr:6042    return cxstring::createRef("ObjCAvailabilityCheckExpr");6043  case CXCursor_ObjCSelfExpr:6044    return cxstring::createRef("ObjCSelfExpr");6045  case CXCursor_ObjCEncodeExpr:6046    return cxstring::createRef("ObjCEncodeExpr");6047  case CXCursor_ObjCSelectorExpr:6048    return cxstring::createRef("ObjCSelectorExpr");6049  case CXCursor_ObjCProtocolExpr:6050    return cxstring::createRef("ObjCProtocolExpr");6051  case CXCursor_ObjCBridgedCastExpr:6052    return cxstring::createRef("ObjCBridgedCastExpr");6053  case CXCursor_BlockExpr:6054    return cxstring::createRef("BlockExpr");6055  case CXCursor_PackExpansionExpr:6056    return cxstring::createRef("PackExpansionExpr");6057  case CXCursor_SizeOfPackExpr:6058    return cxstring::createRef("SizeOfPackExpr");6059  case CXCursor_PackIndexingExpr:6060    return cxstring::createRef("PackIndexingExpr");6061  case CXCursor_LambdaExpr:6062    return cxstring::createRef("LambdaExpr");6063  case CXCursor_UnexposedExpr:6064    return cxstring::createRef("UnexposedExpr");6065  case CXCursor_DeclRefExpr:6066    return cxstring::createRef("DeclRefExpr");6067  case CXCursor_MemberRefExpr:6068    return cxstring::createRef("MemberRefExpr");6069  case CXCursor_CallExpr:6070    return cxstring::createRef("CallExpr");6071  case CXCursor_ObjCMessageExpr:6072    return cxstring::createRef("ObjCMessageExpr");6073  case CXCursor_BuiltinBitCastExpr:6074    return cxstring::createRef("BuiltinBitCastExpr");6075  case CXCursor_ConceptSpecializationExpr:6076    return cxstring::createRef("ConceptSpecializationExpr");6077  case CXCursor_RequiresExpr:6078    return cxstring::createRef("RequiresExpr");6079  case CXCursor_CXXParenListInitExpr:6080    return cxstring::createRef("CXXParenListInitExpr");6081  case CXCursor_UnexposedStmt:6082    return cxstring::createRef("UnexposedStmt");6083  case CXCursor_DeclStmt:6084    return cxstring::createRef("DeclStmt");6085  case CXCursor_LabelStmt:6086    return cxstring::createRef("LabelStmt");6087  case CXCursor_CompoundStmt:6088    return cxstring::createRef("CompoundStmt");6089  case CXCursor_CaseStmt:6090    return cxstring::createRef("CaseStmt");6091  case CXCursor_DefaultStmt:6092    return cxstring::createRef("DefaultStmt");6093  case CXCursor_IfStmt:6094    return cxstring::createRef("IfStmt");6095  case CXCursor_SwitchStmt:6096    return cxstring::createRef("SwitchStmt");6097  case CXCursor_WhileStmt:6098    return cxstring::createRef("WhileStmt");6099  case CXCursor_DoStmt:6100    return cxstring::createRef("DoStmt");6101  case CXCursor_ForStmt:6102    return cxstring::createRef("ForStmt");6103  case CXCursor_GotoStmt:6104    return cxstring::createRef("GotoStmt");6105  case CXCursor_IndirectGotoStmt:6106    return cxstring::createRef("IndirectGotoStmt");6107  case CXCursor_ContinueStmt:6108    return cxstring::createRef("ContinueStmt");6109  case CXCursor_BreakStmt:6110    return cxstring::createRef("BreakStmt");6111  case CXCursor_ReturnStmt:6112    return cxstring::createRef("ReturnStmt");6113  case CXCursor_GCCAsmStmt:6114    return cxstring::createRef("GCCAsmStmt");6115  case CXCursor_MSAsmStmt:6116    return cxstring::createRef("MSAsmStmt");6117  case CXCursor_ObjCAtTryStmt:6118    return cxstring::createRef("ObjCAtTryStmt");6119  case CXCursor_ObjCAtCatchStmt:6120    return cxstring::createRef("ObjCAtCatchStmt");6121  case CXCursor_ObjCAtFinallyStmt:6122    return cxstring::createRef("ObjCAtFinallyStmt");6123  case CXCursor_ObjCAtThrowStmt:6124    return cxstring::createRef("ObjCAtThrowStmt");6125  case CXCursor_ObjCAtSynchronizedStmt:6126    return cxstring::createRef("ObjCAtSynchronizedStmt");6127  case CXCursor_ObjCAutoreleasePoolStmt:6128    return cxstring::createRef("ObjCAutoreleasePoolStmt");6129  case CXCursor_ObjCForCollectionStmt:6130    return cxstring::createRef("ObjCForCollectionStmt");6131  case CXCursor_CXXCatchStmt:6132    return cxstring::createRef("CXXCatchStmt");6133  case CXCursor_CXXTryStmt:6134    return cxstring::createRef("CXXTryStmt");6135  case CXCursor_CXXForRangeStmt:6136    return cxstring::createRef("CXXForRangeStmt");6137  case CXCursor_SEHTryStmt:6138    return cxstring::createRef("SEHTryStmt");6139  case CXCursor_SEHExceptStmt:6140    return cxstring::createRef("SEHExceptStmt");6141  case CXCursor_SEHFinallyStmt:6142    return cxstring::createRef("SEHFinallyStmt");6143  case CXCursor_SEHLeaveStmt:6144    return cxstring::createRef("SEHLeaveStmt");6145  case CXCursor_NullStmt:6146    return cxstring::createRef("NullStmt");6147  case CXCursor_InvalidFile:6148    return cxstring::createRef("InvalidFile");6149  case CXCursor_InvalidCode:6150    return cxstring::createRef("InvalidCode");6151  case CXCursor_NoDeclFound:6152    return cxstring::createRef("NoDeclFound");6153  case CXCursor_NotImplemented:6154    return cxstring::createRef("NotImplemented");6155  case CXCursor_TranslationUnit:6156    return cxstring::createRef("TranslationUnit");6157  case CXCursor_UnexposedAttr:6158    return cxstring::createRef("UnexposedAttr");6159  case CXCursor_IBActionAttr:6160    return cxstring::createRef("attribute(ibaction)");6161  case CXCursor_IBOutletAttr:6162    return cxstring::createRef("attribute(iboutlet)");6163  case CXCursor_IBOutletCollectionAttr:6164    return cxstring::createRef("attribute(iboutletcollection)");6165  case CXCursor_CXXFinalAttr:6166    return cxstring::createRef("attribute(final)");6167  case CXCursor_CXXOverrideAttr:6168    return cxstring::createRef("attribute(override)");6169  case CXCursor_AnnotateAttr:6170    return cxstring::createRef("attribute(annotate)");6171  case CXCursor_AsmLabelAttr:6172    return cxstring::createRef("asm label");6173  case CXCursor_PackedAttr:6174    return cxstring::createRef("attribute(packed)");6175  case CXCursor_PureAttr:6176    return cxstring::createRef("attribute(pure)");6177  case CXCursor_ConstAttr:6178    return cxstring::createRef("attribute(const)");6179  case CXCursor_NoDuplicateAttr:6180    return cxstring::createRef("attribute(noduplicate)");6181  case CXCursor_CUDAConstantAttr:6182    return cxstring::createRef("attribute(constant)");6183  case CXCursor_CUDADeviceAttr:6184    return cxstring::createRef("attribute(device)");6185  case CXCursor_CUDAGlobalAttr:6186    return cxstring::createRef("attribute(global)");6187  case CXCursor_CUDAHostAttr:6188    return cxstring::createRef("attribute(host)");6189  case CXCursor_CUDASharedAttr:6190    return cxstring::createRef("attribute(shared)");6191  case CXCursor_VisibilityAttr:6192    return cxstring::createRef("attribute(visibility)");6193  case CXCursor_DLLExport:6194    return cxstring::createRef("attribute(dllexport)");6195  case CXCursor_DLLImport:6196    return cxstring::createRef("attribute(dllimport)");6197  case CXCursor_NSReturnsRetained:6198    return cxstring::createRef("attribute(ns_returns_retained)");6199  case CXCursor_NSReturnsNotRetained:6200    return cxstring::createRef("attribute(ns_returns_not_retained)");6201  case CXCursor_NSReturnsAutoreleased:6202    return cxstring::createRef("attribute(ns_returns_autoreleased)");6203  case CXCursor_NSConsumesSelf:6204    return cxstring::createRef("attribute(ns_consumes_self)");6205  case CXCursor_NSConsumed:6206    return cxstring::createRef("attribute(ns_consumed)");6207  case CXCursor_ObjCException:6208    return cxstring::createRef("attribute(objc_exception)");6209  case CXCursor_ObjCNSObject:6210    return cxstring::createRef("attribute(NSObject)");6211  case CXCursor_ObjCIndependentClass:6212    return cxstring::createRef("attribute(objc_independent_class)");6213  case CXCursor_ObjCPreciseLifetime:6214    return cxstring::createRef("attribute(objc_precise_lifetime)");6215  case CXCursor_ObjCReturnsInnerPointer:6216    return cxstring::createRef("attribute(objc_returns_inner_pointer)");6217  case CXCursor_ObjCRequiresSuper:6218    return cxstring::createRef("attribute(objc_requires_super)");6219  case CXCursor_ObjCRootClass:6220    return cxstring::createRef("attribute(objc_root_class)");6221  case CXCursor_ObjCSubclassingRestricted:6222    return cxstring::createRef("attribute(objc_subclassing_restricted)");6223  case CXCursor_ObjCExplicitProtocolImpl:6224    return cxstring::createRef(6225        "attribute(objc_protocol_requires_explicit_implementation)");6226  case CXCursor_ObjCDesignatedInitializer:6227    return cxstring::createRef("attribute(objc_designated_initializer)");6228  case CXCursor_ObjCRuntimeVisible:6229    return cxstring::createRef("attribute(objc_runtime_visible)");6230  case CXCursor_ObjCBoxable:6231    return cxstring::createRef("attribute(objc_boxable)");6232  case CXCursor_FlagEnum:6233    return cxstring::createRef("attribute(flag_enum)");6234  case CXCursor_PreprocessingDirective:6235    return cxstring::createRef("preprocessing directive");6236  case CXCursor_MacroDefinition:6237    return cxstring::createRef("macro definition");6238  case CXCursor_MacroExpansion:6239    return cxstring::createRef("macro expansion");6240  case CXCursor_InclusionDirective:6241    return cxstring::createRef("inclusion directive");6242  case CXCursor_Namespace:6243    return cxstring::createRef("Namespace");6244  case CXCursor_LinkageSpec:6245    return cxstring::createRef("LinkageSpec");6246  case CXCursor_CXXBaseSpecifier:6247    return cxstring::createRef("C++ base class specifier");6248  case CXCursor_Constructor:6249    return cxstring::createRef("CXXConstructor");6250  case CXCursor_Destructor:6251    return cxstring::createRef("CXXDestructor");6252  case CXCursor_ConversionFunction:6253    return cxstring::createRef("CXXConversion");6254  case CXCursor_TemplateTypeParameter:6255    return cxstring::createRef("TemplateTypeParameter");6256  case CXCursor_NonTypeTemplateParameter:6257    return cxstring::createRef("NonTypeTemplateParameter");6258  case CXCursor_TemplateTemplateParameter:6259    return cxstring::createRef("TemplateTemplateParameter");6260  case CXCursor_FunctionTemplate:6261    return cxstring::createRef("FunctionTemplate");6262  case CXCursor_ClassTemplate:6263    return cxstring::createRef("ClassTemplate");6264  case CXCursor_ClassTemplatePartialSpecialization:6265    return cxstring::createRef("ClassTemplatePartialSpecialization");6266  case CXCursor_NamespaceAlias:6267    return cxstring::createRef("NamespaceAlias");6268  case CXCursor_UsingDirective:6269    return cxstring::createRef("UsingDirective");6270  case CXCursor_UsingDeclaration:6271    return cxstring::createRef("UsingDeclaration");6272  case CXCursor_TypeAliasDecl:6273    return cxstring::createRef("TypeAliasDecl");6274  case CXCursor_ObjCSynthesizeDecl:6275    return cxstring::createRef("ObjCSynthesizeDecl");6276  case CXCursor_ObjCDynamicDecl:6277    return cxstring::createRef("ObjCDynamicDecl");6278  case CXCursor_CXXAccessSpecifier:6279    return cxstring::createRef("CXXAccessSpecifier");6280  case CXCursor_ModuleImportDecl:6281    return cxstring::createRef("ModuleImport");6282  case CXCursor_OMPCanonicalLoop:6283    return cxstring::createRef("OMPCanonicalLoop");6284  case CXCursor_OMPMetaDirective:6285    return cxstring::createRef("OMPMetaDirective");6286  case CXCursor_OMPParallelDirective:6287    return cxstring::createRef("OMPParallelDirective");6288  case CXCursor_OMPSimdDirective:6289    return cxstring::createRef("OMPSimdDirective");6290  case CXCursor_OMPTileDirective:6291    return cxstring::createRef("OMPTileDirective");6292  case CXCursor_OMPStripeDirective:6293    return cxstring::createRef("OMPStripeDirective");6294  case CXCursor_OMPUnrollDirective:6295    return cxstring::createRef("OMPUnrollDirective");6296  case CXCursor_OMPReverseDirective:6297    return cxstring::createRef("OMPReverseDirective");6298  case CXCursor_OMPInterchangeDirective:6299    return cxstring::createRef("OMPInterchangeDirective");6300  case CXCursor_OMPFuseDirective:6301    return cxstring::createRef("OMPFuseDirective");6302  case CXCursor_OMPForDirective:6303    return cxstring::createRef("OMPForDirective");6304  case CXCursor_OMPForSimdDirective:6305    return cxstring::createRef("OMPForSimdDirective");6306  case CXCursor_OMPSectionsDirective:6307    return cxstring::createRef("OMPSectionsDirective");6308  case CXCursor_OMPSectionDirective:6309    return cxstring::createRef("OMPSectionDirective");6310  case CXCursor_OMPScopeDirective:6311    return cxstring::createRef("OMPScopeDirective");6312  case CXCursor_OMPSingleDirective:6313    return cxstring::createRef("OMPSingleDirective");6314  case CXCursor_OMPMasterDirective:6315    return cxstring::createRef("OMPMasterDirective");6316  case CXCursor_OMPCriticalDirective:6317    return cxstring::createRef("OMPCriticalDirective");6318  case CXCursor_OMPParallelForDirective:6319    return cxstring::createRef("OMPParallelForDirective");6320  case CXCursor_OMPParallelForSimdDirective:6321    return cxstring::createRef("OMPParallelForSimdDirective");6322  case CXCursor_OMPParallelMasterDirective:6323    return cxstring::createRef("OMPParallelMasterDirective");6324  case CXCursor_OMPParallelMaskedDirective:6325    return cxstring::createRef("OMPParallelMaskedDirective");6326  case CXCursor_OMPParallelSectionsDirective:6327    return cxstring::createRef("OMPParallelSectionsDirective");6328  case CXCursor_OMPTaskDirective:6329    return cxstring::createRef("OMPTaskDirective");6330  case CXCursor_OMPTaskyieldDirective:6331    return cxstring::createRef("OMPTaskyieldDirective");6332  case CXCursor_OMPBarrierDirective:6333    return cxstring::createRef("OMPBarrierDirective");6334  case CXCursor_OMPTaskwaitDirective:6335    return cxstring::createRef("OMPTaskwaitDirective");6336  case CXCursor_OMPAssumeDirective:6337    return cxstring::createRef("OMPAssumeDirective");6338  case CXCursor_OMPErrorDirective:6339    return cxstring::createRef("OMPErrorDirective");6340  case CXCursor_OMPTaskgroupDirective:6341    return cxstring::createRef("OMPTaskgroupDirective");6342  case CXCursor_OMPFlushDirective:6343    return cxstring::createRef("OMPFlushDirective");6344  case CXCursor_OMPDepobjDirective:6345    return cxstring::createRef("OMPDepobjDirective");6346  case CXCursor_OMPScanDirective:6347    return cxstring::createRef("OMPScanDirective");6348  case CXCursor_OMPOrderedDirective:6349    return cxstring::createRef("OMPOrderedDirective");6350  case CXCursor_OMPAtomicDirective:6351    return cxstring::createRef("OMPAtomicDirective");6352  case CXCursor_OMPTargetDirective:6353    return cxstring::createRef("OMPTargetDirective");6354  case CXCursor_OMPTargetDataDirective:6355    return cxstring::createRef("OMPTargetDataDirective");6356  case CXCursor_OMPTargetEnterDataDirective:6357    return cxstring::createRef("OMPTargetEnterDataDirective");6358  case CXCursor_OMPTargetExitDataDirective:6359    return cxstring::createRef("OMPTargetExitDataDirective");6360  case CXCursor_OMPTargetParallelDirective:6361    return cxstring::createRef("OMPTargetParallelDirective");6362  case CXCursor_OMPTargetParallelForDirective:6363    return cxstring::createRef("OMPTargetParallelForDirective");6364  case CXCursor_OMPTargetUpdateDirective:6365    return cxstring::createRef("OMPTargetUpdateDirective");6366  case CXCursor_OMPTeamsDirective:6367    return cxstring::createRef("OMPTeamsDirective");6368  case CXCursor_OMPCancellationPointDirective:6369    return cxstring::createRef("OMPCancellationPointDirective");6370  case CXCursor_OMPCancelDirective:6371    return cxstring::createRef("OMPCancelDirective");6372  case CXCursor_OMPTaskLoopDirective:6373    return cxstring::createRef("OMPTaskLoopDirective");6374  case CXCursor_OMPTaskLoopSimdDirective:6375    return cxstring::createRef("OMPTaskLoopSimdDirective");6376  case CXCursor_OMPMasterTaskLoopDirective:6377    return cxstring::createRef("OMPMasterTaskLoopDirective");6378  case CXCursor_OMPMaskedTaskLoopDirective:6379    return cxstring::createRef("OMPMaskedTaskLoopDirective");6380  case CXCursor_OMPMasterTaskLoopSimdDirective:6381    return cxstring::createRef("OMPMasterTaskLoopSimdDirective");6382  case CXCursor_OMPMaskedTaskLoopSimdDirective:6383    return cxstring::createRef("OMPMaskedTaskLoopSimdDirective");6384  case CXCursor_OMPParallelMasterTaskLoopDirective:6385    return cxstring::createRef("OMPParallelMasterTaskLoopDirective");6386  case CXCursor_OMPParallelMaskedTaskLoopDirective:6387    return cxstring::createRef("OMPParallelMaskedTaskLoopDirective");6388  case CXCursor_OMPParallelMasterTaskLoopSimdDirective:6389    return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");6390  case CXCursor_OMPParallelMaskedTaskLoopSimdDirective:6391    return cxstring::createRef("OMPParallelMaskedTaskLoopSimdDirective");6392  case CXCursor_OMPDistributeDirective:6393    return cxstring::createRef("OMPDistributeDirective");6394  case CXCursor_OMPDistributeParallelForDirective:6395    return cxstring::createRef("OMPDistributeParallelForDirective");6396  case CXCursor_OMPDistributeParallelForSimdDirective:6397    return cxstring::createRef("OMPDistributeParallelForSimdDirective");6398  case CXCursor_OMPDistributeSimdDirective:6399    return cxstring::createRef("OMPDistributeSimdDirective");6400  case CXCursor_OMPTargetParallelForSimdDirective:6401    return cxstring::createRef("OMPTargetParallelForSimdDirective");6402  case CXCursor_OMPTargetSimdDirective:6403    return cxstring::createRef("OMPTargetSimdDirective");6404  case CXCursor_OMPTeamsDistributeDirective:6405    return cxstring::createRef("OMPTeamsDistributeDirective");6406  case CXCursor_OMPTeamsDistributeSimdDirective:6407    return cxstring::createRef("OMPTeamsDistributeSimdDirective");6408  case CXCursor_OMPTeamsDistributeParallelForSimdDirective:6409    return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");6410  case CXCursor_OMPTeamsDistributeParallelForDirective:6411    return cxstring::createRef("OMPTeamsDistributeParallelForDirective");6412  case CXCursor_OMPTargetTeamsDirective:6413    return cxstring::createRef("OMPTargetTeamsDirective");6414  case CXCursor_OMPTargetTeamsDistributeDirective:6415    return cxstring::createRef("OMPTargetTeamsDistributeDirective");6416  case CXCursor_OMPTargetTeamsDistributeParallelForDirective:6417    return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");6418  case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:6419    return cxstring::createRef(6420        "OMPTargetTeamsDistributeParallelForSimdDirective");6421  case CXCursor_OMPTargetTeamsDistributeSimdDirective:6422    return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");6423  case CXCursor_OMPInteropDirective:6424    return cxstring::createRef("OMPInteropDirective");6425  case CXCursor_OMPDispatchDirective:6426    return cxstring::createRef("OMPDispatchDirective");6427  case CXCursor_OMPMaskedDirective:6428    return cxstring::createRef("OMPMaskedDirective");6429  case CXCursor_OMPGenericLoopDirective:6430    return cxstring::createRef("OMPGenericLoopDirective");6431  case CXCursor_OMPTeamsGenericLoopDirective:6432    return cxstring::createRef("OMPTeamsGenericLoopDirective");6433  case CXCursor_OMPTargetTeamsGenericLoopDirective:6434    return cxstring::createRef("OMPTargetTeamsGenericLoopDirective");6435  case CXCursor_OMPParallelGenericLoopDirective:6436    return cxstring::createRef("OMPParallelGenericLoopDirective");6437  case CXCursor_OMPTargetParallelGenericLoopDirective:6438    return cxstring::createRef("OMPTargetParallelGenericLoopDirective");6439  case CXCursor_OverloadCandidate:6440    return cxstring::createRef("OverloadCandidate");6441  case CXCursor_TypeAliasTemplateDecl:6442    return cxstring::createRef("TypeAliasTemplateDecl");6443  case CXCursor_StaticAssert:6444    return cxstring::createRef("StaticAssert");6445  case CXCursor_FriendDecl:6446    return cxstring::createRef("FriendDecl");6447  case CXCursor_ConvergentAttr:6448    return cxstring::createRef("attribute(convergent)");6449  case CXCursor_WarnUnusedAttr:6450    return cxstring::createRef("attribute(warn_unused)");6451  case CXCursor_WarnUnusedResultAttr:6452    return cxstring::createRef("attribute(warn_unused_result)");6453  case CXCursor_AlignedAttr:6454    return cxstring::createRef("attribute(aligned)");6455  case CXCursor_ConceptDecl:6456    return cxstring::createRef("ConceptDecl");6457  case CXCursor_OpenACCComputeConstruct:6458    return cxstring::createRef("OpenACCComputeConstruct");6459  case CXCursor_OpenACCLoopConstruct:6460    return cxstring::createRef("OpenACCLoopConstruct");6461  case CXCursor_OpenACCCombinedConstruct:6462    return cxstring::createRef("OpenACCCombinedConstruct");6463  case CXCursor_OpenACCDataConstruct:6464    return cxstring::createRef("OpenACCDataConstruct");6465  case CXCursor_OpenACCEnterDataConstruct:6466    return cxstring::createRef("OpenACCEnterDataConstruct");6467  case CXCursor_OpenACCExitDataConstruct:6468    return cxstring::createRef("OpenACCExitDataConstruct");6469  case CXCursor_OpenACCHostDataConstruct:6470    return cxstring::createRef("OpenACCHostDataConstruct");6471  case CXCursor_OpenACCWaitConstruct:6472    return cxstring::createRef("OpenACCWaitConstruct");6473  case CXCursor_OpenACCCacheConstruct:6474    return cxstring::createRef("OpenACCCacheConstruct");6475  case CXCursor_OpenACCInitConstruct:6476    return cxstring::createRef("OpenACCInitConstruct");6477  case CXCursor_OpenACCShutdownConstruct:6478    return cxstring::createRef("OpenACCShutdownConstruct");6479  case CXCursor_OpenACCSetConstruct:6480    return cxstring::createRef("OpenACCSetConstruct");6481  case CXCursor_OpenACCUpdateConstruct:6482    return cxstring::createRef("OpenACCUpdateConstruct");6483  case CXCursor_OpenACCAtomicConstruct:6484    return cxstring::createRef("OpenACCAtomicConstruct");6485  }6486 6487  llvm_unreachable("Unhandled CXCursorKind");6488}6489 6490struct GetCursorData {6491  SourceLocation TokenBeginLoc;6492  bool PointsAtMacroArgExpansion;6493  bool VisitedObjCPropertyImplDecl;6494  SourceLocation VisitedDeclaratorDeclStartLoc;6495  CXCursor &BestCursor;6496 6497  GetCursorData(SourceManager &SM, SourceLocation tokenBegin,6498                CXCursor &outputCursor)6499      : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {6500    PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);6501    VisitedObjCPropertyImplDecl = false;6502  }6503};6504 6505static enum CXChildVisitResult6506GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {6507  GetCursorData *Data = static_cast<GetCursorData *>(client_data);6508  CXCursor *BestCursor = &Data->BestCursor;6509 6510  // If we point inside a macro argument we should provide info of what the6511  // token is so use the actual cursor, don't replace it with a macro expansion6512  // cursor.6513  if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)6514    return CXChildVisit_Recurse;6515 6516  if (clang_isDeclaration(cursor.kind)) {6517    // Avoid having the implicit methods override the property decls.6518    if (const ObjCMethodDecl *MD =6519            dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {6520      if (MD->isImplicit())6521        return CXChildVisit_Break;6522 6523    } else if (const ObjCInterfaceDecl *ID =6524                   dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {6525      // Check that when we have multiple @class references in the same line,6526      // that later ones do not override the previous ones.6527      // If we have:6528      // @class Foo, Bar;6529      // source ranges for both start at '@', so 'Bar' will end up overriding6530      // 'Foo' even though the cursor location was at 'Foo'.6531      if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||6532          BestCursor->kind == CXCursor_ObjCClassRef)6533        if (const ObjCInterfaceDecl *PrevID =6534                dyn_cast_or_null<ObjCInterfaceDecl>(6535                    getCursorDecl(*BestCursor))) {6536          if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&6537              !ID->isThisDeclarationADefinition())6538            return CXChildVisit_Break;6539        }6540 6541    } else if (const DeclaratorDecl *DD =6542                   dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {6543      SourceLocation StartLoc = DD->getSourceRange().getBegin();6544      // Check that when we have multiple declarators in the same line,6545      // that later ones do not override the previous ones.6546      // If we have:6547      // int Foo, Bar;6548      // source ranges for both start at 'int', so 'Bar' will end up overriding6549      // 'Foo' even though the cursor location was at 'Foo'.6550      if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)6551        return CXChildVisit_Break;6552      Data->VisitedDeclaratorDeclStartLoc = StartLoc;6553 6554    } else if (const ObjCPropertyImplDecl *PropImp =6555                   dyn_cast_or_null<ObjCPropertyImplDecl>(6556                       getCursorDecl(cursor))) {6557      (void)PropImp;6558      // Check that when we have multiple @synthesize in the same line,6559      // that later ones do not override the previous ones.6560      // If we have:6561      // @synthesize Foo, Bar;6562      // source ranges for both start at '@', so 'Bar' will end up overriding6563      // 'Foo' even though the cursor location was at 'Foo'.6564      if (Data->VisitedObjCPropertyImplDecl)6565        return CXChildVisit_Break;6566      Data->VisitedObjCPropertyImplDecl = true;6567    }6568  }6569 6570  if (clang_isExpression(cursor.kind) &&6571      clang_isDeclaration(BestCursor->kind)) {6572    if (const Decl *D = getCursorDecl(*BestCursor)) {6573      // Avoid having the cursor of an expression replace the declaration cursor6574      // when the expression source range overlaps the declaration range.6575      // This can happen for C++ constructor expressions whose range generally6576      // include the variable declaration, e.g.:6577      //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl6578      //  cursor.6579      if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&6580          D->getLocation() == Data->TokenBeginLoc)6581        return CXChildVisit_Break;6582    }6583  }6584 6585  // If our current best cursor is the construction of a temporary object,6586  // don't replace that cursor with a type reference, because we want6587  // clang_getCursor() to point at the constructor.6588  if (clang_isExpression(BestCursor->kind) &&6589      isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&6590      cursor.kind == CXCursor_TypeRef) {6591    // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it6592    // as having the actual point on the type reference.6593    *BestCursor = getTypeRefedCallExprCursor(*BestCursor);6594    return CXChildVisit_Recurse;6595  }6596 6597  // If we already have an Objective-C superclass reference, don't6598  // update it further.6599  if (BestCursor->kind == CXCursor_ObjCSuperClassRef)6600    return CXChildVisit_Break;6601 6602  *BestCursor = cursor;6603  return CXChildVisit_Recurse;6604}6605 6606CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {6607  if (isNotUsableTU(TU)) {6608    LOG_BAD_TU(TU);6609    return clang_getNullCursor();6610  }6611 6612  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);6613  ASTUnit::ConcurrencyCheck Check(*CXXUnit);6614 6615  SourceLocation SLoc = cxloc::translateSourceLocation(Loc);6616  CXCursor Result = cxcursor::getCursor(TU, SLoc);6617 6618  LOG_FUNC_SECTION {6619    CXFile SearchFile;6620    unsigned SearchLine, SearchColumn;6621    CXFile ResultFile;6622    unsigned ResultLine, ResultColumn;6623    CXString SearchFileName, ResultFileName, KindSpelling, USR;6624    const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";6625    CXSourceLocation ResultLoc = clang_getCursorLocation(Result);6626 6627    clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,6628                          nullptr);6629    clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,6630                          nullptr);6631    SearchFileName = clang_getFileName(SearchFile);6632    ResultFileName = clang_getFileName(ResultFile);6633    KindSpelling = clang_getCursorKindSpelling(Result.kind);6634    USR = clang_getCursorUSR(Result);6635    *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),6636                         SearchLine, SearchColumn,6637                         clang_getCString(KindSpelling))6638         << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),6639                         ResultLine, ResultColumn, clang_getCString(USR),6640                         IsDef);6641    clang_disposeString(SearchFileName);6642    clang_disposeString(ResultFileName);6643    clang_disposeString(KindSpelling);6644    clang_disposeString(USR);6645 6646    CXCursor Definition = clang_getCursorDefinition(Result);6647    if (!clang_equalCursors(Definition, clang_getNullCursor())) {6648      CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);6649      CXString DefinitionKindSpelling =6650          clang_getCursorKindSpelling(Definition.kind);6651      CXFile DefinitionFile;6652      unsigned DefinitionLine, DefinitionColumn;6653      clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,6654                            &DefinitionColumn, nullptr);6655      CXString DefinitionFileName = clang_getFileName(DefinitionFile);6656      *Log << llvm::format("  -> %s(%s:%d:%d)",6657                           clang_getCString(DefinitionKindSpelling),6658                           clang_getCString(DefinitionFileName), DefinitionLine,6659                           DefinitionColumn);6660      clang_disposeString(DefinitionFileName);6661      clang_disposeString(DefinitionKindSpelling);6662    }6663  }6664 6665  return Result;6666}6667 6668CXCursor clang_getNullCursor(void) {6669  return MakeCXCursorInvalid(CXCursor_InvalidFile);6670}6671 6672unsigned clang_equalCursors(CXCursor X, CXCursor Y) {6673  // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we6674  // can't set consistently. For example, when visiting a DeclStmt we will set6675  // it but we don't set it on the result of clang_getCursorDefinition for6676  // a reference of the same declaration.6677  // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works6678  // when visiting a DeclStmt currently, the AST should be enhanced to be able6679  // to provide that kind of info.6680  if (clang_isDeclaration(X.kind))6681    X.data[1] = nullptr;6682  if (clang_isDeclaration(Y.kind))6683    Y.data[1] = nullptr;6684 6685  return X == Y;6686}6687 6688unsigned clang_hashCursor(CXCursor C) {6689  unsigned Index = 0;6690  if (clang_isExpression(C.kind) || clang_isStatement(C.kind))6691    Index = 1;6692 6693  return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(6694      std::make_pair(C.kind, C.data[Index]));6695}6696 6697unsigned clang_isInvalid(enum CXCursorKind K) {6698  return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;6699}6700 6701unsigned clang_isDeclaration(enum CXCursorKind K) {6702  return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||6703         (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);6704}6705 6706unsigned clang_isInvalidDeclaration(CXCursor C) {6707  if (clang_isDeclaration(C.kind)) {6708    if (const Decl *D = getCursorDecl(C))6709      return D->isInvalidDecl();6710  }6711 6712  return 0;6713}6714 6715unsigned clang_isReference(enum CXCursorKind K) {6716  return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;6717}6718 6719unsigned clang_isExpression(enum CXCursorKind K) {6720  return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;6721}6722 6723unsigned clang_isStatement(enum CXCursorKind K) {6724  return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;6725}6726 6727unsigned clang_isAttribute(enum CXCursorKind K) {6728  return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;6729}6730 6731unsigned clang_isTranslationUnit(enum CXCursorKind K) {6732  return K == CXCursor_TranslationUnit;6733}6734 6735unsigned clang_isPreprocessing(enum CXCursorKind K) {6736  return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;6737}6738 6739unsigned clang_isUnexposed(enum CXCursorKind K) {6740  switch (K) {6741  case CXCursor_UnexposedDecl:6742  case CXCursor_UnexposedExpr:6743  case CXCursor_UnexposedStmt:6744  case CXCursor_UnexposedAttr:6745    return true;6746  default:6747    return false;6748  }6749}6750 6751CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }6752 6753CXSourceLocation clang_getCursorLocation(CXCursor C) {6754  if (clang_isReference(C.kind)) {6755    switch (C.kind) {6756    case CXCursor_ObjCSuperClassRef: {6757      std::pair<const ObjCInterfaceDecl *, SourceLocation> P =6758          getCursorObjCSuperClassRef(C);6759      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);6760    }6761 6762    case CXCursor_ObjCProtocolRef: {6763      std::pair<const ObjCProtocolDecl *, SourceLocation> P =6764          getCursorObjCProtocolRef(C);6765      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);6766    }6767 6768    case CXCursor_ObjCClassRef: {6769      std::pair<const ObjCInterfaceDecl *, SourceLocation> P =6770          getCursorObjCClassRef(C);6771      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);6772    }6773 6774    case CXCursor_TypeRef: {6775      std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);6776      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);6777    }6778 6779    case CXCursor_TemplateRef: {6780      std::pair<const TemplateDecl *, SourceLocation> P =6781          getCursorTemplateRef(C);6782      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);6783    }6784 6785    case CXCursor_NamespaceRef: {6786      std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);6787      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);6788    }6789 6790    case CXCursor_MemberRef: {6791      std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);6792      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);6793    }6794 6795    case CXCursor_VariableRef: {6796      std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);6797      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);6798    }6799 6800    case CXCursor_CXXBaseSpecifier: {6801      const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);6802      if (!BaseSpec)6803        return clang_getNullLocation();6804 6805      if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())6806        return cxloc::translateSourceLocation(6807            getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());6808 6809      return cxloc::translateSourceLocation(getCursorContext(C),6810                                            BaseSpec->getBeginLoc());6811    }6812 6813    case CXCursor_LabelRef: {6814      std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);6815      return cxloc::translateSourceLocation(getCursorContext(C), P.second);6816    }6817 6818    case CXCursor_OverloadedDeclRef:6819      return cxloc::translateSourceLocation(6820          getCursorContext(C), getCursorOverloadedDeclRef(C).second);6821 6822    default:6823      // FIXME: Need a way to enumerate all non-reference cases.6824      llvm_unreachable("Missed a reference kind");6825    }6826  }6827 6828  if (clang_isExpression(C.kind))6829    return cxloc::translateSourceLocation(6830        getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));6831 6832  if (clang_isStatement(C.kind))6833    return cxloc::translateSourceLocation(getCursorContext(C),6834                                          getCursorStmt(C)->getBeginLoc());6835 6836  if (C.kind == CXCursor_PreprocessingDirective) {6837    SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();6838    return cxloc::translateSourceLocation(getCursorContext(C), L);6839  }6840 6841  if (C.kind == CXCursor_MacroExpansion) {6842    SourceLocation L =6843        cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();6844    return cxloc::translateSourceLocation(getCursorContext(C), L);6845  }6846 6847  if (C.kind == CXCursor_MacroDefinition) {6848    SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();6849    return cxloc::translateSourceLocation(getCursorContext(C), L);6850  }6851 6852  if (C.kind == CXCursor_InclusionDirective) {6853    SourceLocation L =6854        cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();6855    return cxloc::translateSourceLocation(getCursorContext(C), L);6856  }6857 6858  if (clang_isAttribute(C.kind)) {6859    SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();6860    return cxloc::translateSourceLocation(getCursorContext(C), L);6861  }6862 6863  if (!clang_isDeclaration(C.kind))6864    return clang_getNullLocation();6865 6866  const Decl *D = getCursorDecl(C);6867  if (!D)6868    return clang_getNullLocation();6869 6870  SourceLocation Loc = D->getLocation();6871  // FIXME: Multiple variables declared in a single declaration6872  // currently lack the information needed to correctly determine their6873  // ranges when accounting for the type-specifier.  We use context6874  // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,6875  // and if so, whether it is the first decl.6876  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {6877    if (!cxcursor::isFirstInDeclGroup(C))6878      Loc = VD->getLocation();6879  }6880 6881  // For ObjC methods, give the start location of the method name.6882  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))6883    Loc = MD->getSelectorStartLoc();6884 6885  return cxloc::translateSourceLocation(getCursorContext(C), Loc);6886}6887 6888} // end extern "C"6889 6890CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {6891  assert(TU);6892 6893  // Guard against an invalid SourceLocation, or we may assert in one6894  // of the following calls.6895  if (SLoc.isInvalid())6896    return clang_getNullCursor();6897 6898  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);6899 6900  // Translate the given source location to make it point at the beginning of6901  // the token under the cursor.6902  SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),6903                                    CXXUnit->getASTContext().getLangOpts());6904 6905  CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);6906  if (SLoc.isValid()) {6907    GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);6908    CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,6909                            /*VisitPreprocessorLast=*/true,6910                            /*VisitIncludedEntities=*/false,6911                            SourceLocation(SLoc));6912    CursorVis.visitFileRegion();6913  }6914 6915  return Result;6916}6917 6918static SourceRange getRawCursorExtent(CXCursor C) {6919  if (clang_isReference(C.kind)) {6920    switch (C.kind) {6921    case CXCursor_ObjCSuperClassRef:6922      return getCursorObjCSuperClassRef(C).second;6923 6924    case CXCursor_ObjCProtocolRef:6925      return getCursorObjCProtocolRef(C).second;6926 6927    case CXCursor_ObjCClassRef:6928      return getCursorObjCClassRef(C).second;6929 6930    case CXCursor_TypeRef:6931      return getCursorTypeRef(C).second;6932 6933    case CXCursor_TemplateRef:6934      return getCursorTemplateRef(C).second;6935 6936    case CXCursor_NamespaceRef:6937      return getCursorNamespaceRef(C).second;6938 6939    case CXCursor_MemberRef:6940      return getCursorMemberRef(C).second;6941 6942    case CXCursor_CXXBaseSpecifier:6943      return getCursorCXXBaseSpecifier(C)->getSourceRange();6944 6945    case CXCursor_LabelRef:6946      return getCursorLabelRef(C).second;6947 6948    case CXCursor_OverloadedDeclRef:6949      return getCursorOverloadedDeclRef(C).second;6950 6951    case CXCursor_VariableRef:6952      return getCursorVariableRef(C).second;6953 6954    default:6955      // FIXME: Need a way to enumerate all non-reference cases.6956      llvm_unreachable("Missed a reference kind");6957    }6958  }6959 6960  if (clang_isExpression(C.kind))6961    return getCursorExpr(C)->getSourceRange();6962 6963  if (clang_isStatement(C.kind))6964    return getCursorStmt(C)->getSourceRange();6965 6966  if (clang_isAttribute(C.kind))6967    return getCursorAttr(C)->getRange();6968 6969  if (C.kind == CXCursor_PreprocessingDirective)6970    return cxcursor::getCursorPreprocessingDirective(C);6971 6972  if (C.kind == CXCursor_MacroExpansion) {6973    ASTUnit *TU = getCursorASTUnit(C);6974    SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();6975    return TU->mapRangeFromPreamble(Range);6976  }6977 6978  if (C.kind == CXCursor_MacroDefinition) {6979    ASTUnit *TU = getCursorASTUnit(C);6980    SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();6981    return TU->mapRangeFromPreamble(Range);6982  }6983 6984  if (C.kind == CXCursor_InclusionDirective) {6985    ASTUnit *TU = getCursorASTUnit(C);6986    SourceRange Range =6987        cxcursor::getCursorInclusionDirective(C)->getSourceRange();6988    return TU->mapRangeFromPreamble(Range);6989  }6990 6991  if (C.kind == CXCursor_TranslationUnit) {6992    ASTUnit *TU = getCursorASTUnit(C);6993    FileID MainID = TU->getSourceManager().getMainFileID();6994    SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);6995    SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);6996    return SourceRange(Start, End);6997  }6998 6999  if (clang_isDeclaration(C.kind)) {7000    const Decl *D = cxcursor::getCursorDecl(C);7001    if (!D)7002      return SourceRange();7003 7004    SourceRange R = D->getSourceRange();7005    // FIXME: Multiple variables declared in a single declaration7006    // currently lack the information needed to correctly determine their7007    // ranges when accounting for the type-specifier.  We use context7008    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,7009    // and if so, whether it is the first decl.7010    if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {7011      if (!cxcursor::isFirstInDeclGroup(C))7012        R.setBegin(VD->getLocation());7013    }7014    return R;7015  }7016  return SourceRange();7017}7018 7019/// Retrieves the "raw" cursor extent, which is then extended to include7020/// the decl-specifier-seq for declarations.7021static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {7022  if (clang_isDeclaration(C.kind)) {7023    const Decl *D = cxcursor::getCursorDecl(C);7024    if (!D)7025      return SourceRange();7026 7027    SourceRange R = D->getSourceRange();7028 7029    // Adjust the start of the location for declarations preceded by7030    // declaration specifiers.7031    SourceLocation StartLoc;7032    if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {7033      if (TypeSourceInfo *TI = DD->getTypeSourceInfo())7034        StartLoc = TI->getTypeLoc().getBeginLoc();7035    } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {7036      if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())7037        StartLoc = TI->getTypeLoc().getBeginLoc();7038    }7039 7040    if (StartLoc.isValid() && R.getBegin().isValid() &&7041        SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))7042      R.setBegin(StartLoc);7043 7044    // FIXME: Multiple variables declared in a single declaration7045    // currently lack the information needed to correctly determine their7046    // ranges when accounting for the type-specifier.  We use context7047    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,7048    // and if so, whether it is the first decl.7049    if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {7050      if (!cxcursor::isFirstInDeclGroup(C))7051        R.setBegin(VD->getLocation());7052    }7053 7054    return R;7055  }7056 7057  return getRawCursorExtent(C);7058}7059 7060CXSourceRange clang_getCursorExtent(CXCursor C) {7061  SourceRange R = getRawCursorExtent(C);7062  if (R.isInvalid())7063    return clang_getNullRange();7064 7065  return cxloc::translateSourceRange(getCursorContext(C), R);7066}7067 7068CXCursor clang_getCursorReferenced(CXCursor C) {7069  if (clang_isInvalid(C.kind))7070    return clang_getNullCursor();7071 7072  CXTranslationUnit tu = getCursorTU(C);7073  if (clang_isDeclaration(C.kind)) {7074    const Decl *D = getCursorDecl(C);7075    if (!D)7076      return clang_getNullCursor();7077    if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))7078      return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);7079    if (const ObjCPropertyImplDecl *PropImpl =7080            dyn_cast<ObjCPropertyImplDecl>(D))7081      if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())7082        return MakeCXCursor(Property, tu);7083 7084    return C;7085  }7086 7087  if (clang_isExpression(C.kind)) {7088    const Expr *E = getCursorExpr(C);7089    const Decl *D = getDeclFromExpr(E);7090    if (D) {7091      CXCursor declCursor = MakeCXCursor(D, tu);7092      declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),7093                                               declCursor);7094      return declCursor;7095    }7096 7097    if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))7098      return MakeCursorOverloadedDeclRef(Ovl, tu);7099 7100    return clang_getNullCursor();7101  }7102 7103  if (clang_isStatement(C.kind)) {7104    const Stmt *S = getCursorStmt(C);7105    if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))7106      if (LabelDecl *label = Goto->getLabel())7107        if (LabelStmt *labelS = label->getStmt())7108          return MakeCXCursor(labelS, getCursorDecl(C), tu);7109 7110    return clang_getNullCursor();7111  }7112 7113  if (C.kind == CXCursor_MacroExpansion) {7114    if (const MacroDefinitionRecord *Def =7115            getCursorMacroExpansion(C).getDefinition())7116      return MakeMacroDefinitionCursor(Def, tu);7117  }7118 7119  if (!clang_isReference(C.kind))7120    return clang_getNullCursor();7121 7122  switch (C.kind) {7123  case CXCursor_ObjCSuperClassRef:7124    return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);7125 7126  case CXCursor_ObjCProtocolRef: {7127    const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;7128    if (const ObjCProtocolDecl *Def = Prot->getDefinition())7129      return MakeCXCursor(Def, tu);7130 7131    return MakeCXCursor(Prot, tu);7132  }7133 7134  case CXCursor_ObjCClassRef: {7135    const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;7136    if (const ObjCInterfaceDecl *Def = Class->getDefinition())7137      return MakeCXCursor(Def, tu);7138 7139    return MakeCXCursor(Class, tu);7140  }7141 7142  case CXCursor_TypeRef:7143    return MakeCXCursor(getCursorTypeRef(C).first, tu);7144 7145  case CXCursor_TemplateRef:7146    return MakeCXCursor(getCursorTemplateRef(C).first, tu);7147 7148  case CXCursor_NamespaceRef:7149    return MakeCXCursor(getCursorNamespaceRef(C).first, tu);7150 7151  case CXCursor_MemberRef:7152    return MakeCXCursor(getCursorMemberRef(C).first, tu);7153 7154  case CXCursor_CXXBaseSpecifier: {7155    const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);7156    return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));7157  }7158 7159  case CXCursor_LabelRef:7160    // FIXME: We end up faking the "parent" declaration here because we7161    // don't want to make CXCursor larger.7162    return MakeCXCursor(7163        getCursorLabelRef(C).first,7164        cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);7165 7166  case CXCursor_OverloadedDeclRef:7167    return C;7168 7169  case CXCursor_VariableRef:7170    return MakeCXCursor(getCursorVariableRef(C).first, tu);7171 7172  default:7173    // We would prefer to enumerate all non-reference cursor kinds here.7174    llvm_unreachable("Unhandled reference cursor kind");7175  }7176}7177 7178CXCursor clang_getCursorDefinition(CXCursor C) {7179  if (clang_isInvalid(C.kind))7180    return clang_getNullCursor();7181 7182  CXTranslationUnit TU = getCursorTU(C);7183 7184  bool WasReference = false;7185  if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {7186    C = clang_getCursorReferenced(C);7187    WasReference = true;7188  }7189 7190  if (C.kind == CXCursor_MacroExpansion)7191    return clang_getCursorReferenced(C);7192 7193  if (!clang_isDeclaration(C.kind))7194    return clang_getNullCursor();7195 7196  const Decl *D = getCursorDecl(C);7197  if (!D)7198    return clang_getNullCursor();7199 7200  switch (D->getKind()) {7201  // Declaration kinds that don't really separate the notions of7202  // declaration and definition.7203  case Decl::Namespace:7204  case Decl::Typedef:7205  case Decl::TypeAlias:7206  case Decl::TypeAliasTemplate:7207  case Decl::TemplateTypeParm:7208  case Decl::EnumConstant:7209  case Decl::Field:7210  case Decl::Binding:7211  case Decl::MSProperty:7212  case Decl::MSGuid:7213  case Decl::HLSLBuffer:7214  case Decl::HLSLRootSignature:7215  case Decl::UnnamedGlobalConstant:7216  case Decl::TemplateParamObject:7217  case Decl::IndirectField:7218  case Decl::ObjCIvar:7219  case Decl::ObjCAtDefsField:7220  case Decl::ImplicitParam:7221  case Decl::ParmVar:7222  case Decl::NonTypeTemplateParm:7223  case Decl::TemplateTemplateParm:7224  case Decl::ObjCCategoryImpl:7225  case Decl::ObjCImplementation:7226  case Decl::AccessSpec:7227  case Decl::LinkageSpec:7228  case Decl::Export:7229  case Decl::ObjCPropertyImpl:7230  case Decl::FileScopeAsm:7231  case Decl::TopLevelStmt:7232  case Decl::StaticAssert:7233  case Decl::Block:7234  case Decl::OutlinedFunction:7235  case Decl::Captured:7236  case Decl::OMPCapturedExpr:7237  case Decl::Label: // FIXME: Is this right??7238  case Decl::CXXDeductionGuide:7239  case Decl::Import:7240  case Decl::OMPThreadPrivate:7241  case Decl::OMPGroupPrivate:7242  case Decl::OMPAllocate:7243  case Decl::OMPDeclareReduction:7244  case Decl::OMPDeclareMapper:7245  case Decl::OMPRequires:7246  case Decl::ObjCTypeParam:7247  case Decl::BuiltinTemplate:7248  case Decl::PragmaComment:7249  case Decl::PragmaDetectMismatch:7250  case Decl::UsingPack:7251  case Decl::Concept:7252  case Decl::ImplicitConceptSpecialization:7253  case Decl::LifetimeExtendedTemporary:7254  case Decl::RequiresExprBody:7255  case Decl::UnresolvedUsingIfExists:7256  case Decl::OpenACCDeclare:7257  case Decl::OpenACCRoutine:7258    return C;7259 7260  // Declaration kinds that don't make any sense here, but are7261  // nonetheless harmless.7262  case Decl::Empty:7263  case Decl::TranslationUnit:7264  case Decl::ExternCContext:7265    break;7266 7267  // Declaration kinds for which the definition is not resolvable.7268  case Decl::UnresolvedUsingTypename:7269  case Decl::UnresolvedUsingValue:7270    break;7271 7272  case Decl::UsingDirective:7273    return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),7274                        TU);7275 7276  case Decl::NamespaceAlias:7277    return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);7278 7279  case Decl::Enum:7280  case Decl::Record:7281  case Decl::CXXRecord:7282  case Decl::ClassTemplateSpecialization:7283  case Decl::ClassTemplatePartialSpecialization:7284    if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())7285      return MakeCXCursor(Def, TU);7286    return clang_getNullCursor();7287 7288  case Decl::Function:7289  case Decl::CXXMethod:7290  case Decl::CXXConstructor:7291  case Decl::CXXDestructor:7292  case Decl::CXXConversion: {7293    const FunctionDecl *Def = nullptr;7294    if (cast<FunctionDecl>(D)->getBody(Def))7295      return MakeCXCursor(Def, TU);7296    return clang_getNullCursor();7297  }7298 7299  case Decl::Var:7300  case Decl::VarTemplateSpecialization:7301  case Decl::VarTemplatePartialSpecialization:7302  case Decl::Decomposition: {7303    // Ask the variable if it has a definition.7304    if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())7305      return MakeCXCursor(Def, TU);7306    return clang_getNullCursor();7307  }7308 7309  case Decl::FunctionTemplate: {7310    const FunctionDecl *Def = nullptr;7311    if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))7312      return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);7313    return clang_getNullCursor();7314  }7315 7316  case Decl::ClassTemplate: {7317    if (RecordDecl *Def =7318            cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())7319      return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),7320                          TU);7321    return clang_getNullCursor();7322  }7323 7324  case Decl::VarTemplate: {7325    if (VarDecl *Def =7326            cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())7327      return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);7328    return clang_getNullCursor();7329  }7330 7331  case Decl::Using:7332  case Decl::UsingEnum:7333    return MakeCursorOverloadedDeclRef(cast<BaseUsingDecl>(D), D->getLocation(),7334                                       TU);7335 7336  case Decl::UsingShadow:7337  case Decl::ConstructorUsingShadow:7338    return clang_getCursorDefinition(7339        MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));7340 7341  case Decl::ObjCMethod: {7342    const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);7343    if (Method->isThisDeclarationADefinition())7344      return C;7345 7346    // Dig out the method definition in the associated7347    // @implementation, if we have it.7348    // FIXME: The ASTs should make finding the definition easier.7349    if (const ObjCInterfaceDecl *Class =7350            dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))7351      if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())7352        if (ObjCMethodDecl *Def = ClassImpl->getMethod(7353                Method->getSelector(), Method->isInstanceMethod()))7354          if (Def->isThisDeclarationADefinition())7355            return MakeCXCursor(Def, TU);7356 7357    return clang_getNullCursor();7358  }7359 7360  case Decl::ObjCCategory:7361    if (ObjCCategoryImplDecl *Impl =7362            cast<ObjCCategoryDecl>(D)->getImplementation())7363      return MakeCXCursor(Impl, TU);7364    return clang_getNullCursor();7365 7366  case Decl::ObjCProtocol:7367    if (const ObjCProtocolDecl *Def =7368            cast<ObjCProtocolDecl>(D)->getDefinition())7369      return MakeCXCursor(Def, TU);7370    return clang_getNullCursor();7371 7372  case Decl::ObjCInterface: {7373    // There are two notions of a "definition" for an Objective-C7374    // class: the interface and its implementation. When we resolved a7375    // reference to an Objective-C class, produce the @interface as7376    // the definition; when we were provided with the interface,7377    // produce the @implementation as the definition.7378    const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);7379    if (WasReference) {7380      if (const ObjCInterfaceDecl *Def = IFace->getDefinition())7381        return MakeCXCursor(Def, TU);7382    } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())7383      return MakeCXCursor(Impl, TU);7384    return clang_getNullCursor();7385  }7386 7387  case Decl::ObjCProperty:7388    // FIXME: We don't really know where to find the7389    // ObjCPropertyImplDecls that implement this property.7390    return clang_getNullCursor();7391 7392  case Decl::ObjCCompatibleAlias:7393    if (const ObjCInterfaceDecl *Class =7394            cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())7395      if (const ObjCInterfaceDecl *Def = Class->getDefinition())7396        return MakeCXCursor(Def, TU);7397 7398    return clang_getNullCursor();7399 7400  case Decl::Friend:7401    if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())7402      return clang_getCursorDefinition(MakeCXCursor(Friend, TU));7403    return clang_getNullCursor();7404 7405  case Decl::FriendTemplate:7406    if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())7407      return clang_getCursorDefinition(MakeCXCursor(Friend, TU));7408    return clang_getNullCursor();7409  }7410 7411  return clang_getNullCursor();7412}7413 7414unsigned clang_isCursorDefinition(CXCursor C) {7415  if (!clang_isDeclaration(C.kind))7416    return 0;7417 7418  return clang_getCursorDefinition(C) == C;7419}7420 7421CXCursor clang_getCanonicalCursor(CXCursor C) {7422  if (!clang_isDeclaration(C.kind))7423    return C;7424 7425  if (const Decl *D = getCursorDecl(C)) {7426    if (const ObjCCategoryImplDecl *CatImplD =7427            dyn_cast<ObjCCategoryImplDecl>(D))7428      if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())7429        return MakeCXCursor(CatD, getCursorTU(C));7430 7431    if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))7432      if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())7433        return MakeCXCursor(IFD, getCursorTU(C));7434 7435    return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));7436  }7437 7438  return C;7439}7440 7441int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {7442  return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;7443}7444 7445unsigned clang_getNumOverloadedDecls(CXCursor C) {7446  if (C.kind != CXCursor_OverloadedDeclRef)7447    return 0;7448 7449  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;7450  if (const OverloadExpr *E = dyn_cast<const OverloadExpr *>(Storage))7451    return E->getNumDecls();7452 7453  if (OverloadedTemplateStorage *S =7454          dyn_cast<OverloadedTemplateStorage *>(Storage))7455    return S->size();7456 7457  const Decl *D = cast<const Decl *>(Storage);7458  if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))7459    return Using->shadow_size();7460 7461  return 0;7462}7463 7464CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {7465  if (cursor.kind != CXCursor_OverloadedDeclRef)7466    return clang_getNullCursor();7467 7468  if (index >= clang_getNumOverloadedDecls(cursor))7469    return clang_getNullCursor();7470 7471  CXTranslationUnit TU = getCursorTU(cursor);7472  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;7473  if (const OverloadExpr *E = dyn_cast<const OverloadExpr *>(Storage))7474    return MakeCXCursor(E->decls_begin()[index], TU);7475 7476  if (OverloadedTemplateStorage *S =7477          dyn_cast<OverloadedTemplateStorage *>(Storage))7478    return MakeCXCursor(S->begin()[index], TU);7479 7480  const Decl *D = cast<const Decl *>(Storage);7481  if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {7482    // FIXME: This is, unfortunately, linear time.7483    UsingDecl::shadow_iterator Pos = Using->shadow_begin();7484    std::advance(Pos, index);7485    return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);7486  }7487 7488  return clang_getNullCursor();7489}7490 7491void clang_getDefinitionSpellingAndExtent(7492    CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,7493    unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {7494  assert(getCursorDecl(C) && "CXCursor has null decl");7495  const auto *FD = cast<FunctionDecl>(getCursorDecl(C));7496  const auto *Body = cast<CompoundStmt>(FD->getBody());7497 7498  SourceManager &SM = FD->getASTContext().getSourceManager();7499  *startBuf = SM.getCharacterData(Body->getLBracLoc());7500  *endBuf = SM.getCharacterData(Body->getRBracLoc());7501  *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());7502  *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());7503  *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());7504  *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());7505}7506 7507CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,7508                                                unsigned PieceIndex) {7509  RefNamePieces Pieces;7510 7511  switch (C.kind) {7512  case CXCursor_MemberRefExpr:7513    if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))7514      Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),7515                           E->getQualifierLoc().getSourceRange());7516    break;7517 7518  case CXCursor_DeclRefExpr:7519    if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {7520      SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());7521      Pieces =7522          buildPieces(NameFlags, false, E->getNameInfo(),7523                      E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);7524    }7525    break;7526 7527  case CXCursor_CallExpr:7528    if (const CXXOperatorCallExpr *OCE =7529            dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {7530      const Expr *Callee = OCE->getCallee();7531      if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))7532        Callee = ICE->getSubExpr();7533 7534      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))7535        Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),7536                             DRE->getQualifierLoc().getSourceRange());7537    }7538    break;7539 7540  default:7541    break;7542  }7543 7544  if (Pieces.empty()) {7545    if (PieceIndex == 0)7546      return clang_getCursorExtent(C);7547  } else if (PieceIndex < Pieces.size()) {7548    SourceRange R = Pieces[PieceIndex];7549    if (R.isValid())7550      return cxloc::translateSourceRange(getCursorContext(C), R);7551  }7552 7553  return clang_getNullRange();7554}7555 7556void clang_enableStackTraces(void) {7557  // FIXME: Provide an argv0 here so we can find llvm-symbolizer.7558  llvm::sys::PrintStackTraceOnErrorSignal(StringRef());7559}7560 7561void clang_executeOnThread(void (*fn)(void *), void *user_data,7562                           unsigned stack_size) {7563  llvm::thread Thread(stack_size == 0 ? clang::DesiredStackSize7564                                      : std::optional<unsigned>(stack_size),7565                      fn, user_data);7566  Thread.join();7567}7568 7569//===----------------------------------------------------------------------===//7570// Token-based Operations.7571//===----------------------------------------------------------------------===//7572 7573/* CXToken layout:7574 *   int_data[0]: a CXTokenKind7575 *   int_data[1]: starting token location7576 *   int_data[2]: token length7577 *   int_data[3]: reserved7578 *   ptr_data: for identifiers and keywords, an IdentifierInfo*.7579 *   otherwise unused.7580 */7581CXTokenKind clang_getTokenKind(CXToken CXTok) {7582  return static_cast<CXTokenKind>(CXTok.int_data[0]);7583}7584 7585CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {7586  switch (clang_getTokenKind(CXTok)) {7587  case CXToken_Identifier:7588  case CXToken_Keyword:7589    // We know we have an IdentifierInfo*, so use that.7590    return cxstring::createRef(7591        static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());7592 7593  case CXToken_Literal: {7594    // We have stashed the starting pointer in the ptr_data field. Use it.7595    const char *Text = static_cast<const char *>(CXTok.ptr_data);7596    return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));7597  }7598 7599  case CXToken_Punctuation:7600  case CXToken_Comment:7601    break;7602  }7603 7604  if (isNotUsableTU(TU)) {7605    LOG_BAD_TU(TU);7606    return cxstring::createEmpty();7607  }7608 7609  // We have to find the starting buffer pointer the hard way, by7610  // deconstructing the source location.7611  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);7612  if (!CXXUnit)7613    return cxstring::createEmpty();7614 7615  SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);7616  FileIDAndOffset LocInfo =7617      CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);7618  bool Invalid = false;7619  StringRef Buffer =7620      CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);7621  if (Invalid)7622    return cxstring::createEmpty();7623 7624  return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));7625}7626 7627CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {7628  if (isNotUsableTU(TU)) {7629    LOG_BAD_TU(TU);7630    return clang_getNullLocation();7631  }7632 7633  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);7634  if (!CXXUnit)7635    return clang_getNullLocation();7636 7637  return cxloc::translateSourceLocation(7638      CXXUnit->getASTContext(),7639      SourceLocation::getFromRawEncoding(CXTok.int_data[1]));7640}7641 7642CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {7643  if (isNotUsableTU(TU)) {7644    LOG_BAD_TU(TU);7645    return clang_getNullRange();7646  }7647 7648  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);7649  if (!CXXUnit)7650    return clang_getNullRange();7651 7652  return cxloc::translateSourceRange(7653      CXXUnit->getASTContext(),7654      SourceLocation::getFromRawEncoding(CXTok.int_data[1]));7655}7656 7657static void getTokens(ASTUnit *CXXUnit, SourceRange Range,7658                      SmallVectorImpl<CXToken> &CXTokens) {7659  SourceManager &SourceMgr = CXXUnit->getSourceManager();7660  FileIDAndOffset BeginLocInfo =7661      SourceMgr.getDecomposedSpellingLoc(Range.getBegin());7662  FileIDAndOffset EndLocInfo =7663      SourceMgr.getDecomposedSpellingLoc(Range.getEnd());7664 7665  // Cannot tokenize across files.7666  if (BeginLocInfo.first != EndLocInfo.first)7667    return;7668 7669  // Create a lexer7670  bool Invalid = false;7671  StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);7672  if (Invalid)7673    return;7674 7675  Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),7676            CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),7677            Buffer.data() + BeginLocInfo.second, Buffer.end());7678  Lex.SetCommentRetentionState(true);7679 7680  // Lex tokens until we hit the end of the range.7681  const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;7682  Token Tok;7683  bool previousWasAt = false;7684  do {7685    // Lex the next token7686    Lex.LexFromRawLexer(Tok);7687    if (Tok.is(tok::eof))7688      break;7689 7690    // Initialize the CXToken.7691    CXToken CXTok;7692 7693    //   - Common fields7694    CXTok.int_data[1] = Tok.getLocation().getRawEncoding();7695    CXTok.int_data[2] = Tok.getLength();7696    CXTok.int_data[3] = 0;7697 7698    //   - Kind-specific fields7699    if (Tok.isLiteral()) {7700      CXTok.int_data[0] = CXToken_Literal;7701      CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());7702    } else if (Tok.is(tok::raw_identifier)) {7703      // Lookup the identifier to determine whether we have a keyword.7704      IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);7705 7706      if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {7707        CXTok.int_data[0] = CXToken_Keyword;7708      } else {7709        CXTok.int_data[0] =7710            Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;7711      }7712      CXTok.ptr_data = II;7713    } else if (Tok.is(tok::comment)) {7714      CXTok.int_data[0] = CXToken_Comment;7715      CXTok.ptr_data = nullptr;7716    } else {7717      CXTok.int_data[0] = CXToken_Punctuation;7718      CXTok.ptr_data = nullptr;7719    }7720    CXTokens.push_back(CXTok);7721    previousWasAt = Tok.is(tok::at);7722  } while (Lex.getBufferLocation() < EffectiveBufferEnd);7723}7724 7725CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {7726  LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }7727 7728  if (isNotUsableTU(TU)) {7729    LOG_BAD_TU(TU);7730    return nullptr;7731  }7732 7733  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);7734  if (!CXXUnit)7735    return nullptr;7736 7737  SourceLocation Begin = cxloc::translateSourceLocation(Location);7738  if (Begin.isInvalid())7739    return nullptr;7740  SourceManager &SM = CXXUnit->getSourceManager();7741  FileIDAndOffset DecomposedEnd = SM.getDecomposedLoc(Begin);7742  DecomposedEnd.second +=7743      Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());7744 7745  SourceLocation End =7746      SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);7747 7748  SmallVector<CXToken, 32> CXTokens;7749  getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);7750 7751  if (CXTokens.empty())7752    return nullptr;7753 7754  CXTokens.resize(1);7755  CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));7756 7757  memmove(Token, CXTokens.data(), sizeof(CXToken));7758  return Token;7759}7760 7761void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,7762                    unsigned *NumTokens) {7763  LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }7764 7765  if (Tokens)7766    *Tokens = nullptr;7767  if (NumTokens)7768    *NumTokens = 0;7769 7770  if (isNotUsableTU(TU)) {7771    LOG_BAD_TU(TU);7772    return;7773  }7774 7775  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);7776  if (!CXXUnit || !Tokens || !NumTokens)7777    return;7778 7779  ASTUnit::ConcurrencyCheck Check(*CXXUnit);7780 7781  SourceRange R = cxloc::translateCXSourceRange(Range);7782  if (R.isInvalid())7783    return;7784 7785  SmallVector<CXToken, 32> CXTokens;7786  getTokens(CXXUnit, R, CXTokens);7787 7788  if (CXTokens.empty())7789    return;7790 7791  *Tokens = static_cast<CXToken *>(7792      llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));7793  memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());7794  *NumTokens = CXTokens.size();7795}7796 7797void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,7798                         unsigned NumTokens) {7799  free(Tokens);7800}7801 7802//===----------------------------------------------------------------------===//7803// Token annotation APIs.7804//===----------------------------------------------------------------------===//7805 7806static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,7807                                                     CXCursor parent,7808                                                     CXClientData client_data);7809static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,7810                                              CXClientData client_data);7811 7812namespace {7813class AnnotateTokensWorker {7814  CXToken *Tokens;7815  CXCursor *Cursors;7816  unsigned NumTokens;7817  unsigned TokIdx;7818  unsigned PreprocessingTokIdx;7819  CursorVisitor AnnotateVis;7820  SourceManager &SrcMgr;7821  bool HasContextSensitiveKeywords;7822 7823  struct PostChildrenAction {7824    CXCursor cursor;7825    enum Action { Invalid, Ignore, Postpone } action;7826  };7827  using PostChildrenActions = SmallVector<PostChildrenAction, 0>;7828 7829  struct PostChildrenInfo {7830    CXCursor Cursor;7831    SourceRange CursorRange;7832    unsigned BeforeReachingCursorIdx;7833    unsigned BeforeChildrenTokenIdx;7834    PostChildrenActions ChildActions;7835  };7836  SmallVector<PostChildrenInfo, 8> PostChildrenInfos;7837 7838  CXToken &getTok(unsigned Idx) {7839    assert(Idx < NumTokens);7840    return Tokens[Idx];7841  }7842  const CXToken &getTok(unsigned Idx) const {7843    assert(Idx < NumTokens);7844    return Tokens[Idx];7845  }7846  bool MoreTokens() const { return TokIdx < NumTokens; }7847  unsigned NextToken() const { return TokIdx; }7848  void AdvanceToken() { ++TokIdx; }7849  SourceLocation GetTokenLoc(unsigned tokI) {7850    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);7851  }7852  bool isFunctionMacroToken(unsigned tokI) const {7853    return getTok(tokI).int_data[3] != 0;7854  }7855  SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {7856    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);7857  }7858 7859  void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);7860  bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,7861                                             SourceRange);7862 7863public:7864  AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,7865                       CXTranslationUnit TU, SourceRange RegionOfInterest)7866      : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),7867        PreprocessingTokIdx(0),7868        AnnotateVis(TU, AnnotateTokensVisitor, this,7869                    /*VisitPreprocessorLast=*/true,7870                    /*VisitIncludedEntities=*/false, RegionOfInterest,7871                    /*VisitDeclsOnly=*/false,7872                    AnnotateTokensPostChildrenVisitor),7873        SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),7874        HasContextSensitiveKeywords(false) {}7875 7876  void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }7877  enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);7878  bool IsIgnoredChildCursor(CXCursor cursor) const;7879  PostChildrenActions DetermineChildActions(CXCursor Cursor) const;7880 7881  bool postVisitChildren(CXCursor cursor);7882  void HandlePostPonedChildCursors(const PostChildrenInfo &Info);7883  void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);7884 7885  void AnnotateTokens();7886 7887  /// Determine whether the annotator saw any cursors that have7888  /// context-sensitive keywords.7889  bool hasContextSensitiveKeywords() const {7890    return HasContextSensitiveKeywords;7891  }7892 7893  ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }7894};7895} // namespace7896 7897void AnnotateTokensWorker::AnnotateTokens() {7898  // Walk the AST within the region of interest, annotating tokens7899  // along the way.7900  AnnotateVis.visitFileRegion();7901}7902 7903bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {7904  if (PostChildrenInfos.empty())7905    return false;7906 7907  for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {7908    if (ChildAction.cursor == cursor &&7909        ChildAction.action == PostChildrenAction::Ignore) {7910      return true;7911    }7912  }7913 7914  return false;7915}7916 7917const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {7918  if (!clang_isExpression(Cursor.kind))7919    return nullptr;7920 7921  const Expr *E = getCursorExpr(Cursor);7922  if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {7923    const OverloadedOperatorKind Kind = OCE->getOperator();7924    if (Kind == OO_Call || Kind == OO_Subscript)7925      return OCE;7926  }7927 7928  return nullptr;7929}7930 7931AnnotateTokensWorker::PostChildrenActions7932AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {7933  PostChildrenActions actions;7934 7935  // The DeclRefExpr of CXXOperatorCallExpr referring to the custom operator is7936  // visited before the arguments to the operator call. For the Call and7937  // Subscript operator the range of this DeclRefExpr includes the whole call7938  // expression, so that all tokens in that range would be mapped to the7939  // operator function, including the tokens of the arguments. To avoid that,7940  // ensure to visit this DeclRefExpr as last node.7941  if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {7942    const Expr *Callee = OCE->getCallee();7943    if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {7944      const Expr *SubExpr = ICE->getSubExpr();7945      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {7946        const Decl *parentDecl = getCursorDecl(Cursor);7947        CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);7948 7949        // Visit the DeclRefExpr as last.7950        CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);7951        actions.push_back({cxChild, PostChildrenAction::Postpone});7952 7953        // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally7954        // wide range as the DeclRefExpr. We can skip visiting this entirely.7955        cxChild = MakeCXCursor(ICE, parentDecl, TU);7956        actions.push_back({cxChild, PostChildrenAction::Ignore});7957      }7958    }7959  }7960 7961  return actions;7962}7963 7964static inline void updateCursorAnnotation(CXCursor &Cursor,7965                                          const CXCursor &updateC) {7966  if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))7967    return;7968  Cursor = updateC;7969}7970 7971/// It annotates and advances tokens with a cursor until the comparison7972//// between the cursor location and the source range is the same as7973/// \arg compResult.7974///7975/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.7976/// Pass RangeOverlap to annotate tokens inside a range.7977void AnnotateTokensWorker::annotateAndAdvanceTokens(7978    CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {7979  while (MoreTokens()) {7980    const unsigned I = NextToken();7981    if (isFunctionMacroToken(I))7982      if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))7983        return;7984 7985    SourceLocation TokLoc = GetTokenLoc(I);7986    if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {7987      updateCursorAnnotation(Cursors[I], updateC);7988      AdvanceToken();7989      continue;7990    }7991    break;7992  }7993}7994 7995/// Special annotation handling for macro argument tokens.7996/// \returns true if it advanced beyond all macro tokens, false otherwise.7997bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(7998    CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {7999  assert(MoreTokens());8000  assert(isFunctionMacroToken(NextToken()) &&8001         "Should be called only for macro arg tokens");8002 8003  // This works differently than annotateAndAdvanceTokens; because expanded8004  // macro arguments can have arbitrary translation-unit source order, we do not8005  // advance the token index one by one until a token fails the range test.8006  // We only advance once past all of the macro arg tokens if all of them8007  // pass the range test. If one of them fails we keep the token index pointing8008  // at the start of the macro arg tokens so that the failing token will be8009  // annotated by a subsequent annotation try.8010 8011  bool atLeastOneCompFail = false;8012 8013  unsigned I = NextToken();8014  for (; I < NumTokens && isFunctionMacroToken(I); ++I) {8015    SourceLocation TokLoc = getFunctionMacroTokenLoc(I);8016    if (TokLoc.isFileID())8017      continue; // not macro arg token, it's parens or comma.8018    if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {8019      if (clang_isInvalid(clang_getCursorKind(Cursors[I])))8020        Cursors[I] = updateC;8021    } else8022      atLeastOneCompFail = true;8023  }8024 8025  if (atLeastOneCompFail)8026    return false;8027 8028  TokIdx = I; // All of the tokens were handled, advance beyond all of them.8029  return true;8030}8031 8032enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,8033                                                    CXCursor parent) {8034  SourceRange cursorRange = getRawCursorExtent(cursor);8035  if (cursorRange.isInvalid())8036    return CXChildVisit_Recurse;8037 8038  if (IsIgnoredChildCursor(cursor))8039    return CXChildVisit_Continue;8040 8041  if (!HasContextSensitiveKeywords) {8042    // Objective-C properties can have context-sensitive keywords.8043    if (cursor.kind == CXCursor_ObjCPropertyDecl) {8044      if (const ObjCPropertyDecl *Property =8045              dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))8046        HasContextSensitiveKeywords =8047            Property->getPropertyAttributesAsWritten() != 0;8048    }8049    // Objective-C methods can have context-sensitive keywords.8050    else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||8051             cursor.kind == CXCursor_ObjCClassMethodDecl) {8052      if (const ObjCMethodDecl *Method =8053              dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {8054        if (Method->getObjCDeclQualifier())8055          HasContextSensitiveKeywords = true;8056        else {8057          for (const auto *P : Method->parameters()) {8058            if (P->getObjCDeclQualifier()) {8059              HasContextSensitiveKeywords = true;8060              break;8061            }8062          }8063        }8064      }8065    }8066    // C++ methods can have context-sensitive keywords.8067    else if (cursor.kind == CXCursor_CXXMethod) {8068      if (const CXXMethodDecl *Method =8069              dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {8070        if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())8071          HasContextSensitiveKeywords = true;8072      }8073    }8074    // C++ classes can have context-sensitive keywords.8075    else if (cursor.kind == CXCursor_StructDecl ||8076             cursor.kind == CXCursor_ClassDecl ||8077             cursor.kind == CXCursor_ClassTemplate ||8078             cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {8079      if (const Decl *D = getCursorDecl(cursor))8080        if (D->hasAttr<FinalAttr>())8081          HasContextSensitiveKeywords = true;8082    }8083  }8084 8085  // Don't override a property annotation with its getter/setter method.8086  if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&8087      parent.kind == CXCursor_ObjCPropertyDecl)8088    return CXChildVisit_Continue;8089 8090  if (clang_isPreprocessing(cursor.kind)) {8091    // Items in the preprocessing record are kept separate from items in8092    // declarations, so we keep a separate token index.8093    unsigned SavedTokIdx = TokIdx;8094    TokIdx = PreprocessingTokIdx;8095 8096    // Skip tokens up until we catch up to the beginning of the preprocessing8097    // entry.8098    while (MoreTokens()) {8099      const unsigned I = NextToken();8100      SourceLocation TokLoc = GetTokenLoc(I);8101      switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {8102      case RangeBefore:8103        AdvanceToken();8104        continue;8105      case RangeAfter:8106      case RangeOverlap:8107        break;8108      }8109      break;8110    }8111 8112    // Look at all of the tokens within this range.8113    while (MoreTokens()) {8114      const unsigned I = NextToken();8115      SourceLocation TokLoc = GetTokenLoc(I);8116      switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {8117      case RangeBefore:8118        llvm_unreachable("Infeasible");8119      case RangeAfter:8120        break;8121      case RangeOverlap:8122        // For macro expansions, just note where the beginning of the macro8123        // expansion occurs.8124        if (cursor.kind == CXCursor_MacroExpansion) {8125          if (TokLoc == cursorRange.getBegin())8126            Cursors[I] = cursor;8127          AdvanceToken();8128          break;8129        }8130        // We may have already annotated macro names inside macro definitions.8131        if (Cursors[I].kind != CXCursor_MacroExpansion)8132          Cursors[I] = cursor;8133        AdvanceToken();8134        continue;8135      }8136      break;8137    }8138 8139    // Save the preprocessing token index; restore the non-preprocessing8140    // token index.8141    PreprocessingTokIdx = TokIdx;8142    TokIdx = SavedTokIdx;8143    return CXChildVisit_Recurse;8144  }8145 8146  if (cursorRange.isInvalid())8147    return CXChildVisit_Continue;8148 8149  unsigned BeforeReachingCursorIdx = NextToken();8150  const enum CXCursorKind cursorK = clang_getCursorKind(cursor);8151  const enum CXCursorKind K = clang_getCursorKind(parent);8152  const CXCursor updateC =8153      (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||8154       // Attributes are annotated out-of-order, skip tokens until we reach it.8155       clang_isAttribute(cursor.kind))8156          ? clang_getNullCursor()8157          : parent;8158 8159  annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);8160 8161  // Avoid having the cursor of an expression "overwrite" the annotation of the8162  // variable declaration that it belongs to.8163  // This can happen for C++ constructor expressions whose range generally8164  // include the variable declaration, e.g.:8165  //  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.8166  if (clang_isExpression(cursorK) && MoreTokens()) {8167    const Expr *E = getCursorExpr(cursor);8168    if (const Decl *D = getCursorDecl(cursor)) {8169      const unsigned I = NextToken();8170      if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&8171          E->getBeginLoc() == D->getLocation() &&8172          E->getBeginLoc() == GetTokenLoc(I)) {8173        updateCursorAnnotation(Cursors[I], updateC);8174        AdvanceToken();8175      }8176    }8177  }8178 8179  // Before recursing into the children keep some state that we are going8180  // to use in the AnnotateTokensWorker::postVisitChildren callback to do some8181  // extra work after the child nodes are visited.8182  // Note that we don't call VisitChildren here to avoid traversing statements8183  // code-recursively which can blow the stack.8184 8185  PostChildrenInfo Info;8186  Info.Cursor = cursor;8187  Info.CursorRange = cursorRange;8188  Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;8189  Info.BeforeChildrenTokenIdx = NextToken();8190  Info.ChildActions = DetermineChildActions(cursor);8191  PostChildrenInfos.push_back(Info);8192 8193  return CXChildVisit_Recurse;8194}8195 8196bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {8197  if (PostChildrenInfos.empty())8198    return false;8199  const PostChildrenInfo &Info = PostChildrenInfos.back();8200  if (!clang_equalCursors(Info.Cursor, cursor))8201    return false;8202 8203  HandlePostPonedChildCursors(Info);8204 8205  const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;8206  const unsigned AfterChildren = NextToken();8207  SourceRange cursorRange = Info.CursorRange;8208 8209  // Scan the tokens that are at the end of the cursor, but are not captured8210  // but the child cursors.8211  annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);8212 8213  // Scan the tokens that are at the beginning of the cursor, but are not8214  // capture by the child cursors.8215  for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {8216    if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))8217      break;8218 8219    Cursors[I] = cursor;8220  }8221 8222  // Attributes are annotated out-of-order, rewind TokIdx to when we first8223  // encountered the attribute cursor.8224  if (clang_isAttribute(cursor.kind))8225    TokIdx = Info.BeforeReachingCursorIdx;8226 8227  PostChildrenInfos.pop_back();8228  return false;8229}8230 8231void AnnotateTokensWorker::HandlePostPonedChildCursors(8232    const PostChildrenInfo &Info) {8233  for (const auto &ChildAction : Info.ChildActions) {8234    if (ChildAction.action == PostChildrenAction::Postpone) {8235      HandlePostPonedChildCursor(ChildAction.cursor,8236                                 Info.BeforeChildrenTokenIdx);8237    }8238  }8239}8240 8241void AnnotateTokensWorker::HandlePostPonedChildCursor(8242    CXCursor Cursor, unsigned StartTokenIndex) {8243  unsigned I = StartTokenIndex;8244 8245  // The bracket tokens of a Call or Subscript operator are mapped to8246  // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding8247  // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.8248  for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {8249    const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(8250        Cursor, CXNameRange_WantQualifier, RefNameRangeNr);8251    if (clang_Range_isNull(CXRefNameRange))8252      break; // All ranges handled.8253 8254    SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);8255    while (I < NumTokens) {8256      const SourceLocation TokenLocation = GetTokenLoc(I);8257      if (!TokenLocation.isValid())8258        break;8259 8260      // Adapt the end range, because LocationCompare() reports8261      // RangeOverlap even for the not-inclusive end location.8262      const SourceLocation fixedEnd =8263          RefNameRange.getEnd().getLocWithOffset(-1);8264      RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);8265 8266      const RangeComparisonResult ComparisonResult =8267          LocationCompare(SrcMgr, TokenLocation, RefNameRange);8268 8269      if (ComparisonResult == RangeOverlap) {8270        Cursors[I++] = Cursor;8271      } else if (ComparisonResult == RangeBefore) {8272        ++I; // Not relevant token, check next one.8273      } else if (ComparisonResult == RangeAfter) {8274        break; // All tokens updated for current range, check next.8275      }8276    }8277  }8278}8279 8280static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,8281                                                     CXCursor parent,8282                                                     CXClientData client_data) {8283  return static_cast<AnnotateTokensWorker *>(client_data)8284      ->Visit(cursor, parent);8285}8286 8287static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,8288                                              CXClientData client_data) {8289  return static_cast<AnnotateTokensWorker *>(client_data)8290      ->postVisitChildren(cursor);8291}8292 8293namespace {8294 8295/// Uses the macro expansions in the preprocessing record to find8296/// and mark tokens that are macro arguments. This info is used by the8297/// AnnotateTokensWorker.8298class MarkMacroArgTokensVisitor {8299  SourceManager &SM;8300  CXToken *Tokens;8301  unsigned NumTokens;8302  unsigned CurIdx;8303 8304public:8305  MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,8306                            unsigned numTokens)8307      : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}8308 8309  CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {8310    if (cursor.kind != CXCursor_MacroExpansion)8311      return CXChildVisit_Continue;8312 8313    SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();8314    if (macroRange.getBegin() == macroRange.getEnd())8315      return CXChildVisit_Continue; // it's not a function macro.8316 8317    for (; CurIdx < NumTokens; ++CurIdx) {8318      if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),8319                                        macroRange.getBegin()))8320        break;8321    }8322 8323    if (CurIdx == NumTokens)8324      return CXChildVisit_Break;8325 8326    for (; CurIdx < NumTokens; ++CurIdx) {8327      SourceLocation tokLoc = getTokenLoc(CurIdx);8328      if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))8329        break;8330 8331      setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));8332    }8333 8334    if (CurIdx == NumTokens)8335      return CXChildVisit_Break;8336 8337    return CXChildVisit_Continue;8338  }8339 8340private:8341  CXToken &getTok(unsigned Idx) {8342    assert(Idx < NumTokens);8343    return Tokens[Idx];8344  }8345  const CXToken &getTok(unsigned Idx) const {8346    assert(Idx < NumTokens);8347    return Tokens[Idx];8348  }8349 8350  SourceLocation getTokenLoc(unsigned tokI) {8351    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);8352  }8353 8354  void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {8355    // The third field is reserved and currently not used. Use it here8356    // to mark macro arg expanded tokens with their expanded locations.8357    getTok(tokI).int_data[3] = loc.getRawEncoding();8358  }8359};8360 8361} // end anonymous namespace8362 8363static CXChildVisitResult8364MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,8365                                  CXClientData client_data) {8366  return static_cast<MarkMacroArgTokensVisitor *>(client_data)8367      ->visit(cursor, parent);8368}8369 8370/// Used by \c annotatePreprocessorTokens.8371/// \returns true if lexing was finished, false otherwise.8372static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,8373                    unsigned NumTokens) {8374  if (NextIdx >= NumTokens)8375    return true;8376 8377  ++NextIdx;8378  Lex.LexFromRawLexer(Tok);8379  return Tok.is(tok::eof);8380}8381 8382static void annotatePreprocessorTokens(CXTranslationUnit TU,8383                                       SourceRange RegionOfInterest,8384                                       CXCursor *Cursors, CXToken *Tokens,8385                                       unsigned NumTokens) {8386  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);8387 8388  Preprocessor &PP = CXXUnit->getPreprocessor();8389  SourceManager &SourceMgr = CXXUnit->getSourceManager();8390  FileIDAndOffset BeginLocInfo =8391      SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());8392  FileIDAndOffset EndLocInfo =8393      SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());8394 8395  if (BeginLocInfo.first != EndLocInfo.first)8396    return;8397 8398  StringRef Buffer;8399  bool Invalid = false;8400  Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);8401  if (Buffer.empty() || Invalid)8402    return;8403 8404  Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),8405            CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),8406            Buffer.data() + BeginLocInfo.second, Buffer.end());8407  Lex.SetCommentRetentionState(true);8408 8409  unsigned NextIdx = 0;8410  // Lex tokens in raw mode until we hit the end of the range, to avoid8411  // entering #includes or expanding macros.8412  while (true) {8413    Token Tok;8414    if (lexNext(Lex, Tok, NextIdx, NumTokens))8415      break;8416    unsigned TokIdx = NextIdx - 1;8417    assert(Tok.getLocation() ==8418           SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));8419 8420  reprocess:8421    if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {8422      // We have found a preprocessing directive. Annotate the tokens8423      // appropriately.8424      //8425      // FIXME: Some simple tests here could identify macro definitions and8426      // #undefs, to provide specific cursor kinds for those.8427 8428      SourceLocation BeginLoc = Tok.getLocation();8429      if (lexNext(Lex, Tok, NextIdx, NumTokens))8430        break;8431 8432      MacroInfo *MI = nullptr;8433      if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {8434        if (lexNext(Lex, Tok, NextIdx, NumTokens))8435          break;8436 8437        if (Tok.is(tok::raw_identifier)) {8438          IdentifierInfo &II =8439              PP.getIdentifierTable().get(Tok.getRawIdentifier());8440          SourceLocation MappedTokLoc =8441              CXXUnit->mapLocationToPreamble(Tok.getLocation());8442          MI = getMacroInfo(II, MappedTokLoc, TU);8443        }8444      }8445 8446      bool finished = false;8447      do {8448        if (lexNext(Lex, Tok, NextIdx, NumTokens)) {8449          finished = true;8450          break;8451        }8452        // If we are in a macro definition, check if the token was ever a8453        // macro name and annotate it if that's the case.8454        if (MI) {8455          SourceLocation SaveLoc = Tok.getLocation();8456          Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));8457          MacroDefinitionRecord *MacroDef =8458              checkForMacroInMacroDefinition(MI, Tok, TU);8459          Tok.setLocation(SaveLoc);8460          if (MacroDef)8461            Cursors[NextIdx - 1] =8462                MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);8463        }8464      } while (!Tok.isAtStartOfLine());8465 8466      unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;8467      assert(TokIdx <= LastIdx);8468      SourceLocation EndLoc =8469          SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);8470      CXCursor Cursor =8471          MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);8472 8473      for (; TokIdx <= LastIdx; ++TokIdx)8474        updateCursorAnnotation(Cursors[TokIdx], Cursor);8475 8476      if (finished)8477        break;8478      goto reprocess;8479    }8480  }8481}8482 8483// This gets run a separate thread to avoid stack blowout.8484static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,8485                                     CXToken *Tokens, unsigned NumTokens,8486                                     CXCursor *Cursors) {8487  CIndexer *CXXIdx = TU->CIdx;8488  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))8489    setThreadBackgroundPriority();8490 8491  // Determine the region of interest, which contains all of the tokens.8492  SourceRange RegionOfInterest;8493  RegionOfInterest.setBegin(8494      cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));8495  RegionOfInterest.setEnd(cxloc::translateSourceLocation(8496      clang_getTokenLocation(TU, Tokens[NumTokens - 1])));8497 8498  // Relex the tokens within the source range to look for preprocessing8499  // directives.8500  annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);8501 8502  // If begin location points inside a macro argument, set it to the expansion8503  // location so we can have the full context when annotating semantically.8504  {8505    SourceManager &SM = CXXUnit->getSourceManager();8506    SourceLocation Loc =8507        SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());8508    if (Loc.isMacroID())8509      RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));8510  }8511 8512  if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {8513    // Search and mark tokens that are macro argument expansions.8514    MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,8515                                      NumTokens);8516    CursorVisitor MacroArgMarker(8517        TU, MarkMacroArgTokensVisitorDelegate, &Visitor,8518        /*VisitPreprocessorLast=*/true,8519        /*VisitIncludedEntities=*/false, RegionOfInterest);8520    MacroArgMarker.visitPreprocessedEntitiesInRegion();8521  }8522 8523  // Annotate all of the source locations in the region of interest that map to8524  // a specific cursor.8525  AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);8526 8527  // FIXME: We use a ridiculous stack size here because the data-recursion8528  // algorithm uses a large stack frame than the non-data recursive version,8529  // and AnnotationTokensWorker currently transforms the data-recursion8530  // algorithm back into a traditional recursion by explicitly calling8531  // VisitChildren().  We will need to remove this explicit recursive call.8532  W.AnnotateTokens();8533 8534  // If we ran into any entities that involve context-sensitive keywords,8535  // take another pass through the tokens to mark them as such.8536  if (W.hasContextSensitiveKeywords()) {8537    for (unsigned I = 0; I != NumTokens; ++I) {8538      if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)8539        continue;8540 8541      if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {8542        IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);8543        if (const ObjCPropertyDecl *Property =8544                dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {8545          if (Property->getPropertyAttributesAsWritten() != 0 &&8546              llvm::StringSwitch<bool>(II->getName())8547                  .Case("readonly", true)8548                  .Case("assign", true)8549                  .Case("unsafe_unretained", true)8550                  .Case("readwrite", true)8551                  .Case("retain", true)8552                  .Case("copy", true)8553                  .Case("nonatomic", true)8554                  .Case("atomic", true)8555                  .Case("getter", true)8556                  .Case("setter", true)8557                  .Case("strong", true)8558                  .Case("weak", true)8559                  .Case("class", true)8560                  .Default(false))8561            Tokens[I].int_data[0] = CXToken_Keyword;8562        }8563        continue;8564      }8565 8566      if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||8567          Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {8568        IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);8569        if (llvm::StringSwitch<bool>(II->getName())8570                .Case("in", true)8571                .Case("out", true)8572                .Case("inout", true)8573                .Case("oneway", true)8574                .Case("bycopy", true)8575                .Case("byref", true)8576                .Default(false))8577          Tokens[I].int_data[0] = CXToken_Keyword;8578        continue;8579      }8580 8581      if (Cursors[I].kind == CXCursor_CXXFinalAttr ||8582          Cursors[I].kind == CXCursor_CXXOverrideAttr) {8583        Tokens[I].int_data[0] = CXToken_Keyword;8584        continue;8585      }8586    }8587  }8588}8589 8590void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,8591                          unsigned NumTokens, CXCursor *Cursors) {8592  if (isNotUsableTU(TU)) {8593    LOG_BAD_TU(TU);8594    return;8595  }8596  if (NumTokens == 0 || !Tokens || !Cursors) {8597    LOG_FUNC_SECTION { *Log << "<null input>"; }8598    return;8599  }8600 8601  LOG_FUNC_SECTION {8602    *Log << TU << ' ';8603    CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);8604    CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);8605    *Log << clang_getRange(bloc, eloc);8606  }8607 8608  // Any token we don't specifically annotate will have a NULL cursor.8609  CXCursor C = clang_getNullCursor();8610  for (unsigned I = 0; I != NumTokens; ++I)8611    Cursors[I] = C;8612 8613  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);8614  if (!CXXUnit)8615    return;8616 8617  ASTUnit::ConcurrencyCheck Check(*CXXUnit);8618 8619  auto AnnotateTokensImpl = [=]() {8620    clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);8621  };8622  llvm::CrashRecoveryContext CRC;8623  if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {8624    fprintf(stderr, "libclang: crash detected while annotating tokens\n");8625  }8626}8627 8628//===----------------------------------------------------------------------===//8629// Operations for querying information of a GCC inline assembly block under a8630// cursor.8631//===----------------------------------------------------------------------===//8632CXString clang_Cursor_getGCCAssemblyTemplate(CXCursor Cursor) {8633  if (!clang_isStatement(Cursor.kind))8634    return cxstring::createEmpty();8635  if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) {8636    ASTContext const &C = getCursorContext(Cursor);8637    std::string AsmTemplate = S->generateAsmString(C);8638    return cxstring::createDup(AsmTemplate);8639  }8640  return cxstring::createEmpty();8641}8642 8643unsigned clang_Cursor_isGCCAssemblyHasGoto(CXCursor Cursor) {8644  if (!clang_isStatement(Cursor.kind))8645    return 0;8646  if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)))8647    return S->isAsmGoto();8648  return 0;8649}8650 8651unsigned clang_Cursor_getGCCAssemblyNumOutputs(CXCursor Cursor) {8652  if (!clang_isStatement(Cursor.kind))8653    return 0;8654  if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)))8655    return S->getNumOutputs();8656  return 0;8657}8658 8659unsigned clang_Cursor_getGCCAssemblyNumInputs(CXCursor Cursor) {8660  if (!clang_isStatement(Cursor.kind))8661    return 0;8662  if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)))8663    return S->getNumInputs();8664  return 0;8665}8666 8667unsigned clang_Cursor_getGCCAssemblyInput(CXCursor Cursor, unsigned Index,8668                                          CXString *Constraint,8669                                          CXCursor *ExprCursor) {8670  if (!clang_isStatement(Cursor.kind) || !Constraint || !ExprCursor)8671    return 0;8672  if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor));8673      S && Index < S->getNumInputs()) {8674    *Constraint = cxstring::createDup(S->getInputConstraint(Index));8675    *ExprCursor = MakeCXCursor(S->getInputExpr(Index), getCursorDecl(Cursor),8676                               cxcursor::getCursorTU(Cursor));8677    return 1;8678  }8679  return 0;8680}8681 8682unsigned clang_Cursor_getGCCAssemblyOutput(CXCursor Cursor, unsigned Index,8683                                           CXString *Constraint,8684                                           CXCursor *ExprCursor) {8685  if (!clang_isStatement(Cursor.kind) || !Constraint || !ExprCursor)8686    return 0;8687  if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor));8688      S && Index < S->getNumOutputs()) {8689    *Constraint = cxstring::createDup(S->getOutputConstraint(Index));8690    *ExprCursor = MakeCXCursor(S->getOutputExpr(Index), getCursorDecl(Cursor),8691                               cxcursor::getCursorTU(Cursor));8692    return 1;8693  }8694  return 0;8695}8696 8697unsigned clang_Cursor_getGCCAssemblyNumClobbers(CXCursor Cursor) {8698  if (!clang_isStatement(Cursor.kind))8699    return 0;8700  if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)))8701    return S->getNumClobbers();8702  return 0;8703}8704 8705CXString clang_Cursor_getGCCAssemblyClobber(CXCursor Cursor, unsigned Index) {8706  if (!clang_isStatement(Cursor.kind))8707    return cxstring::createEmpty();8708  if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor));8709      S && Index < S->getNumClobbers())8710    return cxstring::createDup(S->getClobber(Index));8711  return cxstring::createEmpty();8712}8713 8714unsigned clang_Cursor_isGCCAssemblyVolatile(CXCursor Cursor) {8715  if (!clang_isStatement(Cursor.kind))8716    return 0;8717  if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)))8718    return S->isVolatile();8719  return 0;8720}8721 8722//===----------------------------------------------------------------------===//8723// Operations for querying linkage of a cursor.8724//===----------------------------------------------------------------------===//8725 8726CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {8727  if (!clang_isDeclaration(cursor.kind))8728    return CXLinkage_Invalid;8729 8730  const Decl *D = cxcursor::getCursorDecl(cursor);8731  if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))8732    switch (ND->getLinkageInternal()) {8733    case Linkage::Invalid:8734      return CXLinkage_Invalid;8735    case Linkage::None:8736    case Linkage::VisibleNone:8737      return CXLinkage_NoLinkage;8738    case Linkage::Internal:8739      return CXLinkage_Internal;8740    case Linkage::UniqueExternal:8741      return CXLinkage_UniqueExternal;8742    case Linkage::Module:8743    case Linkage::External:8744      return CXLinkage_External;8745    };8746 8747  return CXLinkage_Invalid;8748}8749 8750//===----------------------------------------------------------------------===//8751// Operations for querying visibility of a cursor.8752//===----------------------------------------------------------------------===//8753 8754CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {8755  if (!clang_isDeclaration(cursor.kind))8756    return CXVisibility_Invalid;8757 8758  const Decl *D = cxcursor::getCursorDecl(cursor);8759  if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))8760    switch (ND->getVisibility()) {8761    case HiddenVisibility:8762      return CXVisibility_Hidden;8763    case ProtectedVisibility:8764      return CXVisibility_Protected;8765    case DefaultVisibility:8766      return CXVisibility_Default;8767    };8768 8769  return CXVisibility_Invalid;8770}8771 8772//===----------------------------------------------------------------------===//8773// Operations for querying language of a cursor.8774//===----------------------------------------------------------------------===//8775 8776static CXLanguageKind getDeclLanguage(const Decl *D) {8777  if (!D)8778    return CXLanguage_C;8779 8780  switch (D->getKind()) {8781  default:8782    break;8783  case Decl::ImplicitParam:8784  case Decl::ObjCAtDefsField:8785  case Decl::ObjCCategory:8786  case Decl::ObjCCategoryImpl:8787  case Decl::ObjCCompatibleAlias:8788  case Decl::ObjCImplementation:8789  case Decl::ObjCInterface:8790  case Decl::ObjCIvar:8791  case Decl::ObjCMethod:8792  case Decl::ObjCProperty:8793  case Decl::ObjCPropertyImpl:8794  case Decl::ObjCProtocol:8795  case Decl::ObjCTypeParam:8796    return CXLanguage_ObjC;8797  case Decl::CXXConstructor:8798  case Decl::CXXConversion:8799  case Decl::CXXDestructor:8800  case Decl::CXXMethod:8801  case Decl::CXXRecord:8802  case Decl::ClassTemplate:8803  case Decl::ClassTemplatePartialSpecialization:8804  case Decl::ClassTemplateSpecialization:8805  case Decl::Friend:8806  case Decl::FriendTemplate:8807  case Decl::FunctionTemplate:8808  case Decl::LinkageSpec:8809  case Decl::Namespace:8810  case Decl::NamespaceAlias:8811  case Decl::NonTypeTemplateParm:8812  case Decl::StaticAssert:8813  case Decl::TemplateTemplateParm:8814  case Decl::TemplateTypeParm:8815  case Decl::UnresolvedUsingTypename:8816  case Decl::UnresolvedUsingValue:8817  case Decl::Using:8818  case Decl::UsingDirective:8819  case Decl::UsingShadow:8820    return CXLanguage_CPlusPlus;8821  }8822 8823  return CXLanguage_C;8824}8825 8826static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {8827  if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())8828    return CXAvailability_NotAvailable;8829 8830  switch (D->getAvailability()) {8831  case AR_Available:8832  case AR_NotYetIntroduced:8833    if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))8834      return getCursorAvailabilityForDecl(8835          cast<Decl>(EnumConst->getDeclContext()));8836    return CXAvailability_Available;8837 8838  case AR_Deprecated:8839    return CXAvailability_Deprecated;8840 8841  case AR_Unavailable:8842    return CXAvailability_NotAvailable;8843  }8844 8845  llvm_unreachable("Unknown availability kind!");8846}8847 8848enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {8849  if (clang_isDeclaration(cursor.kind))8850    if (const Decl *D = cxcursor::getCursorDecl(cursor))8851      return getCursorAvailabilityForDecl(D);8852 8853  return CXAvailability_Available;8854}8855 8856static CXVersion convertVersion(VersionTuple In) {8857  CXVersion Out = {-1, -1, -1};8858  if (In.empty())8859    return Out;8860 8861  Out.Major = In.getMajor();8862 8863  std::optional<unsigned> Minor = In.getMinor();8864  if (Minor)8865    Out.Minor = *Minor;8866  else8867    return Out;8868 8869  std::optional<unsigned> Subminor = In.getSubminor();8870  if (Subminor)8871    Out.Subminor = *Subminor;8872 8873  return Out;8874}8875 8876static void getCursorPlatformAvailabilityForDecl(8877    const Decl *D, int *always_deprecated, CXString *deprecated_message,8878    int *always_unavailable, CXString *unavailable_message,8879    SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {8880  bool HadAvailAttr = false;8881  for (auto A : D->attrs()) {8882    if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {8883      HadAvailAttr = true;8884      if (always_deprecated)8885        *always_deprecated = 1;8886      if (deprecated_message) {8887        clang_disposeString(*deprecated_message);8888        *deprecated_message = cxstring::createDup(Deprecated->getMessage());8889      }8890      continue;8891    }8892 8893    if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {8894      HadAvailAttr = true;8895      if (always_unavailable)8896        *always_unavailable = 1;8897      if (unavailable_message) {8898        clang_disposeString(*unavailable_message);8899        *unavailable_message = cxstring::createDup(Unavailable->getMessage());8900      }8901      continue;8902    }8903 8904    if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {8905      AvailabilityAttrs.push_back(Avail);8906      HadAvailAttr = true;8907    }8908  }8909 8910  if (!HadAvailAttr)8911    if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))8912      return getCursorPlatformAvailabilityForDecl(8913          cast<Decl>(EnumConst->getDeclContext()), always_deprecated,8914          deprecated_message, always_unavailable, unavailable_message,8915          AvailabilityAttrs);8916 8917  // If no availability attributes are found, inherit the attribute from the8918  // containing decl or the class or category interface decl.8919  if (AvailabilityAttrs.empty()) {8920    const ObjCContainerDecl *CD = nullptr;8921    const DeclContext *DC = D->getDeclContext();8922 8923    if (auto *IMD = dyn_cast<ObjCImplementationDecl>(D))8924      CD = IMD->getClassInterface();8925    else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D))8926      CD = CatD->getClassInterface();8927    else if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(D))8928      CD = IMD->getCategoryDecl();8929    else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(DC))8930      CD = ID;8931    else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(DC))8932      CD = CatD;8933    else if (auto *IMD = dyn_cast<ObjCImplementationDecl>(DC))8934      CD = IMD->getClassInterface();8935    else if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(DC))8936      CD = IMD->getCategoryDecl();8937    else if (auto *PD = dyn_cast<ObjCProtocolDecl>(DC))8938      CD = PD;8939 8940    if (CD)8941      getCursorPlatformAvailabilityForDecl(8942          CD, always_deprecated, deprecated_message, always_unavailable,8943          unavailable_message, AvailabilityAttrs);8944    return;8945  }8946 8947  llvm::sort(8948      AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {8949        return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();8950      });8951  ASTContext &Ctx = D->getASTContext();8952  auto It = llvm::unique(8953      AvailabilityAttrs, [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {8954        if (LHS->getPlatform() != RHS->getPlatform())8955          return false;8956 8957        if (LHS->getIntroduced() == RHS->getIntroduced() &&8958            LHS->getDeprecated() == RHS->getDeprecated() &&8959            LHS->getObsoleted() == RHS->getObsoleted() &&8960            LHS->getMessage() == RHS->getMessage() &&8961            LHS->getReplacement() == RHS->getReplacement())8962          return true;8963 8964        if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||8965            (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||8966            (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))8967          return false;8968 8969        if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())8970          LHS->setIntroduced(Ctx, RHS->getIntroduced());8971 8972        if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {8973          LHS->setDeprecated(Ctx, RHS->getDeprecated());8974          if (LHS->getMessage().empty())8975            LHS->setMessage(Ctx, RHS->getMessage());8976          if (LHS->getReplacement().empty())8977            LHS->setReplacement(Ctx, RHS->getReplacement());8978        }8979 8980        if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {8981          LHS->setObsoleted(Ctx, RHS->getObsoleted());8982          if (LHS->getMessage().empty())8983            LHS->setMessage(Ctx, RHS->getMessage());8984          if (LHS->getReplacement().empty())8985            LHS->setReplacement(Ctx, RHS->getReplacement());8986        }8987 8988        return true;8989      });8990  AvailabilityAttrs.erase(It, AvailabilityAttrs.end());8991}8992 8993int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,8994                                        CXString *deprecated_message,8995                                        int *always_unavailable,8996                                        CXString *unavailable_message,8997                                        CXPlatformAvailability *availability,8998                                        int availability_size) {8999  if (always_deprecated)9000    *always_deprecated = 0;9001  if (deprecated_message)9002    *deprecated_message = cxstring::createEmpty();9003  if (always_unavailable)9004    *always_unavailable = 0;9005  if (unavailable_message)9006    *unavailable_message = cxstring::createEmpty();9007 9008  if (!clang_isDeclaration(cursor.kind))9009    return 0;9010 9011  const Decl *D = cxcursor::getCursorDecl(cursor);9012  if (!D)9013    return 0;9014 9015  SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;9016  getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,9017                                       always_unavailable, unavailable_message,9018                                       AvailabilityAttrs);9019  for (const auto &Avail : llvm::enumerate(9020           llvm::ArrayRef(AvailabilityAttrs).take_front(availability_size))) {9021    availability[Avail.index()].Platform =9022        cxstring::createDup(Avail.value()->getPlatform()->getName());9023    availability[Avail.index()].Introduced =9024        convertVersion(Avail.value()->getIntroduced());9025    availability[Avail.index()].Deprecated =9026        convertVersion(Avail.value()->getDeprecated());9027    availability[Avail.index()].Obsoleted =9028        convertVersion(Avail.value()->getObsoleted());9029    availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();9030    availability[Avail.index()].Message =9031        cxstring::createDup(Avail.value()->getMessage());9032  }9033 9034  return AvailabilityAttrs.size();9035}9036 9037void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {9038  clang_disposeString(availability->Platform);9039  clang_disposeString(availability->Message);9040}9041 9042CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {9043  if (clang_isDeclaration(cursor.kind))9044    return getDeclLanguage(cxcursor::getCursorDecl(cursor));9045 9046  return CXLanguage_Invalid;9047}9048 9049CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {9050  const Decl *D = cxcursor::getCursorDecl(cursor);9051  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {9052    switch (VD->getTLSKind()) {9053    case VarDecl::TLS_None:9054      return CXTLS_None;9055    case VarDecl::TLS_Dynamic:9056      return CXTLS_Dynamic;9057    case VarDecl::TLS_Static:9058      return CXTLS_Static;9059    }9060  }9061 9062  return CXTLS_None;9063}9064 9065/// If the given cursor is the "templated" declaration9066/// describing a class or function template, return the class or9067/// function template.9068static const Decl *maybeGetTemplateCursor(const Decl *D) {9069  if (!D)9070    return nullptr;9071 9072  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))9073    if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())9074      return FunTmpl;9075 9076  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))9077    if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())9078      return ClassTmpl;9079 9080  return D;9081}9082 9083enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {9084  StorageClass sc = SC_None;9085  const Decl *D = getCursorDecl(C);9086  if (D) {9087    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {9088      sc = FD->getStorageClass();9089    } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {9090      sc = VD->getStorageClass();9091    } else {9092      return CX_SC_Invalid;9093    }9094  } else {9095    return CX_SC_Invalid;9096  }9097  switch (sc) {9098  case SC_None:9099    return CX_SC_None;9100  case SC_Extern:9101    return CX_SC_Extern;9102  case SC_Static:9103    return CX_SC_Static;9104  case SC_PrivateExtern:9105    return CX_SC_PrivateExtern;9106  case SC_Auto:9107    return CX_SC_Auto;9108  case SC_Register:9109    return CX_SC_Register;9110  }9111  llvm_unreachable("Unhandled storage class!");9112}9113 9114CXCursor clang_getCursorSemanticParent(CXCursor cursor) {9115  if (clang_isDeclaration(cursor.kind)) {9116    if (const Decl *D = getCursorDecl(cursor)) {9117      const DeclContext *DC = D->getDeclContext();9118      if (!DC)9119        return clang_getNullCursor();9120 9121      return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),9122                          getCursorTU(cursor));9123    }9124  }9125 9126  if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {9127    if (const Decl *D = getCursorDecl(cursor))9128      return MakeCXCursor(D, getCursorTU(cursor));9129  }9130 9131  return clang_getNullCursor();9132}9133 9134CXCursor clang_getCursorLexicalParent(CXCursor cursor) {9135  if (clang_isDeclaration(cursor.kind)) {9136    if (const Decl *D = getCursorDecl(cursor)) {9137      const DeclContext *DC = D->getLexicalDeclContext();9138      if (!DC)9139        return clang_getNullCursor();9140 9141      return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),9142                          getCursorTU(cursor));9143    }9144  }9145 9146  // FIXME: Note that we can't easily compute the lexical context of a9147  // statement or expression, so we return nothing.9148  return clang_getNullCursor();9149}9150 9151CXFile clang_getIncludedFile(CXCursor cursor) {9152  if (cursor.kind != CXCursor_InclusionDirective)9153    return nullptr;9154 9155  const InclusionDirective *ID = getCursorInclusionDirective(cursor);9156  return cxfile::makeCXFile(ID->getFile());9157}9158 9159unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {9160  if (C.kind != CXCursor_ObjCPropertyDecl)9161    return CXObjCPropertyAttr_noattr;9162 9163  unsigned Result = CXObjCPropertyAttr_noattr;9164  const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));9165  ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();9166 9167#define SET_CXOBJCPROP_ATTR(A)                                                 \9168  if (Attr & ObjCPropertyAttribute::kind_##A)                                  \9169  Result |= CXObjCPropertyAttr_##A9170  SET_CXOBJCPROP_ATTR(readonly);9171  SET_CXOBJCPROP_ATTR(getter);9172  SET_CXOBJCPROP_ATTR(assign);9173  SET_CXOBJCPROP_ATTR(readwrite);9174  SET_CXOBJCPROP_ATTR(retain);9175  SET_CXOBJCPROP_ATTR(copy);9176  SET_CXOBJCPROP_ATTR(nonatomic);9177  SET_CXOBJCPROP_ATTR(setter);9178  SET_CXOBJCPROP_ATTR(atomic);9179  SET_CXOBJCPROP_ATTR(weak);9180  SET_CXOBJCPROP_ATTR(strong);9181  SET_CXOBJCPROP_ATTR(unsafe_unretained);9182  SET_CXOBJCPROP_ATTR(class);9183#undef SET_CXOBJCPROP_ATTR9184 9185  return Result;9186}9187 9188CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {9189  if (C.kind != CXCursor_ObjCPropertyDecl)9190    return cxstring::createNull();9191 9192  const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));9193  Selector sel = PD->getGetterName();9194  if (sel.isNull())9195    return cxstring::createNull();9196 9197  return cxstring::createDup(sel.getAsString());9198}9199 9200CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {9201  if (C.kind != CXCursor_ObjCPropertyDecl)9202    return cxstring::createNull();9203 9204  const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));9205  Selector sel = PD->getSetterName();9206  if (sel.isNull())9207    return cxstring::createNull();9208 9209  return cxstring::createDup(sel.getAsString());9210}9211 9212unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {9213  if (!clang_isDeclaration(C.kind))9214    return CXObjCDeclQualifier_None;9215 9216  Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;9217  const Decl *D = getCursorDecl(C);9218  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))9219    QT = MD->getObjCDeclQualifier();9220  else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))9221    QT = PD->getObjCDeclQualifier();9222  if (QT == Decl::OBJC_TQ_None)9223    return CXObjCDeclQualifier_None;9224 9225  unsigned Result = CXObjCDeclQualifier_None;9226  if (QT & Decl::OBJC_TQ_In)9227    Result |= CXObjCDeclQualifier_In;9228  if (QT & Decl::OBJC_TQ_Inout)9229    Result |= CXObjCDeclQualifier_Inout;9230  if (QT & Decl::OBJC_TQ_Out)9231    Result |= CXObjCDeclQualifier_Out;9232  if (QT & Decl::OBJC_TQ_Bycopy)9233    Result |= CXObjCDeclQualifier_Bycopy;9234  if (QT & Decl::OBJC_TQ_Byref)9235    Result |= CXObjCDeclQualifier_Byref;9236  if (QT & Decl::OBJC_TQ_Oneway)9237    Result |= CXObjCDeclQualifier_Oneway;9238 9239  return Result;9240}9241 9242unsigned clang_Cursor_isObjCOptional(CXCursor C) {9243  if (!clang_isDeclaration(C.kind))9244    return 0;9245 9246  const Decl *D = getCursorDecl(C);9247  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))9248    return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;9249  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))9250    return MD->getImplementationControl() ==9251           ObjCImplementationControl::Optional;9252 9253  return 0;9254}9255 9256unsigned clang_Cursor_isVariadic(CXCursor C) {9257  if (!clang_isDeclaration(C.kind))9258    return 0;9259 9260  const Decl *D = getCursorDecl(C);9261  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))9262    return FD->isVariadic();9263  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))9264    return MD->isVariadic();9265 9266  return 0;9267}9268 9269unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,9270                                       CXString *definedIn,9271                                       unsigned *isGenerated) {9272  if (!clang_isDeclaration(C.kind))9273    return 0;9274 9275  const Decl *D = getCursorDecl(C);9276 9277  if (auto *attr = D->getExternalSourceSymbolAttr()) {9278    if (language)9279      *language = cxstring::createDup(attr->getLanguage());9280    if (definedIn)9281      *definedIn = cxstring::createDup(attr->getDefinedIn());9282    if (isGenerated)9283      *isGenerated = attr->getGeneratedDeclaration();9284    return 1;9285  }9286  return 0;9287}9288 9289enum CX_BinaryOperatorKind clang_Cursor_getBinaryOpcode(CXCursor C) {9290  return static_cast<CX_BinaryOperatorKind>(9291      clang_getCursorBinaryOperatorKind(C));9292}9293 9294CXString clang_Cursor_getBinaryOpcodeStr(enum CX_BinaryOperatorKind Op) {9295  return clang_getBinaryOperatorKindSpelling(9296      static_cast<CXBinaryOperatorKind>(Op));9297}9298 9299CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {9300  if (!clang_isDeclaration(C.kind))9301    return clang_getNullRange();9302 9303  const Decl *D = getCursorDecl(C);9304  ASTContext &Context = getCursorContext(C);9305  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);9306  if (!RC)9307    return clang_getNullRange();9308 9309  return cxloc::translateSourceRange(Context, RC->getSourceRange());9310}9311 9312CXString clang_Cursor_getRawCommentText(CXCursor C) {9313  if (!clang_isDeclaration(C.kind))9314    return cxstring::createNull();9315 9316  const Decl *D = getCursorDecl(C);9317  ASTContext &Context = getCursorContext(C);9318  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);9319  StringRef RawText =9320      RC ? RC->getRawText(Context.getSourceManager()) : StringRef();9321 9322  // Don't duplicate the string because RawText points directly into source9323  // code.9324  return cxstring::createRef(RawText);9325}9326 9327CXString clang_Cursor_getBriefCommentText(CXCursor C) {9328  if (!clang_isDeclaration(C.kind))9329    return cxstring::createNull();9330 9331  const Decl *D = getCursorDecl(C);9332  const ASTContext &Context = getCursorContext(C);9333  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);9334 9335  if (RC) {9336    StringRef BriefText = RC->getBriefText(Context);9337 9338    // Don't duplicate the string because RawComment ensures that this memory9339    // will not go away.9340    return cxstring::createRef(BriefText);9341  }9342 9343  return cxstring::createNull();9344}9345 9346CXModule clang_Cursor_getModule(CXCursor C) {9347  if (C.kind == CXCursor_ModuleImportDecl) {9348    if (const ImportDecl *ImportD =9349            dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))9350      return ImportD->getImportedModule();9351  }9352 9353  return nullptr;9354}9355 9356CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {9357  if (isNotUsableTU(TU)) {9358    LOG_BAD_TU(TU);9359    return nullptr;9360  }9361  if (!File)9362    return nullptr;9363  FileEntryRef FE = *cxfile::getFileEntryRef(File);9364 9365  ASTUnit &Unit = *cxtu::getASTUnit(TU);9366  HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();9367  ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);9368 9369  return Header.getModule();9370}9371 9372CXFile clang_Module_getASTFile(CXModule CXMod) {9373  if (!CXMod)9374    return nullptr;9375  Module *Mod = static_cast<Module *>(CXMod);9376  return cxfile::makeCXFile(Mod->getASTFile());9377}9378 9379CXModule clang_Module_getParent(CXModule CXMod) {9380  if (!CXMod)9381    return nullptr;9382  Module *Mod = static_cast<Module *>(CXMod);9383  return Mod->Parent;9384}9385 9386CXString clang_Module_getName(CXModule CXMod) {9387  if (!CXMod)9388    return cxstring::createEmpty();9389  Module *Mod = static_cast<Module *>(CXMod);9390  return cxstring::createDup(Mod->Name);9391}9392 9393CXString clang_Module_getFullName(CXModule CXMod) {9394  if (!CXMod)9395    return cxstring::createEmpty();9396  Module *Mod = static_cast<Module *>(CXMod);9397  return cxstring::createDup(Mod->getFullModuleName());9398}9399 9400int clang_Module_isSystem(CXModule CXMod) {9401  if (!CXMod)9402    return 0;9403  Module *Mod = static_cast<Module *>(CXMod);9404  return Mod->IsSystem;9405}9406 9407unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,9408                                            CXModule CXMod) {9409  if (isNotUsableTU(TU)) {9410    LOG_BAD_TU(TU);9411    return 0;9412  }9413  if (!CXMod)9414    return 0;9415  Module *Mod = static_cast<Module *>(CXMod);9416  FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();9417  ArrayRef<FileEntryRef> TopHeaders = Mod->getTopHeaders(FileMgr);9418  return TopHeaders.size();9419}9420 9421CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,9422                                      unsigned Index) {9423  if (isNotUsableTU(TU)) {9424    LOG_BAD_TU(TU);9425    return nullptr;9426  }9427  if (!CXMod)9428    return nullptr;9429  Module *Mod = static_cast<Module *>(CXMod);9430  FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();9431 9432  ArrayRef<FileEntryRef> TopHeaders = Mod->getTopHeaders(FileMgr);9433  if (Index < TopHeaders.size())9434    return cxfile::makeCXFile(TopHeaders[Index]);9435 9436  return nullptr;9437}9438 9439//===----------------------------------------------------------------------===//9440// C++ AST instrospection.9441//===----------------------------------------------------------------------===//9442 9443unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {9444  if (!clang_isDeclaration(C.kind))9445    return 0;9446 9447  const Decl *D = cxcursor::getCursorDecl(C);9448  const CXXConstructorDecl *Constructor =9449      D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;9450  return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;9451}9452 9453unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {9454  if (!clang_isDeclaration(C.kind))9455    return 0;9456 9457  const Decl *D = cxcursor::getCursorDecl(C);9458  const CXXConstructorDecl *Constructor =9459      D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;9460  return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;9461}9462 9463unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {9464  if (!clang_isDeclaration(C.kind))9465    return 0;9466 9467  const Decl *D = cxcursor::getCursorDecl(C);9468  const CXXConstructorDecl *Constructor =9469      D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;9470  return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;9471}9472 9473unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {9474  if (!clang_isDeclaration(C.kind))9475    return 0;9476 9477  const Decl *D = cxcursor::getCursorDecl(C);9478  const CXXConstructorDecl *Constructor =9479      D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;9480  // Passing 'false' excludes constructors marked 'explicit'.9481  return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;9482}9483 9484unsigned clang_CXXField_isMutable(CXCursor C) {9485  if (!clang_isDeclaration(C.kind))9486    return 0;9487 9488  if (const auto D = cxcursor::getCursorDecl(C))9489    if (const auto FD = dyn_cast_or_null<FieldDecl>(D))9490      return FD->isMutable() ? 1 : 0;9491  return 0;9492}9493 9494unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {9495  if (!clang_isDeclaration(C.kind))9496    return 0;9497 9498  const Decl *D = cxcursor::getCursorDecl(C);9499  const CXXMethodDecl *Method =9500      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;9501  return (Method && Method->isPureVirtual()) ? 1 : 0;9502}9503 9504unsigned clang_CXXMethod_isConst(CXCursor C) {9505  if (!clang_isDeclaration(C.kind))9506    return 0;9507 9508  const Decl *D = cxcursor::getCursorDecl(C);9509  const CXXMethodDecl *Method =9510      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;9511  return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;9512}9513 9514unsigned clang_CXXMethod_isDefaulted(CXCursor C) {9515  if (!clang_isDeclaration(C.kind))9516    return 0;9517 9518  const Decl *D = cxcursor::getCursorDecl(C);9519  const CXXMethodDecl *Method =9520      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;9521  return (Method && Method->isDefaulted()) ? 1 : 0;9522}9523 9524unsigned clang_CXXMethod_isDeleted(CXCursor C) {9525  if (!clang_isDeclaration(C.kind))9526    return 0;9527 9528  const Decl *D = cxcursor::getCursorDecl(C);9529  const CXXMethodDecl *Method =9530      D ? dyn_cast_if_present<CXXMethodDecl>(D->getAsFunction()) : nullptr;9531  return (Method && Method->isDeleted()) ? 1 : 0;9532}9533 9534unsigned clang_CXXMethod_isStatic(CXCursor C) {9535  if (!clang_isDeclaration(C.kind))9536    return 0;9537 9538  const Decl *D = cxcursor::getCursorDecl(C);9539  const CXXMethodDecl *Method =9540      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;9541  return (Method && Method->isStatic()) ? 1 : 0;9542}9543 9544unsigned clang_CXXMethod_isVirtual(CXCursor C) {9545  if (!clang_isDeclaration(C.kind))9546    return 0;9547 9548  const Decl *D = cxcursor::getCursorDecl(C);9549  const CXXMethodDecl *Method =9550      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;9551  return (Method && Method->isVirtual()) ? 1 : 0;9552}9553 9554unsigned clang_CXXMethod_isCopyAssignmentOperator(CXCursor C) {9555  if (!clang_isDeclaration(C.kind))9556    return 0;9557 9558  const Decl *D = cxcursor::getCursorDecl(C);9559  const CXXMethodDecl *Method =9560      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;9561 9562  return (Method && Method->isCopyAssignmentOperator()) ? 1 : 0;9563}9564 9565unsigned clang_CXXMethod_isMoveAssignmentOperator(CXCursor C) {9566  if (!clang_isDeclaration(C.kind))9567    return 0;9568 9569  const Decl *D = cxcursor::getCursorDecl(C);9570  const CXXMethodDecl *Method =9571      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;9572 9573  return (Method && Method->isMoveAssignmentOperator()) ? 1 : 0;9574}9575 9576unsigned clang_CXXMethod_isExplicit(CXCursor C) {9577  if (!clang_isDeclaration(C.kind))9578    return 0;9579 9580  const Decl *D = cxcursor::getCursorDecl(C);9581  const FunctionDecl *FD = D->getAsFunction();9582 9583  if (!FD)9584    return 0;9585 9586  if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(FD))9587    return Ctor->isExplicit();9588 9589  if (const auto *Conv = dyn_cast<CXXConversionDecl>(FD))9590    return Conv->isExplicit();9591 9592  return 0;9593}9594 9595unsigned clang_CXXRecord_isAbstract(CXCursor C) {9596  if (!clang_isDeclaration(C.kind))9597    return 0;9598 9599  const auto *D = cxcursor::getCursorDecl(C);9600  const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);9601  if (RD)9602    RD = RD->getDefinition();9603  return (RD && RD->isAbstract()) ? 1 : 0;9604}9605 9606unsigned clang_EnumDecl_isScoped(CXCursor C) {9607  if (!clang_isDeclaration(C.kind))9608    return 0;9609 9610  const Decl *D = cxcursor::getCursorDecl(C);9611  auto *Enum = dyn_cast_or_null<EnumDecl>(D);9612  return (Enum && Enum->isScoped()) ? 1 : 0;9613}9614 9615//===----------------------------------------------------------------------===//9616// Attribute introspection.9617//===----------------------------------------------------------------------===//9618 9619CXType clang_getIBOutletCollectionType(CXCursor C) {9620  if (C.kind != CXCursor_IBOutletCollectionAttr)9621    return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));9622 9623  const IBOutletCollectionAttr *A =9624      cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));9625 9626  return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));9627}9628 9629//===----------------------------------------------------------------------===//9630// Inspecting memory usage.9631//===----------------------------------------------------------------------===//9632 9633typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;9634 9635static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,9636                                                enum CXTUResourceUsageKind k,9637                                                unsigned long amount) {9638  CXTUResourceUsageEntry entry = {k, amount};9639  entries.push_back(entry);9640}9641 9642const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {9643  const char *str = "";9644  switch (kind) {9645  case CXTUResourceUsage_AST:9646    str = "ASTContext: expressions, declarations, and types";9647    break;9648  case CXTUResourceUsage_Identifiers:9649    str = "ASTContext: identifiers";9650    break;9651  case CXTUResourceUsage_Selectors:9652    str = "ASTContext: selectors";9653    break;9654  case CXTUResourceUsage_GlobalCompletionResults:9655    str = "Code completion: cached global results";9656    break;9657  case CXTUResourceUsage_SourceManagerContentCache:9658    str = "SourceManager: content cache allocator";9659    break;9660  case CXTUResourceUsage_AST_SideTables:9661    str = "ASTContext: side tables";9662    break;9663  case CXTUResourceUsage_SourceManager_Membuffer_Malloc:9664    str = "SourceManager: malloc'ed memory buffers";9665    break;9666  case CXTUResourceUsage_SourceManager_Membuffer_MMap:9667    str = "SourceManager: mmap'ed memory buffers";9668    break;9669  case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:9670    str = "ExternalASTSource: malloc'ed memory buffers";9671    break;9672  case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:9673    str = "ExternalASTSource: mmap'ed memory buffers";9674    break;9675  case CXTUResourceUsage_Preprocessor:9676    str = "Preprocessor: malloc'ed memory";9677    break;9678  case CXTUResourceUsage_PreprocessingRecord:9679    str = "Preprocessor: PreprocessingRecord";9680    break;9681  case CXTUResourceUsage_SourceManager_DataStructures:9682    str = "SourceManager: data structures and tables";9683    break;9684  case CXTUResourceUsage_Preprocessor_HeaderSearch:9685    str = "Preprocessor: header search tables";9686    break;9687  }9688  return str;9689}9690 9691CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {9692  if (isNotUsableTU(TU)) {9693    LOG_BAD_TU(TU);9694    CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};9695    return usage;9696  }9697 9698  ASTUnit *astUnit = cxtu::getASTUnit(TU);9699  std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());9700  ASTContext &astContext = astUnit->getASTContext();9701 9702  // How much memory is used by AST nodes and types?9703  createCXTUResourceUsageEntry(9704      *entries, CXTUResourceUsage_AST,9705      (unsigned long)astContext.getASTAllocatedMemory());9706 9707  // How much memory is used by identifiers?9708  createCXTUResourceUsageEntry(9709      *entries, CXTUResourceUsage_Identifiers,9710      (unsigned long)astContext.Idents.getAllocator().getTotalMemory());9711 9712  // How much memory is used for selectors?9713  createCXTUResourceUsageEntry(9714      *entries, CXTUResourceUsage_Selectors,9715      (unsigned long)astContext.Selectors.getTotalMemory());9716 9717  // How much memory is used by ASTContext's side tables?9718  createCXTUResourceUsageEntry(9719      *entries, CXTUResourceUsage_AST_SideTables,9720      (unsigned long)astContext.getSideTableAllocatedMemory());9721 9722  // How much memory is used for caching global code completion results?9723  unsigned long completionBytes = 0;9724  if (GlobalCodeCompletionAllocator *completionAllocator =9725          astUnit->getCachedCompletionAllocator().get()) {9726    completionBytes = completionAllocator->getTotalMemory();9727  }9728  createCXTUResourceUsageEntry(9729      *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);9730 9731  // How much memory is being used by SourceManager's content cache?9732  createCXTUResourceUsageEntry(9733      *entries, CXTUResourceUsage_SourceManagerContentCache,9734      (unsigned long)astContext.getSourceManager().getContentCacheSize());9735 9736  // How much memory is being used by the MemoryBuffer's in SourceManager?9737  const SourceManager::MemoryBufferSizes &srcBufs =9738      astUnit->getSourceManager().getMemoryBufferSizes();9739 9740  createCXTUResourceUsageEntry(*entries,9741                               CXTUResourceUsage_SourceManager_Membuffer_Malloc,9742                               (unsigned long)srcBufs.malloc_bytes);9743  createCXTUResourceUsageEntry(*entries,9744                               CXTUResourceUsage_SourceManager_Membuffer_MMap,9745                               (unsigned long)srcBufs.mmap_bytes);9746  createCXTUResourceUsageEntry(9747      *entries, CXTUResourceUsage_SourceManager_DataStructures,9748      (unsigned long)astContext.getSourceManager().getDataStructureSizes());9749 9750  // How much memory is being used by the ExternalASTSource?9751  if (ExternalASTSource *esrc = astContext.getExternalSource()) {9752    const ExternalASTSource::MemoryBufferSizes &sizes =9753        esrc->getMemoryBufferSizes();9754 9755    createCXTUResourceUsageEntry(9756        *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,9757        (unsigned long)sizes.malloc_bytes);9758    createCXTUResourceUsageEntry(9759        *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,9760        (unsigned long)sizes.mmap_bytes);9761  }9762 9763  // How much memory is being used by the Preprocessor?9764  Preprocessor &pp = astUnit->getPreprocessor();9765  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,9766                               pp.getTotalMemory());9767 9768  if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {9769    createCXTUResourceUsageEntry(*entries,9770                                 CXTUResourceUsage_PreprocessingRecord,9771                                 pRec->getTotalMemory());9772  }9773 9774  createCXTUResourceUsageEntry(*entries,9775                               CXTUResourceUsage_Preprocessor_HeaderSearch,9776                               pp.getHeaderSearchInfo().getTotalMemory());9777 9778  CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),9779                             !entries->empty() ? &(*entries)[0] : nullptr};9780  (void)entries.release();9781  return usage;9782}9783 9784void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {9785  if (usage.data)9786    delete (MemUsageEntries *)usage.data;9787}9788 9789CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {9790  CXSourceRangeList *skipped = new CXSourceRangeList;9791  skipped->count = 0;9792  skipped->ranges = nullptr;9793 9794  if (isNotUsableTU(TU)) {9795    LOG_BAD_TU(TU);9796    return skipped;9797  }9798 9799  if (!file)9800    return skipped;9801 9802  ASTUnit *astUnit = cxtu::getASTUnit(TU);9803  PreprocessingRecord *ppRec =9804      astUnit->getPreprocessor().getPreprocessingRecord();9805  if (!ppRec)9806    return skipped;9807 9808  ASTContext &Ctx = astUnit->getASTContext();9809  SourceManager &sm = Ctx.getSourceManager();9810  FileEntryRef fileEntry = *cxfile::getFileEntryRef(file);9811  FileID wantedFileID = sm.translateFile(fileEntry);9812  bool isMainFile = wantedFileID == sm.getMainFileID();9813 9814  const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();9815  std::vector<SourceRange> wantedRanges;9816  for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),9817                                                ei = SkippedRanges.end();9818       i != ei; ++i) {9819    if (sm.getFileID(i->getBegin()) == wantedFileID ||9820        sm.getFileID(i->getEnd()) == wantedFileID)9821      wantedRanges.push_back(*i);9822    else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||9823                            astUnit->isInPreambleFileID(i->getEnd())))9824      wantedRanges.push_back(*i);9825  }9826 9827  skipped->count = wantedRanges.size();9828  skipped->ranges = new CXSourceRange[skipped->count];9829  for (unsigned i = 0, ei = skipped->count; i != ei; ++i)9830    skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);9831 9832  return skipped;9833}9834 9835CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {9836  CXSourceRangeList *skipped = new CXSourceRangeList;9837  skipped->count = 0;9838  skipped->ranges = nullptr;9839 9840  if (isNotUsableTU(TU)) {9841    LOG_BAD_TU(TU);9842    return skipped;9843  }9844 9845  ASTUnit *astUnit = cxtu::getASTUnit(TU);9846  PreprocessingRecord *ppRec =9847      astUnit->getPreprocessor().getPreprocessingRecord();9848  if (!ppRec)9849    return skipped;9850 9851  ASTContext &Ctx = astUnit->getASTContext();9852 9853  const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();9854 9855  skipped->count = SkippedRanges.size();9856  skipped->ranges = new CXSourceRange[skipped->count];9857  for (unsigned i = 0, ei = skipped->count; i != ei; ++i)9858    skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);9859 9860  return skipped;9861}9862 9863void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {9864  if (ranges) {9865    delete[] ranges->ranges;9866    delete ranges;9867  }9868}9869 9870void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {9871  CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);9872  for (unsigned I = 0; I != Usage.numEntries; ++I)9873    fprintf(stderr, "  %s: %lu\n",9874            clang_getTUResourceUsageName(Usage.entries[I].kind),9875            Usage.entries[I].amount);9876 9877  clang_disposeCXTUResourceUsage(Usage);9878}9879 9880CXCursor clang_Cursor_getVarDeclInitializer(CXCursor cursor) {9881  const Decl *const D = getCursorDecl(cursor);9882  if (!D)9883    return clang_getNullCursor();9884  const auto *const VD = dyn_cast<VarDecl>(D);9885  if (!VD)9886    return clang_getNullCursor();9887  const Expr *const Init = VD->getInit();9888  if (!Init)9889    return clang_getNullCursor();9890 9891  return cxcursor::MakeCXCursor(Init, VD, cxcursor::getCursorTU(cursor));9892}9893 9894int clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor) {9895  const Decl *const D = getCursorDecl(cursor);9896  if (!D)9897    return -1;9898  const auto *const VD = dyn_cast<VarDecl>(D);9899  if (!VD)9900    return -1;9901 9902  return VD->hasGlobalStorage();9903}9904 9905int clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor) {9906  const Decl *const D = getCursorDecl(cursor);9907  if (!D)9908    return -1;9909  const auto *const VD = dyn_cast<VarDecl>(D);9910  if (!VD)9911    return -1;9912 9913  return VD->hasExternalStorage();9914}9915 9916//===----------------------------------------------------------------------===//9917// Misc. utility functions.9918//===----------------------------------------------------------------------===//9919 9920/// Default to using our desired 8 MB stack size on "safety" threads.9921static unsigned SafetyStackThreadSize = DesiredStackSize;9922 9923namespace clang {9924 9925bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,9926               unsigned Size) {9927  if (!Size)9928    Size = GetSafetyThreadStackSize();9929  if (Size && !getenv("LIBCLANG_NOTHREADS"))9930    return CRC.RunSafelyOnThread(Fn, Size);9931  return CRC.RunSafely(Fn);9932}9933 9934unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }9935 9936void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }9937 9938} // namespace clang9939 9940void clang::setThreadBackgroundPriority() {9941  if (getenv("LIBCLANG_BGPRIO_DISABLE"))9942    return;9943 9944#if LLVM_ENABLE_THREADS9945  // The function name setThreadBackgroundPriority is for historical reasons;9946  // Low is more appropriate.9947  llvm::set_thread_priority(llvm::ThreadPriority::Low);9948#endif9949}9950 9951void cxindex::printDiagsToStderr(ASTUnit *Unit) {9952  if (!Unit)9953    return;9954 9955  for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),9956                                     DEnd = Unit->stored_diag_end();9957       D != DEnd; ++D) {9958    CXStoredDiagnostic Diag(*D, Unit->getLangOpts());9959    CXString Msg =9960        clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());9961    fprintf(stderr, "%s\n", clang_getCString(Msg));9962    clang_disposeString(Msg);9963  }9964#ifdef _WIN329965  // On Windows, force a flush, since there may be multiple copies of9966  // stderr and stdout in the file system, all with different buffers9967  // but writing to the same device.9968  fflush(stderr);9969#endif9970}9971 9972MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,9973                                 SourceLocation MacroDefLoc,9974                                 CXTranslationUnit TU) {9975  if (MacroDefLoc.isInvalid() || !TU)9976    return nullptr;9977  if (!II.hadMacroDefinition())9978    return nullptr;9979 9980  ASTUnit *Unit = cxtu::getASTUnit(TU);9981  Preprocessor &PP = Unit->getPreprocessor();9982  MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);9983  if (MD) {9984    for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;9985         Def = Def.getPreviousDefinition()) {9986      if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())9987        return Def.getMacroInfo();9988    }9989  }9990 9991  return nullptr;9992}9993 9994const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,9995                                       CXTranslationUnit TU) {9996  if (!MacroDef || !TU)9997    return nullptr;9998  const IdentifierInfo *II = MacroDef->getName();9999  if (!II)10000    return nullptr;10001 10002  return getMacroInfo(*II, MacroDef->getLocation(), TU);10003}10004 10005MacroDefinitionRecord *10006cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,10007                                        CXTranslationUnit TU) {10008  if (!MI || !TU)10009    return nullptr;10010  if (Tok.isNot(tok::raw_identifier))10011    return nullptr;10012 10013  if (MI->getNumTokens() == 0)10014    return nullptr;10015  SourceRange DefRange(MI->getReplacementToken(0).getLocation(),10016                       MI->getDefinitionEndLoc());10017  ASTUnit *Unit = cxtu::getASTUnit(TU);10018 10019  // Check that the token is inside the definition and not its argument list.10020  SourceManager &SM = Unit->getSourceManager();10021  if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))10022    return nullptr;10023  if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))10024    return nullptr;10025 10026  Preprocessor &PP = Unit->getPreprocessor();10027  PreprocessingRecord *PPRec = PP.getPreprocessingRecord();10028  if (!PPRec)10029    return nullptr;10030 10031  IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());10032  if (!II.hadMacroDefinition())10033    return nullptr;10034 10035  // Check that the identifier is not one of the macro arguments.10036  if (llvm::is_contained(MI->params(), &II))10037    return nullptr;10038 10039  MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);10040  if (!InnerMD)10041    return nullptr;10042 10043  return PPRec->findMacroDefinition(InnerMD->getMacroInfo());10044}10045 10046MacroDefinitionRecord *10047cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,10048                                        CXTranslationUnit TU) {10049  if (Loc.isInvalid() || !MI || !TU)10050    return nullptr;10051 10052  if (MI->getNumTokens() == 0)10053    return nullptr;10054  ASTUnit *Unit = cxtu::getASTUnit(TU);10055  Preprocessor &PP = Unit->getPreprocessor();10056  if (!PP.getPreprocessingRecord())10057    return nullptr;10058  Loc = Unit->getSourceManager().getSpellingLoc(Loc);10059  Token Tok;10060  if (PP.getRawToken(Loc, Tok))10061    return nullptr;10062 10063  return checkForMacroInMacroDefinition(MI, Tok, TU);10064}10065 10066CXString clang_getClangVersion() {10067  return cxstring::createDup(getClangFullVersion());10068}10069 10070Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {10071  if (TU) {10072    if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {10073      LogOS << '<' << Unit->getMainFileName() << '>';10074      if (Unit->isMainFileAST())10075        LogOS << " (" << Unit->getASTFileName() << ')';10076      return *this;10077    }10078  } else {10079    LogOS << "<NULL TU>";10080  }10081  return *this;10082}10083 10084Logger &cxindex::Logger::operator<<(FileEntryRef FE) {10085  *this << FE.getName();10086  return *this;10087}10088 10089Logger &cxindex::Logger::operator<<(CXCursor cursor) {10090  CXString cursorName = clang_getCursorDisplayName(cursor);10091  *this << cursorName << "@" << clang_getCursorLocation(cursor);10092  clang_disposeString(cursorName);10093  return *this;10094}10095 10096Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {10097  CXFile File;10098  unsigned Line, Column;10099  clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);10100  CXString FileName = clang_getFileName(File);10101  *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);10102  clang_disposeString(FileName);10103  return *this;10104}10105 10106Logger &cxindex::Logger::operator<<(CXSourceRange range) {10107  CXSourceLocation BLoc = clang_getRangeStart(range);10108  CXSourceLocation ELoc = clang_getRangeEnd(range);10109 10110  CXFile BFile;10111  unsigned BLine, BColumn;10112  clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);10113 10114  CXFile EFile;10115  unsigned ELine, EColumn;10116  clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);10117 10118  CXString BFileName = clang_getFileName(BFile);10119  if (BFile == EFile) {10120    *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),10121                          BLine, BColumn, ELine, EColumn);10122  } else {10123    CXString EFileName = clang_getFileName(EFile);10124    *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,10125                          BColumn)10126          << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,10127                          EColumn);10128    clang_disposeString(EFileName);10129  }10130  clang_disposeString(BFileName);10131  return *this;10132}10133 10134Logger &cxindex::Logger::operator<<(CXString Str) {10135  *this << clang_getCString(Str);10136  return *this;10137}10138 10139Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {10140  LogOS << Fmt;10141  return *this;10142}10143 10144static llvm::ManagedStatic<std::mutex> LoggingMutex;10145 10146cxindex::Logger::~Logger() {10147  std::lock_guard<std::mutex> L(*LoggingMutex);10148 10149  static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();10150 10151  raw_ostream &OS = llvm::errs();10152  OS << "[libclang:" << Name << ':';10153 10154#ifdef USE_DARWIN_THREADS10155  // TODO: Portability.10156  mach_port_t tid = pthread_mach_thread_np(pthread_self());10157  OS << tid << ':';10158#endif10159 10160  llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();10161  OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());10162  OS << Msg << '\n';10163 10164  if (Trace) {10165    llvm::sys::PrintStackTrace(OS);10166    OS << "--------------------------------------------------\n";10167  }10168}10169 10170CXString clang_getBinaryOperatorKindSpelling(enum CXBinaryOperatorKind kind) {10171  if (kind > CXBinaryOperator_Last)10172    return cxstring::createEmpty();10173 10174  return cxstring::createDup(10175      BinaryOperator::getOpcodeStr(static_cast<BinaryOperatorKind>(kind - 1)));10176}10177 10178enum CXBinaryOperatorKind clang_getCursorBinaryOperatorKind(CXCursor cursor) {10179  if (clang_isExpression(cursor.kind)) {10180    const Expr *expr = getCursorExpr(cursor);10181 10182    if (const auto *op = dyn_cast<BinaryOperator>(expr))10183      return static_cast<CXBinaryOperatorKind>(op->getOpcode() + 1);10184 10185    if (const auto *op = dyn_cast<CXXRewrittenBinaryOperator>(expr))10186      return static_cast<CXBinaryOperatorKind>(op->getOpcode() + 1);10187  }10188 10189  return CXBinaryOperator_Invalid;10190}10191 10192CXString clang_getUnaryOperatorKindSpelling(enum CXUnaryOperatorKind kind) {10193  return cxstring::createRef(10194      UnaryOperator::getOpcodeStr(static_cast<UnaryOperatorKind>(kind - 1)));10195}10196 10197enum CXUnaryOperatorKind clang_getCursorUnaryOperatorKind(CXCursor cursor) {10198  if (clang_isExpression(cursor.kind)) {10199    const Expr *expr = getCursorExpr(cursor);10200 10201    if (const auto *op = dyn_cast<UnaryOperator>(expr))10202      return static_cast<CXUnaryOperatorKind>(op->getOpcode() + 1);10203  }10204 10205  return CXUnaryOperator_Invalid;10206}10207