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