[LoongArch][Clang] Make the parameters and return value of {x,}vorn.v builti ns ...
[llvm-project.git] / clang / tools / libclang / CIndex.cpp
blobcec6f026fccfd8b8f4a3d5c125400614ed406ece
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the main API hooks in the Clang-C Source Indexing
10 // library.
12 //===----------------------------------------------------------------------===//
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/Frontend/ASTUnit.h"
42 #include "clang/Frontend/CompilerInstance.h"
43 #include "clang/Index/CommentToXML.h"
44 #include "clang/Lex/HeaderSearch.h"
45 #include "clang/Lex/Lexer.h"
46 #include "clang/Lex/PreprocessingRecord.h"
47 #include "clang/Lex/Preprocessor.h"
48 #include "llvm/ADT/STLExtras.h"
49 #include "llvm/ADT/StringSwitch.h"
50 #include "llvm/Config/llvm-config.h"
51 #include "llvm/Support/Compiler.h"
52 #include "llvm/Support/CrashRecoveryContext.h"
53 #include "llvm/Support/Format.h"
54 #include "llvm/Support/ManagedStatic.h"
55 #include "llvm/Support/MemoryBuffer.h"
56 #include "llvm/Support/Program.h"
57 #include "llvm/Support/SaveAndRestore.h"
58 #include "llvm/Support/Signals.h"
59 #include "llvm/Support/TargetSelect.h"
60 #include "llvm/Support/Threading.h"
61 #include "llvm/Support/Timer.h"
62 #include "llvm/Support/raw_ostream.h"
63 #include "llvm/Support/thread.h"
64 #include <mutex>
65 #include <optional>
67 #if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
68 #define USE_DARWIN_THREADS
69 #endif
71 #ifdef USE_DARWIN_THREADS
72 #include <pthread.h>
73 #endif
75 using namespace clang;
76 using namespace clang::cxcursor;
77 using namespace clang::cxtu;
78 using namespace clang::cxindex;
80 CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,
81 std::unique_ptr<ASTUnit> AU) {
82 if (!AU)
83 return nullptr;
84 assert(CIdx);
85 CXTranslationUnit D = new CXTranslationUnitImpl();
86 D->CIdx = CIdx;
87 D->TheASTUnit = AU.release();
88 D->StringPool = new cxstring::CXStringPool();
89 D->Diagnostics = nullptr;
90 D->OverridenCursorsPool = createOverridenCXCursorsPool();
91 D->CommentToXML = nullptr;
92 D->ParsingOptions = 0;
93 D->Arguments = {};
94 return D;
97 bool cxtu::isASTReadError(ASTUnit *AU) {
98 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
99 DEnd = AU->stored_diag_end();
100 D != DEnd; ++D) {
101 if (D->getLevel() >= DiagnosticsEngine::Error &&
102 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
103 diag::DiagCat_AST_Deserialization_Issue)
104 return true;
106 return false;
109 cxtu::CXTUOwner::~CXTUOwner() {
110 if (TU)
111 clang_disposeTranslationUnit(TU);
114 /// Compare two source ranges to determine their relative position in
115 /// the translation unit.
116 static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1,
117 SourceRange R2) {
118 assert(R1.isValid() && "First range is invalid?");
119 assert(R2.isValid() && "Second range is invalid?");
120 if (R1.getEnd() != R2.getBegin() &&
121 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
122 return RangeBefore;
123 if (R2.getEnd() != R1.getBegin() &&
124 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
125 return RangeAfter;
126 return RangeOverlap;
129 /// Determine if a source location falls within, before, or after a
130 /// a given source range.
131 static RangeComparisonResult LocationCompare(SourceManager &SM,
132 SourceLocation L, SourceRange R) {
133 assert(R.isValid() && "First range is invalid?");
134 assert(L.isValid() && "Second range is invalid?");
135 if (L == R.getBegin() || L == R.getEnd())
136 return RangeOverlap;
137 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
138 return RangeBefore;
139 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
140 return RangeAfter;
141 return RangeOverlap;
144 /// Translate a Clang source range into a CIndex source range.
146 /// Clang internally represents ranges where the end location points to the
147 /// start of the token at the end. However, for external clients it is more
148 /// useful to have a CXSourceRange be a proper half-open interval. This routine
149 /// does the appropriate translation.
150 CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
151 const LangOptions &LangOpts,
152 const CharSourceRange &R) {
153 // We want the last character in this location, so we will adjust the
154 // location accordingly.
155 SourceLocation EndLoc = R.getEnd();
156 bool IsTokenRange = R.isTokenRange();
157 if (EndLoc.isValid() && EndLoc.isMacroID() &&
158 !SM.isMacroArgExpansion(EndLoc)) {
159 CharSourceRange Expansion = SM.getExpansionRange(EndLoc);
160 EndLoc = Expansion.getEnd();
161 IsTokenRange = Expansion.isTokenRange();
163 if (IsTokenRange && EndLoc.isValid()) {
164 unsigned Length =
165 Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);
166 EndLoc = EndLoc.getLocWithOffset(Length);
169 CXSourceRange Result = {
170 {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};
171 return Result;
174 CharSourceRange cxloc::translateCXRangeToCharRange(CXSourceRange R) {
175 return CharSourceRange::getCharRange(
176 SourceLocation::getFromRawEncoding(R.begin_int_data),
177 SourceLocation::getFromRawEncoding(R.end_int_data));
180 //===----------------------------------------------------------------------===//
181 // Cursor visitor.
182 //===----------------------------------------------------------------------===//
184 static SourceRange getRawCursorExtent(CXCursor C);
185 static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
187 RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
188 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
191 /// Visit the given cursor and, if requested by the visitor,
192 /// its children.
194 /// \param Cursor the cursor to visit.
196 /// \param CheckedRegionOfInterest if true, then the caller already checked
197 /// that this cursor is within the region of interest.
199 /// \returns true if the visitation should be aborted, false if it
200 /// should continue.
201 bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
202 if (clang_isInvalid(Cursor.kind))
203 return false;
205 if (clang_isDeclaration(Cursor.kind)) {
206 const Decl *D = getCursorDecl(Cursor);
207 if (!D) {
208 assert(0 && "Invalid declaration cursor");
209 return true; // abort.
212 // Ignore implicit declarations, unless it's an objc method because
213 // currently we should report implicit methods for properties when indexing.
214 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
215 return false;
218 // If we have a range of interest, and this cursor doesn't intersect with it,
219 // we're done.
220 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
221 SourceRange Range = getRawCursorExtent(Cursor);
222 if (Range.isInvalid() || CompareRegionOfInterest(Range))
223 return false;
226 switch (Visitor(Cursor, Parent, ClientData)) {
227 case CXChildVisit_Break:
228 return true;
230 case CXChildVisit_Continue:
231 return false;
233 case CXChildVisit_Recurse: {
234 bool ret = VisitChildren(Cursor);
235 if (PostChildrenVisitor)
236 if (PostChildrenVisitor(Cursor, ClientData))
237 return true;
238 return ret;
242 llvm_unreachable("Invalid CXChildVisitResult!");
245 static bool visitPreprocessedEntitiesInRange(SourceRange R,
246 PreprocessingRecord &PPRec,
247 CursorVisitor &Visitor) {
248 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
249 FileID FID;
251 if (!Visitor.shouldVisitIncludedEntities()) {
252 // If the begin/end of the range lie in the same FileID, do the optimization
253 // where we skip preprocessed entities that do not come from the same
254 // FileID.
255 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
256 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
257 FID = FileID();
260 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
261 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
262 PPRec, FID);
265 bool CursorVisitor::visitFileRegion() {
266 if (RegionOfInterest.isInvalid())
267 return false;
269 ASTUnit *Unit = cxtu::getASTUnit(TU);
270 SourceManager &SM = Unit->getSourceManager();
272 std::pair<FileID, unsigned> Begin = SM.getDecomposedLoc(
273 SM.getFileLoc(RegionOfInterest.getBegin())),
274 End = SM.getDecomposedLoc(
275 SM.getFileLoc(RegionOfInterest.getEnd()));
277 if (End.first != Begin.first) {
278 // If the end does not reside in the same file, try to recover by
279 // picking the end of the file of begin location.
280 End.first = Begin.first;
281 End.second = SM.getFileIDSize(Begin.first);
284 assert(Begin.first == End.first);
285 if (Begin.second > End.second)
286 return false;
288 FileID File = Begin.first;
289 unsigned Offset = Begin.second;
290 unsigned Length = End.second - Begin.second;
292 if (!VisitDeclsOnly && !VisitPreprocessorLast)
293 if (visitPreprocessedEntitiesInRegion())
294 return true; // visitation break.
296 if (visitDeclsFromFileRegion(File, Offset, Length))
297 return true; // visitation break.
299 if (!VisitDeclsOnly && VisitPreprocessorLast)
300 return visitPreprocessedEntitiesInRegion();
302 return false;
305 static bool isInLexicalContext(Decl *D, DeclContext *DC) {
306 if (!DC)
307 return false;
309 for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;
310 DeclDC = DeclDC->getLexicalParent()) {
311 if (DeclDC == DC)
312 return true;
314 return false;
317 bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,
318 unsigned Length) {
319 ASTUnit *Unit = cxtu::getASTUnit(TU);
320 SourceManager &SM = Unit->getSourceManager();
321 SourceRange Range = RegionOfInterest;
323 SmallVector<Decl *, 16> Decls;
324 Unit->findFileRegionDecls(File, Offset, Length, Decls);
326 // If we didn't find any file level decls for the file, try looking at the
327 // file that it was included from.
328 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
329 bool Invalid = false;
330 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
331 if (Invalid)
332 return false;
334 SourceLocation Outer;
335 if (SLEntry.isFile())
336 Outer = SLEntry.getFile().getIncludeLoc();
337 else
338 Outer = SLEntry.getExpansion().getExpansionLocStart();
339 if (Outer.isInvalid())
340 return false;
342 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
343 Length = 0;
344 Unit->findFileRegionDecls(File, Offset, Length, Decls);
347 assert(!Decls.empty());
349 bool VisitedAtLeastOnce = false;
350 DeclContext *CurDC = nullptr;
351 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
352 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
353 Decl *D = *DIt;
354 if (D->getSourceRange().isInvalid())
355 continue;
357 if (isInLexicalContext(D, CurDC))
358 continue;
360 CurDC = dyn_cast<DeclContext>(D);
362 if (TagDecl *TD = dyn_cast<TagDecl>(D))
363 if (!TD->isFreeStanding())
364 continue;
366 RangeComparisonResult CompRes =
367 RangeCompare(SM, D->getSourceRange(), Range);
368 if (CompRes == RangeBefore)
369 continue;
370 if (CompRes == RangeAfter)
371 break;
373 assert(CompRes == RangeOverlap);
374 VisitedAtLeastOnce = true;
376 if (isa<ObjCContainerDecl>(D)) {
377 FileDI_current = &DIt;
378 FileDE_current = DE;
379 } else {
380 FileDI_current = nullptr;
383 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
384 return true; // visitation break.
387 if (VisitedAtLeastOnce)
388 return false;
390 // No Decls overlapped with the range. Move up the lexical context until there
391 // is a context that contains the range or we reach the translation unit
392 // level.
393 DeclContext *DC = DIt == Decls.begin()
394 ? (*DIt)->getLexicalDeclContext()
395 : (*(DIt - 1))->getLexicalDeclContext();
397 while (DC && !DC->isTranslationUnit()) {
398 Decl *D = cast<Decl>(DC);
399 SourceRange CurDeclRange = D->getSourceRange();
400 if (CurDeclRange.isInvalid())
401 break;
403 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
404 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
405 return true; // visitation break.
408 DC = D->getLexicalDeclContext();
411 return false;
414 bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
415 if (!AU->getPreprocessor().getPreprocessingRecord())
416 return false;
418 PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();
419 SourceManager &SM = AU->getSourceManager();
421 if (RegionOfInterest.isValid()) {
422 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
423 SourceLocation B = MappedRange.getBegin();
424 SourceLocation E = MappedRange.getEnd();
426 if (AU->isInPreambleFileID(B)) {
427 if (SM.isLoadedSourceLocation(E))
428 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,
429 *this);
431 // Beginning of range lies in the preamble but it also extends beyond
432 // it into the main file. Split the range into 2 parts, one covering
433 // the preamble and another covering the main file. This allows subsequent
434 // calls to visitPreprocessedEntitiesInRange to accept a source range that
435 // lies in the same FileID, allowing it to skip preprocessed entities that
436 // do not come from the same FileID.
437 bool breaked = visitPreprocessedEntitiesInRange(
438 SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);
439 if (breaked)
440 return true;
441 return visitPreprocessedEntitiesInRange(
442 SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);
445 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
448 bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
450 if (OnlyLocalDecls)
451 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
452 PPRec);
454 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
457 template <typename InputIterator>
458 bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
459 InputIterator Last,
460 PreprocessingRecord &PPRec,
461 FileID FID) {
462 for (; First != Last; ++First) {
463 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
464 continue;
466 PreprocessedEntity *PPE = *First;
467 if (!PPE)
468 continue;
470 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
471 if (Visit(MakeMacroExpansionCursor(ME, TU)))
472 return true;
474 continue;
477 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
478 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
479 return true;
481 continue;
484 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
485 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
486 return true;
488 continue;
492 return false;
495 /// Visit the children of the given cursor.
497 /// \returns true if the visitation should be aborted, false if it
498 /// should continue.
499 bool CursorVisitor::VisitChildren(CXCursor Cursor) {
500 if (clang_isReference(Cursor.kind) &&
501 Cursor.kind != CXCursor_CXXBaseSpecifier) {
502 // By definition, references have no children.
503 return false;
506 // Set the Parent field to Cursor, then back to its old value once we're
507 // done.
508 SetParentRAII SetParent(Parent, StmtParent, Cursor);
510 if (clang_isDeclaration(Cursor.kind)) {
511 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
512 if (!D)
513 return false;
515 return VisitAttributes(D) || Visit(D);
518 if (clang_isStatement(Cursor.kind)) {
519 if (const Stmt *S = getCursorStmt(Cursor))
520 return Visit(S);
522 return false;
525 if (clang_isExpression(Cursor.kind)) {
526 if (const Expr *E = getCursorExpr(Cursor))
527 return Visit(E);
529 return false;
532 if (clang_isTranslationUnit(Cursor.kind)) {
533 CXTranslationUnit TU = getCursorTU(Cursor);
534 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
536 int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
537 for (unsigned I = 0; I != 2; ++I) {
538 if (VisitOrder[I]) {
539 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
540 RegionOfInterest.isInvalid()) {
541 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
542 TLEnd = CXXUnit->top_level_end();
543 TL != TLEnd; ++TL) {
544 const std::optional<bool> V = handleDeclForVisitation(*TL);
545 if (!V)
546 continue;
547 return *V;
549 } else if (VisitDeclContext(
550 CXXUnit->getASTContext().getTranslationUnitDecl()))
551 return true;
552 continue;
555 // Walk the preprocessing record.
556 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
557 visitPreprocessedEntitiesInRegion();
560 return false;
563 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
564 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
565 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
566 return Visit(BaseTSInfo->getTypeLoc());
571 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
572 const IBOutletCollectionAttr *A =
573 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
574 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
575 return Visit(cxcursor::MakeCursorObjCClassRef(
576 ObjT->getInterface(),
577 A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));
580 if (clang_isAttribute(Cursor.kind)) {
581 if (const Attr *A = getCursorAttr(Cursor))
582 return Visit(A);
584 return false;
587 // If pointing inside a macro definition, check if the token is an identifier
588 // that was ever defined as a macro. In such a case, create a "pseudo" macro
589 // expansion cursor for that token.
590 SourceLocation BeginLoc = RegionOfInterest.getBegin();
591 if (Cursor.kind == CXCursor_MacroDefinition &&
592 BeginLoc == RegionOfInterest.getEnd()) {
593 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
594 const MacroInfo *MI =
595 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
596 if (MacroDefinitionRecord *MacroDef =
597 checkForMacroInMacroDefinition(MI, Loc, TU))
598 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
601 // Nothing to visit at the moment.
602 return false;
605 bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
606 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
607 if (Visit(TSInfo->getTypeLoc()))
608 return true;
610 if (Stmt *Body = B->getBody())
611 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
613 return false;
616 std::optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
617 if (RegionOfInterest.isValid()) {
618 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
619 if (Range.isInvalid())
620 return std::nullopt;
622 switch (CompareRegionOfInterest(Range)) {
623 case RangeBefore:
624 // This declaration comes before the region of interest; skip it.
625 return std::nullopt;
627 case RangeAfter:
628 // This declaration comes after the region of interest; we're done.
629 return false;
631 case RangeOverlap:
632 // This declaration overlaps the region of interest; visit it.
633 break;
636 return true;
639 bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
640 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
642 // FIXME: Eventually remove. This part of a hack to support proper
643 // iteration over all Decls contained lexically within an ObjC container.
644 SaveAndRestore DI_saved(DI_current, &I);
645 SaveAndRestore DE_saved(DE_current, E);
647 for (; I != E; ++I) {
648 Decl *D = *I;
649 if (D->getLexicalDeclContext() != DC)
650 continue;
651 // Filter out synthesized property accessor redeclarations.
652 if (isa<ObjCImplDecl>(DC))
653 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
654 if (OMD->isSynthesizedAccessorStub())
655 continue;
656 const std::optional<bool> V = handleDeclForVisitation(D);
657 if (!V)
658 continue;
659 return *V;
661 return false;
664 std::optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
665 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
667 // Ignore synthesized ivars here, otherwise if we have something like:
668 // @synthesize prop = _prop;
669 // and '_prop' is not declared, we will encounter a '_prop' ivar before
670 // encountering the 'prop' synthesize declaration and we will think that
671 // we passed the region-of-interest.
672 if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
673 if (ivarD->getSynthesize())
674 return std::nullopt;
677 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
678 // declarations is a mismatch with the compiler semantics.
679 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
680 auto *ID = cast<ObjCInterfaceDecl>(D);
681 if (!ID->isThisDeclarationADefinition())
682 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
684 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
685 auto *PD = cast<ObjCProtocolDecl>(D);
686 if (!PD->isThisDeclarationADefinition())
687 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
690 const std::optional<bool> V = shouldVisitCursor(Cursor);
691 if (!V)
692 return std::nullopt;
693 if (!*V)
694 return false;
695 if (Visit(Cursor, true))
696 return true;
697 return std::nullopt;
700 bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
701 llvm_unreachable("Translation units are visited directly by Visit()");
704 bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
705 if (VisitTemplateParameters(D->getTemplateParameters()))
706 return true;
708 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
711 bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
712 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
713 return Visit(TSInfo->getTypeLoc());
715 return false;
718 bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
719 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
720 return Visit(TSInfo->getTypeLoc());
722 return false;
725 bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }
727 bool CursorVisitor::VisitClassTemplateSpecializationDecl(
728 ClassTemplateSpecializationDecl *D) {
729 bool ShouldVisitBody = false;
730 switch (D->getSpecializationKind()) {
731 case TSK_Undeclared:
732 case TSK_ImplicitInstantiation:
733 // Nothing to visit
734 return false;
736 case TSK_ExplicitInstantiationDeclaration:
737 case TSK_ExplicitInstantiationDefinition:
738 break;
740 case TSK_ExplicitSpecialization:
741 ShouldVisitBody = true;
742 break;
745 // Visit the template arguments used in the specialization.
746 if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) {
747 for (const TemplateArgumentLoc &Arg : ArgsWritten->arguments())
748 if (VisitTemplateArgumentLoc(Arg))
749 return true;
752 return ShouldVisitBody && VisitCXXRecordDecl(D);
755 bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
756 ClassTemplatePartialSpecializationDecl *D) {
757 // FIXME: Visit the "outer" template parameter lists on the TagDecl
758 // before visiting these template parameters.
759 if (VisitTemplateParameters(D->getTemplateParameters()))
760 return true;
762 // Visit the partial specialization arguments.
763 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
764 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
765 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
766 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
767 return true;
769 return VisitCXXRecordDecl(D);
772 bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
773 if (const auto *TC = D->getTypeConstraint()) {
774 if (VisitTypeConstraint(*TC))
775 return true;
778 // Visit the default argument.
779 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
780 VisitTemplateArgumentLoc(D->getDefaultArgument()))
781 return true;
783 return false;
786 bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
787 if (Expr *Init = D->getInitExpr())
788 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
789 return false;
792 bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
793 unsigned NumParamList = DD->getNumTemplateParameterLists();
794 for (unsigned i = 0; i < NumParamList; i++) {
795 TemplateParameterList *Params = DD->getTemplateParameterList(i);
796 if (VisitTemplateParameters(Params))
797 return true;
800 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
801 if (Visit(TSInfo->getTypeLoc()))
802 return true;
804 // Visit the nested-name-specifier, if present.
805 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
806 if (VisitNestedNameSpecifierLoc(QualifierLoc))
807 return true;
809 return false;
812 static bool HasTrailingReturnType(FunctionDecl *ND) {
813 const QualType Ty = ND->getType();
814 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
815 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
816 return FT->hasTrailingReturn();
819 return false;
822 /// Compare two base or member initializers based on their source order.
823 static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
824 CXXCtorInitializer *const *Y) {
825 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
828 bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
829 unsigned NumParamList = ND->getNumTemplateParameterLists();
830 for (unsigned i = 0; i < NumParamList; i++) {
831 TemplateParameterList *Params = ND->getTemplateParameterList(i);
832 if (VisitTemplateParameters(Params))
833 return true;
836 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
837 // Visit the function declaration's syntactic components in the order
838 // written. This requires a bit of work.
839 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
840 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
841 const bool HasTrailingRT = HasTrailingReturnType(ND);
843 // If we have a function declared directly (without the use of a typedef),
844 // visit just the return type. Otherwise, just visit the function's type
845 // now.
846 if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
847 Visit(FTL.getReturnLoc())) ||
848 (!FTL && Visit(TL)))
849 return true;
851 // Visit the nested-name-specifier, if present.
852 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
853 if (VisitNestedNameSpecifierLoc(QualifierLoc))
854 return true;
856 // Visit the declaration name.
857 if (!isa<CXXDestructorDecl>(ND))
858 if (VisitDeclarationNameInfo(ND->getNameInfo()))
859 return true;
861 // FIXME: Visit explicitly-specified template arguments!
863 // Visit the function parameters, if we have a function type.
864 if (FTL && VisitFunctionTypeLoc(FTL, true))
865 return true;
867 // Visit the function's trailing return type.
868 if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
869 return true;
871 // FIXME: Attributes?
874 if (auto *E = ND->getTrailingRequiresClause()) {
875 if (Visit(E))
876 return true;
879 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
880 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
881 // Find the initializers that were written in the source.
882 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
883 for (auto *I : Constructor->inits()) {
884 if (!I->isWritten())
885 continue;
887 WrittenInits.push_back(I);
890 // Sort the initializers in source order
891 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
892 &CompareCXXCtorInitializers);
894 // Visit the initializers in source order
895 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
896 CXXCtorInitializer *Init = WrittenInits[I];
897 if (Init->isAnyMemberInitializer()) {
898 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
899 Init->getMemberLocation(), TU)))
900 return true;
901 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
902 if (Visit(TInfo->getTypeLoc()))
903 return true;
906 // Visit the initializer value.
907 if (Expr *Initializer = Init->getInit())
908 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
909 return true;
913 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
914 return true;
917 return false;
920 bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
921 if (VisitDeclaratorDecl(D))
922 return true;
924 if (Expr *BitWidth = D->getBitWidth())
925 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
927 if (Expr *Init = D->getInClassInitializer())
928 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
930 return false;
933 bool CursorVisitor::VisitVarDecl(VarDecl *D) {
934 if (VisitDeclaratorDecl(D))
935 return true;
937 if (Expr *Init = D->getInit())
938 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
940 return false;
943 bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
944 if (VisitDeclaratorDecl(D))
945 return true;
947 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
948 if (D->hasDefaultArgument() &&
949 VisitTemplateArgumentLoc(D->getDefaultArgument()))
950 return true;
952 return false;
955 bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
956 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
957 // before visiting these template parameters.
958 if (VisitTemplateParameters(D->getTemplateParameters()))
959 return true;
961 auto *FD = D->getTemplatedDecl();
962 return VisitAttributes(FD) || VisitFunctionDecl(FD);
965 bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
966 // FIXME: Visit the "outer" template parameter lists on the TagDecl
967 // before visiting these template parameters.
968 if (VisitTemplateParameters(D->getTemplateParameters()))
969 return true;
971 auto *CD = D->getTemplatedDecl();
972 return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
975 bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
976 if (VisitTemplateParameters(D->getTemplateParameters()))
977 return true;
979 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
980 VisitTemplateArgumentLoc(D->getDefaultArgument()))
981 return true;
983 return false;
986 bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
987 // Visit the bound, if it's explicit.
988 if (D->hasExplicitBound()) {
989 if (auto TInfo = D->getTypeSourceInfo()) {
990 if (Visit(TInfo->getTypeLoc()))
991 return true;
995 return false;
998 bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
999 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
1000 if (Visit(TSInfo->getTypeLoc()))
1001 return true;
1003 for (const auto *P : ND->parameters()) {
1004 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
1005 return true;
1008 return ND->isThisDeclarationADefinition() &&
1009 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
1012 template <typename DeclIt>
1013 static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
1014 SourceManager &SM, SourceLocation EndLoc,
1015 SmallVectorImpl<Decl *> &Decls) {
1016 DeclIt next = *DI_current;
1017 while (++next != DE_current) {
1018 Decl *D_next = *next;
1019 if (!D_next)
1020 break;
1021 SourceLocation L = D_next->getBeginLoc();
1022 if (!L.isValid())
1023 break;
1024 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
1025 *DI_current = next;
1026 Decls.push_back(D_next);
1027 continue;
1029 break;
1033 bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
1034 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
1035 // an @implementation can lexically contain Decls that are not properly
1036 // nested in the AST. When we identify such cases, we need to retrofit
1037 // this nesting here.
1038 if (!DI_current && !FileDI_current)
1039 return VisitDeclContext(D);
1041 // Scan the Decls that immediately come after the container
1042 // in the current DeclContext. If any fall within the
1043 // container's lexical region, stash them into a vector
1044 // for later processing.
1045 SmallVector<Decl *, 24> DeclsInContainer;
1046 SourceLocation EndLoc = D->getSourceRange().getEnd();
1047 SourceManager &SM = AU->getSourceManager();
1048 if (EndLoc.isValid()) {
1049 if (DI_current) {
1050 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
1051 DeclsInContainer);
1052 } else {
1053 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
1054 DeclsInContainer);
1058 // The common case.
1059 if (DeclsInContainer.empty())
1060 return VisitDeclContext(D);
1062 // Get all the Decls in the DeclContext, and sort them with the
1063 // additional ones we've collected. Then visit them.
1064 for (auto *SubDecl : D->decls()) {
1065 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1066 SubDecl->getBeginLoc().isInvalid())
1067 continue;
1068 DeclsInContainer.push_back(SubDecl);
1071 // Now sort the Decls so that they appear in lexical order.
1072 llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {
1073 SourceLocation L_A = A->getBeginLoc();
1074 SourceLocation L_B = B->getBeginLoc();
1075 return L_A != L_B
1076 ? SM.isBeforeInTranslationUnit(L_A, L_B)
1077 : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());
1080 // Now visit the decls.
1081 for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),
1082 E = DeclsInContainer.end();
1083 I != E; ++I) {
1084 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
1085 const std::optional<bool> &V = shouldVisitCursor(Cursor);
1086 if (!V)
1087 continue;
1088 if (!*V)
1089 return false;
1090 if (Visit(Cursor, true))
1091 return true;
1093 return false;
1096 bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1097 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1098 TU)))
1099 return true;
1101 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1102 return true;
1104 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1105 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1106 E = ND->protocol_end();
1107 I != E; ++I, ++PL)
1108 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1109 return true;
1111 return VisitObjCContainerDecl(ND);
1114 bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1115 if (!PID->isThisDeclarationADefinition())
1116 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1118 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1119 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1120 E = PID->protocol_end();
1121 I != E; ++I, ++PL)
1122 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1123 return true;
1125 return VisitObjCContainerDecl(PID);
1128 bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1129 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1130 return true;
1132 // FIXME: This implements a workaround with @property declarations also being
1133 // installed in the DeclContext for the @interface. Eventually this code
1134 // should be removed.
1135 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1136 if (!CDecl || !CDecl->IsClassExtension())
1137 return false;
1139 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1140 if (!ID)
1141 return false;
1143 IdentifierInfo *PropertyId = PD->getIdentifier();
1144 ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
1145 cast<DeclContext>(ID), PropertyId, PD->getQueryKind());
1147 if (!prevDecl)
1148 return false;
1150 // Visit synthesized methods since they will be skipped when visiting
1151 // the @interface.
1152 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1153 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1154 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1155 return true;
1157 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1158 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1159 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1160 return true;
1162 return false;
1165 bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1166 if (!typeParamList)
1167 return false;
1169 for (auto *typeParam : *typeParamList) {
1170 // Visit the type parameter.
1171 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1172 return true;
1175 return false;
1178 bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1179 if (!D->isThisDeclarationADefinition()) {
1180 // Forward declaration is treated like a reference.
1181 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1184 // Objective-C type parameters.
1185 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1186 return true;
1188 // Issue callbacks for super class.
1189 if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
1190 D->getSuperClass(), D->getSuperClassLoc(), TU)))
1191 return true;
1193 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1194 if (Visit(SuperClassTInfo->getTypeLoc()))
1195 return true;
1197 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1198 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1199 E = D->protocol_end();
1200 I != E; ++I, ++PL)
1201 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1202 return true;
1204 return VisitObjCContainerDecl(D);
1207 bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1208 return VisitObjCContainerDecl(D);
1211 bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1212 // 'ID' could be null when dealing with invalid code.
1213 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1214 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1215 return true;
1217 return VisitObjCImplDecl(D);
1220 bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1221 #if 0
1222 // Issue callbacks for super class.
1223 // FIXME: No source location information!
1224 if (D->getSuperClass() &&
1225 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1226 D->getSuperClassLoc(),
1227 TU)))
1228 return true;
1229 #endif
1231 return VisitObjCImplDecl(D);
1234 bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1235 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1236 if (PD->isIvarNameSpecified())
1237 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1239 return false;
1242 bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1243 return VisitDeclContext(D);
1246 bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1247 // Visit nested-name-specifier.
1248 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1249 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1250 return true;
1252 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1253 D->getTargetNameLoc(), TU));
1256 bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1257 // Visit nested-name-specifier.
1258 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1259 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1260 return true;
1263 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1264 return true;
1266 return VisitDeclarationNameInfo(D->getNameInfo());
1269 bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1270 // Visit nested-name-specifier.
1271 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1272 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1273 return true;
1275 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1276 D->getIdentLocation(), TU));
1279 bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1280 // Visit nested-name-specifier.
1281 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1282 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1283 return true;
1286 return VisitDeclarationNameInfo(D->getNameInfo());
1289 bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1290 UnresolvedUsingTypenameDecl *D) {
1291 // Visit nested-name-specifier.
1292 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1293 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1294 return true;
1296 return false;
1299 bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
1300 if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
1301 return true;
1302 if (auto *Message = D->getMessage())
1303 if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
1304 return true;
1305 return false;
1308 bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {
1309 if (NamedDecl *FriendD = D->getFriendDecl()) {
1310 if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))
1311 return true;
1312 } else if (TypeSourceInfo *TI = D->getFriendType()) {
1313 if (Visit(TI->getTypeLoc()))
1314 return true;
1316 return false;
1319 bool CursorVisitor::VisitDecompositionDecl(DecompositionDecl *D) {
1320 for (auto *B : D->bindings()) {
1321 if (Visit(MakeCXCursor(B, TU, RegionOfInterest)))
1322 return true;
1324 return VisitVarDecl(D);
1327 bool CursorVisitor::VisitConceptDecl(ConceptDecl *D) {
1328 if (VisitTemplateParameters(D->getTemplateParameters()))
1329 return true;
1331 if (auto *E = D->getConstraintExpr()) {
1332 if (Visit(MakeCXCursor(E, D, TU, RegionOfInterest)))
1333 return true;
1335 return false;
1338 bool CursorVisitor::VisitTypeConstraint(const TypeConstraint &TC) {
1339 if (TC.getNestedNameSpecifierLoc()) {
1340 if (VisitNestedNameSpecifierLoc(TC.getNestedNameSpecifierLoc()))
1341 return true;
1343 if (TC.getNamedConcept()) {
1344 if (Visit(MakeCursorTemplateRef(TC.getNamedConcept(),
1345 TC.getConceptNameLoc(), TU)))
1346 return true;
1348 if (auto Args = TC.getTemplateArgsAsWritten()) {
1349 for (const auto &Arg : Args->arguments()) {
1350 if (VisitTemplateArgumentLoc(Arg))
1351 return true;
1354 return false;
1357 bool CursorVisitor::VisitConceptRequirement(const concepts::Requirement &R) {
1358 using namespace concepts;
1359 switch (R.getKind()) {
1360 case Requirement::RK_Type: {
1361 const TypeRequirement &TR = cast<TypeRequirement>(R);
1362 if (!TR.isSubstitutionFailure()) {
1363 if (Visit(TR.getType()->getTypeLoc()))
1364 return true;
1366 break;
1368 case Requirement::RK_Simple:
1369 case Requirement::RK_Compound: {
1370 const ExprRequirement &ER = cast<ExprRequirement>(R);
1371 if (!ER.isExprSubstitutionFailure()) {
1372 if (Visit(ER.getExpr()))
1373 return true;
1375 if (ER.getKind() == Requirement::RK_Compound) {
1376 const auto &RTR = ER.getReturnTypeRequirement();
1377 if (RTR.isTypeConstraint()) {
1378 if (const auto *Cons = RTR.getTypeConstraint())
1379 VisitTypeConstraint(*Cons);
1382 break;
1384 case Requirement::RK_Nested: {
1385 const NestedRequirement &NR = cast<NestedRequirement>(R);
1386 if (!NR.hasInvalidConstraint()) {
1387 if (Visit(NR.getConstraintExpr()))
1388 return true;
1390 break;
1393 return false;
1396 bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1397 switch (Name.getName().getNameKind()) {
1398 case clang::DeclarationName::Identifier:
1399 case clang::DeclarationName::CXXLiteralOperatorName:
1400 case clang::DeclarationName::CXXDeductionGuideName:
1401 case clang::DeclarationName::CXXOperatorName:
1402 case clang::DeclarationName::CXXUsingDirective:
1403 return false;
1405 case clang::DeclarationName::CXXConstructorName:
1406 case clang::DeclarationName::CXXDestructorName:
1407 case clang::DeclarationName::CXXConversionFunctionName:
1408 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1409 return Visit(TSInfo->getTypeLoc());
1410 return false;
1412 case clang::DeclarationName::ObjCZeroArgSelector:
1413 case clang::DeclarationName::ObjCOneArgSelector:
1414 case clang::DeclarationName::ObjCMultiArgSelector:
1415 // FIXME: Per-identifier location info?
1416 return false;
1419 llvm_unreachable("Invalid DeclarationName::Kind!");
1422 bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1423 SourceRange Range) {
1424 // FIXME: This whole routine is a hack to work around the lack of proper
1425 // source information in nested-name-specifiers (PR5791). Since we do have
1426 // a beginning source location, we can visit the first component of the
1427 // nested-name-specifier, if it's a single-token component.
1428 if (!NNS)
1429 return false;
1431 // Get the first component in the nested-name-specifier.
1432 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1433 NNS = Prefix;
1435 switch (NNS->getKind()) {
1436 case NestedNameSpecifier::Namespace:
1437 return Visit(
1438 MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
1440 case NestedNameSpecifier::NamespaceAlias:
1441 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1442 Range.getBegin(), TU));
1444 case NestedNameSpecifier::TypeSpec: {
1445 // If the type has a form where we know that the beginning of the source
1446 // range matches up with a reference cursor. Visit the appropriate reference
1447 // cursor.
1448 const Type *T = NNS->getAsType();
1449 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1450 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1451 if (const TagType *Tag = dyn_cast<TagType>(T))
1452 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1453 if (const TemplateSpecializationType *TST =
1454 dyn_cast<TemplateSpecializationType>(T))
1455 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1456 break;
1459 case NestedNameSpecifier::TypeSpecWithTemplate:
1460 case NestedNameSpecifier::Global:
1461 case NestedNameSpecifier::Identifier:
1462 case NestedNameSpecifier::Super:
1463 break;
1466 return false;
1469 bool CursorVisitor::VisitNestedNameSpecifierLoc(
1470 NestedNameSpecifierLoc Qualifier) {
1471 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1472 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1473 Qualifiers.push_back(Qualifier);
1475 while (!Qualifiers.empty()) {
1476 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1477 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1478 switch (NNS->getKind()) {
1479 case NestedNameSpecifier::Namespace:
1480 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1481 Q.getLocalBeginLoc(), TU)))
1482 return true;
1484 break;
1486 case NestedNameSpecifier::NamespaceAlias:
1487 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1488 Q.getLocalBeginLoc(), TU)))
1489 return true;
1491 break;
1493 case NestedNameSpecifier::TypeSpec:
1494 case NestedNameSpecifier::TypeSpecWithTemplate:
1495 if (Visit(Q.getTypeLoc()))
1496 return true;
1498 break;
1500 case NestedNameSpecifier::Global:
1501 case NestedNameSpecifier::Identifier:
1502 case NestedNameSpecifier::Super:
1503 break;
1507 return false;
1510 bool CursorVisitor::VisitTemplateParameters(
1511 const TemplateParameterList *Params) {
1512 if (!Params)
1513 return false;
1515 for (TemplateParameterList::const_iterator P = Params->begin(),
1516 PEnd = Params->end();
1517 P != PEnd; ++P) {
1518 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1519 return true;
1522 if (const auto *E = Params->getRequiresClause()) {
1523 if (Visit(MakeCXCursor(E, nullptr, TU, RegionOfInterest)))
1524 return true;
1527 return false;
1530 bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1531 switch (Name.getKind()) {
1532 case TemplateName::Template:
1533 case TemplateName::UsingTemplate:
1534 case TemplateName::QualifiedTemplate: // FIXME: Visit nested-name-specifier.
1535 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1537 case TemplateName::OverloadedTemplate:
1538 // Visit the overloaded template set.
1539 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1540 return true;
1542 return false;
1544 case TemplateName::AssumedTemplate:
1545 // FIXME: Visit DeclarationName?
1546 return false;
1548 case TemplateName::DependentTemplate:
1549 // FIXME: Visit nested-name-specifier.
1550 return false;
1552 case TemplateName::SubstTemplateTemplateParm:
1553 return Visit(MakeCursorTemplateRef(
1554 Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));
1556 case TemplateName::SubstTemplateTemplateParmPack:
1557 return Visit(MakeCursorTemplateRef(
1558 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
1559 TU));
1561 case TemplateName::DeducedTemplate:
1562 llvm_unreachable("DeducedTemplate shouldn't appear in source");
1565 llvm_unreachable("Invalid TemplateName::Kind!");
1568 bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1569 switch (TAL.getArgument().getKind()) {
1570 case TemplateArgument::Null:
1571 case TemplateArgument::Integral:
1572 case TemplateArgument::Pack:
1573 return false;
1575 case TemplateArgument::Type:
1576 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578 return false;
1580 case TemplateArgument::Declaration:
1581 if (Expr *E = TAL.getSourceDeclExpression())
1582 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1583 return false;
1585 case TemplateArgument::StructuralValue:
1586 if (Expr *E = TAL.getSourceStructuralValueExpression())
1587 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1588 return false;
1590 case TemplateArgument::NullPtr:
1591 if (Expr *E = TAL.getSourceNullPtrExpression())
1592 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1593 return false;
1595 case TemplateArgument::Expression:
1596 if (Expr *E = TAL.getSourceExpression())
1597 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1598 return false;
1600 case TemplateArgument::Template:
1601 case TemplateArgument::TemplateExpansion:
1602 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1603 return true;
1605 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1606 TAL.getTemplateNameLoc());
1609 llvm_unreachable("Invalid TemplateArgument::Kind!");
1612 bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1613 return VisitDeclContext(D);
1616 bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1617 return Visit(TL.getUnqualifiedLoc());
1620 bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1621 ASTContext &Context = AU->getASTContext();
1623 // Some builtin types (such as Objective-C's "id", "sel", and
1624 // "Class") have associated declarations. Create cursors for those.
1625 QualType VisitType;
1626 switch (TL.getTypePtr()->getKind()) {
1628 case BuiltinType::Void:
1629 case BuiltinType::NullPtr:
1630 case BuiltinType::Dependent:
1631 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
1632 case BuiltinType::Id:
1633 #include "clang/Basic/OpenCLImageTypes.def"
1634 #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
1635 #include "clang/Basic/OpenCLExtensionTypes.def"
1636 case BuiltinType::OCLSampler:
1637 case BuiltinType::OCLEvent:
1638 case BuiltinType::OCLClkEvent:
1639 case BuiltinType::OCLQueue:
1640 case BuiltinType::OCLReserveID:
1641 #define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1642 #include "clang/Basic/AArch64SVEACLETypes.def"
1643 #define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
1644 #include "clang/Basic/PPCTypes.def"
1645 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1646 #include "clang/Basic/RISCVVTypes.def"
1647 #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1648 #include "clang/Basic/WebAssemblyReferenceTypes.def"
1649 #define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
1650 #include "clang/Basic/AMDGPUTypes.def"
1651 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1652 #include "clang/Basic/HLSLIntangibleTypes.def"
1653 #define BUILTIN_TYPE(Id, SingletonId)
1654 #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1655 #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1656 #define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1657 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1658 #include "clang/AST/BuiltinTypes.def"
1659 break;
1661 case BuiltinType::ObjCId:
1662 VisitType = Context.getObjCIdType();
1663 break;
1665 case BuiltinType::ObjCClass:
1666 VisitType = Context.getObjCClassType();
1667 break;
1669 case BuiltinType::ObjCSel:
1670 VisitType = Context.getObjCSelType();
1671 break;
1674 if (!VisitType.isNull()) {
1675 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1676 return Visit(
1677 MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
1680 return false;
1683 bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1684 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1687 bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1688 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1691 bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1692 if (TL.isDefinition())
1693 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1695 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1698 bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1699 if (const auto *TC = TL.getDecl()->getTypeConstraint()) {
1700 if (VisitTypeConstraint(*TC))
1701 return true;
1704 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1707 bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1708 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
1711 bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
1712 if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
1713 return true;
1714 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1715 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1716 TU)))
1717 return true;
1720 return false;
1723 bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1724 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1725 return true;
1727 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1728 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1729 return true;
1732 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1733 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1734 TU)))
1735 return true;
1738 return false;
1741 bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1742 return Visit(TL.getPointeeLoc());
1745 bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1746 return Visit(TL.getInnerLoc());
1749 bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
1750 return Visit(TL.getInnerLoc());
1753 bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1754 return Visit(TL.getPointeeLoc());
1757 bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1758 return Visit(TL.getPointeeLoc());
1761 bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1762 return Visit(TL.getPointeeLoc());
1765 bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1766 return Visit(TL.getPointeeLoc());
1769 bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1770 return Visit(TL.getPointeeLoc());
1773 bool CursorVisitor::VisitUsingTypeLoc(UsingTypeLoc TL) {
1774 auto *underlyingDecl = TL.getUnderlyingType()->getAsTagDecl();
1775 if (underlyingDecl) {
1776 return Visit(MakeCursorTypeRef(underlyingDecl, TL.getNameLoc(), TU));
1778 return false;
1781 bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1782 return Visit(TL.getModifiedLoc());
1785 bool CursorVisitor::VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL) {
1786 return Visit(TL.getInnerLoc());
1789 bool CursorVisitor::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
1790 return Visit(TL.getWrappedLoc());
1793 bool CursorVisitor::VisitHLSLAttributedResourceTypeLoc(
1794 HLSLAttributedResourceTypeLoc TL) {
1795 return Visit(TL.getWrappedLoc());
1798 bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1799 bool SkipResultType) {
1800 if (!SkipResultType && Visit(TL.getReturnLoc()))
1801 return true;
1803 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1804 if (Decl *D = TL.getParam(I))
1805 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1806 return true;
1808 return false;
1811 bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1812 if (Visit(TL.getElementLoc()))
1813 return true;
1815 if (Expr *Size = TL.getSizeExpr())
1816 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1818 return false;
1821 bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1822 return Visit(TL.getOriginalLoc());
1825 bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1826 return Visit(TL.getOriginalLoc());
1829 bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
1830 DeducedTemplateSpecializationTypeLoc TL) {
1831 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1832 TL.getTemplateNameLoc()))
1833 return true;
1835 return false;
1838 bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1839 TemplateSpecializationTypeLoc TL) {
1840 // Visit the template name.
1841 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1842 TL.getTemplateNameLoc()))
1843 return true;
1845 // Visit the template arguments.
1846 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1847 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1848 return true;
1850 return false;
1853 bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1854 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1857 bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1858 if (TypeSourceInfo *TSInfo = TL.getUnmodifiedTInfo())
1859 return Visit(TSInfo->getTypeLoc());
1861 return false;
1864 bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1865 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1866 return Visit(TSInfo->getTypeLoc());
1868 return false;
1871 bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1872 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
1875 bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1876 DependentTemplateSpecializationTypeLoc TL) {
1877 // Visit the nested-name-specifier, if there is one.
1878 if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1879 return true;
1881 // Visit the template arguments.
1882 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1883 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1884 return true;
1886 return false;
1889 bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1890 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1891 return true;
1893 return Visit(TL.getNamedTypeLoc());
1896 bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1897 return Visit(TL.getPatternLoc());
1900 bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1901 if (Expr *E = TL.getUnderlyingExpr())
1902 return Visit(MakeCXCursor(E, StmtParent, TU));
1904 return false;
1907 bool CursorVisitor::VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) {
1908 if (Visit(TL.getPatternLoc()))
1909 return true;
1910 return Visit(MakeCXCursor(TL.getIndexExpr(), StmtParent, TU));
1913 bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1914 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1917 bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1918 return Visit(TL.getValueLoc());
1921 bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1922 return Visit(TL.getValueLoc());
1925 #define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1926 bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1927 return Visit##PARENT##Loc(TL); \
1930 DEFAULT_TYPELOC_IMPL(Complex, Type)
1931 DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1932 DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1933 DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1934 DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1935 DEFAULT_TYPELOC_IMPL(ArrayParameter, ConstantArrayType)
1936 DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
1937 DEFAULT_TYPELOC_IMPL(DependentVector, Type)
1938 DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1939 DEFAULT_TYPELOC_IMPL(Vector, Type)
1940 DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1941 DEFAULT_TYPELOC_IMPL(ConstantMatrix, MatrixType)
1942 DEFAULT_TYPELOC_IMPL(DependentSizedMatrix, MatrixType)
1943 DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1944 DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1945 DEFAULT_TYPELOC_IMPL(Record, TagType)
1946 DEFAULT_TYPELOC_IMPL(Enum, TagType)
1947 DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1948 DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1949 DEFAULT_TYPELOC_IMPL(Auto, Type)
1950 DEFAULT_TYPELOC_IMPL(BitInt, Type)
1951 DEFAULT_TYPELOC_IMPL(DependentBitInt, Type)
1953 bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1954 // Visit the nested-name-specifier, if present.
1955 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1956 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1957 return true;
1959 if (D->isCompleteDefinition()) {
1960 for (const auto &I : D->bases()) {
1961 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
1962 return true;
1966 return VisitTagDecl(D);
1969 bool CursorVisitor::VisitAttributes(Decl *D) {
1970 for (const auto *I : D->attrs())
1971 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1972 !I->isImplicit()) &&
1973 Visit(MakeCXCursor(I, D, TU)))
1974 return true;
1976 return false;
1979 //===----------------------------------------------------------------------===//
1980 // Data-recursive visitor methods.
1981 //===----------------------------------------------------------------------===//
1983 namespace {
1984 #define DEF_JOB(NAME, DATA, KIND) \
1985 class NAME : public VisitorJob { \
1986 public: \
1987 NAME(const DATA *d, CXCursor parent) \
1988 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1989 static bool classof(const VisitorJob *VJ) { \
1990 return VJ->getKind() == KIND; \
1992 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1995 DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1996 DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1997 DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1998 DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1999 DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
2000 DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
2001 DEF_JOB(ConceptSpecializationExprVisit, ConceptSpecializationExpr,
2002 ConceptSpecializationExprVisitKind)
2003 DEF_JOB(RequiresExprVisit, RequiresExpr, RequiresExprVisitKind)
2004 DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
2005 #undef DEF_JOB
2007 class ExplicitTemplateArgsVisit : public VisitorJob {
2008 public:
2009 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
2010 const TemplateArgumentLoc *End, CXCursor parent)
2011 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
2012 End) {}
2013 static bool classof(const VisitorJob *VJ) {
2014 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
2016 const TemplateArgumentLoc *begin() const {
2017 return static_cast<const TemplateArgumentLoc *>(data[0]);
2019 const TemplateArgumentLoc *end() {
2020 return static_cast<const TemplateArgumentLoc *>(data[1]);
2023 class DeclVisit : public VisitorJob {
2024 public:
2025 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
2026 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
2027 isFirst ? (void *)1 : (void *)nullptr) {}
2028 static bool classof(const VisitorJob *VJ) {
2029 return VJ->getKind() == DeclVisitKind;
2031 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
2032 bool isFirst() const { return data[1] != nullptr; }
2034 class TypeLocVisit : public VisitorJob {
2035 public:
2036 TypeLocVisit(TypeLoc tl, CXCursor parent)
2037 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
2038 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
2040 static bool classof(const VisitorJob *VJ) {
2041 return VJ->getKind() == TypeLocVisitKind;
2044 TypeLoc get() const {
2045 QualType T = QualType::getFromOpaquePtr(data[0]);
2046 return TypeLoc(T, const_cast<void *>(data[1]));
2050 class LabelRefVisit : public VisitorJob {
2051 public:
2052 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
2053 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
2054 labelLoc.getPtrEncoding()) {}
2056 static bool classof(const VisitorJob *VJ) {
2057 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
2059 const LabelDecl *get() const {
2060 return static_cast<const LabelDecl *>(data[0]);
2062 SourceLocation getLoc() const {
2063 return SourceLocation::getFromPtrEncoding(data[1]);
2067 class NestedNameSpecifierLocVisit : public VisitorJob {
2068 public:
2069 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
2070 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
2071 Qualifier.getNestedNameSpecifier(),
2072 Qualifier.getOpaqueData()) {}
2074 static bool classof(const VisitorJob *VJ) {
2075 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
2078 NestedNameSpecifierLoc get() const {
2079 return NestedNameSpecifierLoc(
2080 const_cast<NestedNameSpecifier *>(
2081 static_cast<const NestedNameSpecifier *>(data[0])),
2082 const_cast<void *>(data[1]));
2086 class DeclarationNameInfoVisit : public VisitorJob {
2087 public:
2088 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
2089 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
2090 static bool classof(const VisitorJob *VJ) {
2091 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
2093 DeclarationNameInfo get() const {
2094 const Stmt *S = static_cast<const Stmt *>(data[0]);
2095 switch (S->getStmtClass()) {
2096 default:
2097 llvm_unreachable("Unhandled Stmt");
2098 case clang::Stmt::MSDependentExistsStmtClass:
2099 return cast<MSDependentExistsStmt>(S)->getNameInfo();
2100 case Stmt::CXXDependentScopeMemberExprClass:
2101 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
2102 case Stmt::DependentScopeDeclRefExprClass:
2103 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
2104 case Stmt::OMPCriticalDirectiveClass:
2105 return cast<OMPCriticalDirective>(S)->getDirectiveName();
2109 class MemberRefVisit : public VisitorJob {
2110 public:
2111 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
2112 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
2113 L.getPtrEncoding()) {}
2114 static bool classof(const VisitorJob *VJ) {
2115 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
2117 const FieldDecl *get() const {
2118 return static_cast<const FieldDecl *>(data[0]);
2120 SourceLocation getLoc() const {
2121 return SourceLocation::getFromRawEncoding(
2122 (SourceLocation::UIntTy)(uintptr_t)data[1]);
2125 class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void>,
2126 public ConstAttrVisitor<EnqueueVisitor, void> {
2127 friend class OpenACCClauseEnqueue;
2128 friend class OMPClauseEnqueue;
2129 VisitorWorkList &WL;
2130 CXCursor Parent;
2132 public:
2133 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
2134 : WL(wl), Parent(parent) {}
2136 void VisitAddrLabelExpr(const AddrLabelExpr *E);
2137 void VisitBlockExpr(const BlockExpr *B);
2138 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
2139 void VisitCompoundStmt(const CompoundStmt *S);
2140 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
2142 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
2143 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
2144 void VisitCXXNewExpr(const CXXNewExpr *E);
2145 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
2146 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
2147 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
2148 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
2149 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
2150 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
2151 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
2152 void VisitCXXCatchStmt(const CXXCatchStmt *S);
2153 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
2154 void VisitDeclRefExpr(const DeclRefExpr *D);
2155 void VisitDeclStmt(const DeclStmt *S);
2156 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
2157 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
2158 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
2159 void VisitForStmt(const ForStmt *FS);
2160 void VisitGotoStmt(const GotoStmt *GS);
2161 void VisitIfStmt(const IfStmt *If);
2162 void VisitInitListExpr(const InitListExpr *IE);
2163 void VisitMemberExpr(const MemberExpr *M);
2164 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2165 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2166 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2167 void VisitOverloadExpr(const OverloadExpr *E);
2168 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2169 void VisitStmt(const Stmt *S);
2170 void VisitSwitchStmt(const SwitchStmt *S);
2171 void VisitWhileStmt(const WhileStmt *W);
2172 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2173 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2174 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2175 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2176 void VisitVAArgExpr(const VAArgExpr *E);
2177 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2178 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2179 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2180 void VisitLambdaExpr(const LambdaExpr *E);
2181 void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
2182 void VisitRequiresExpr(const RequiresExpr *E);
2183 void VisitCXXParenListInitExpr(const CXXParenListInitExpr *E);
2184 void VisitOpenACCComputeConstruct(const OpenACCComputeConstruct *D);
2185 void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *D);
2186 void VisitOpenACCCombinedConstruct(const OpenACCCombinedConstruct *D);
2187 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
2188 void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
2189 void VisitOMPLoopDirective(const OMPLoopDirective *D);
2190 void VisitOMPParallelDirective(const OMPParallelDirective *D);
2191 void VisitOMPSimdDirective(const OMPSimdDirective *D);
2192 void
2193 VisitOMPLoopTransformationDirective(const OMPLoopTransformationDirective *D);
2194 void VisitOMPTileDirective(const OMPTileDirective *D);
2195 void VisitOMPUnrollDirective(const OMPUnrollDirective *D);
2196 void VisitOMPReverseDirective(const OMPReverseDirective *D);
2197 void VisitOMPInterchangeDirective(const OMPInterchangeDirective *D);
2198 void VisitOMPForDirective(const OMPForDirective *D);
2199 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
2200 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
2201 void VisitOMPSectionDirective(const OMPSectionDirective *D);
2202 void VisitOMPSingleDirective(const OMPSingleDirective *D);
2203 void VisitOMPMasterDirective(const OMPMasterDirective *D);
2204 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
2205 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
2206 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
2207 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
2208 void VisitOMPParallelMaskedDirective(const OMPParallelMaskedDirective *D);
2209 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
2210 void VisitOMPTaskDirective(const OMPTaskDirective *D);
2211 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
2212 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
2213 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
2214 void VisitOMPAssumeDirective(const OMPAssumeDirective *D);
2215 void VisitOMPErrorDirective(const OMPErrorDirective *D);
2216 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
2217 void
2218 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
2219 void VisitOMPCancelDirective(const OMPCancelDirective *D);
2220 void VisitOMPFlushDirective(const OMPFlushDirective *D);
2221 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
2222 void VisitOMPScanDirective(const OMPScanDirective *D);
2223 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
2224 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
2225 void VisitOMPTargetDirective(const OMPTargetDirective *D);
2226 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
2227 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
2228 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
2229 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
2230 void
2231 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
2232 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
2233 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
2234 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
2235 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
2236 void VisitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective *D);
2237 void
2238 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
2239 void VisitOMPMaskedTaskLoopSimdDirective(
2240 const OMPMaskedTaskLoopSimdDirective *D);
2241 void VisitOMPParallelMasterTaskLoopDirective(
2242 const OMPParallelMasterTaskLoopDirective *D);
2243 void VisitOMPParallelMaskedTaskLoopDirective(
2244 const OMPParallelMaskedTaskLoopDirective *D);
2245 void VisitOMPParallelMasterTaskLoopSimdDirective(
2246 const OMPParallelMasterTaskLoopSimdDirective *D);
2247 void VisitOMPParallelMaskedTaskLoopSimdDirective(
2248 const OMPParallelMaskedTaskLoopSimdDirective *D);
2249 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
2250 void VisitOMPDistributeParallelForDirective(
2251 const OMPDistributeParallelForDirective *D);
2252 void VisitOMPDistributeParallelForSimdDirective(
2253 const OMPDistributeParallelForSimdDirective *D);
2254 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
2255 void VisitOMPTargetParallelForSimdDirective(
2256 const OMPTargetParallelForSimdDirective *D);
2257 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
2258 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
2259 void VisitOMPTeamsDistributeSimdDirective(
2260 const OMPTeamsDistributeSimdDirective *D);
2261 void VisitOMPTeamsDistributeParallelForSimdDirective(
2262 const OMPTeamsDistributeParallelForSimdDirective *D);
2263 void VisitOMPTeamsDistributeParallelForDirective(
2264 const OMPTeamsDistributeParallelForDirective *D);
2265 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
2266 void VisitOMPTargetTeamsDistributeDirective(
2267 const OMPTargetTeamsDistributeDirective *D);
2268 void VisitOMPTargetTeamsDistributeParallelForDirective(
2269 const OMPTargetTeamsDistributeParallelForDirective *D);
2270 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2271 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
2272 void VisitOMPTargetTeamsDistributeSimdDirective(
2273 const OMPTargetTeamsDistributeSimdDirective *D);
2275 // Attributes
2276 void VisitAnnotateAttr(const AnnotateAttr *A);
2278 private:
2279 void AddDeclarationNameInfo(const Stmt *S);
2280 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
2281 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2282 unsigned NumTemplateArgs);
2283 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2284 void AddStmt(const Stmt *S);
2285 void AddDecl(const Decl *D, bool isFirst = true);
2286 void AddTypeLoc(TypeSourceInfo *TI);
2287 void EnqueueChildren(const Stmt *S);
2288 void EnqueueChildren(const OpenACCClause *S);
2289 void EnqueueChildren(const OMPClause *S);
2290 void EnqueueChildren(const AnnotateAttr *A);
2292 } // namespace
2294 void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
2295 // 'S' should always be non-null, since it comes from the
2296 // statement we are visiting.
2297 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2300 void EnqueueVisitor::AddNestedNameSpecifierLoc(
2301 NestedNameSpecifierLoc Qualifier) {
2302 if (Qualifier)
2303 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2306 void EnqueueVisitor::AddStmt(const Stmt *S) {
2307 if (S)
2308 WL.push_back(StmtVisit(S, Parent));
2310 void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
2311 if (D)
2312 WL.push_back(DeclVisit(D, Parent, isFirst));
2314 void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2315 unsigned NumTemplateArgs) {
2316 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
2318 void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
2319 if (D)
2320 WL.push_back(MemberRefVisit(D, L, Parent));
2322 void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2323 if (TI)
2324 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2326 void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
2327 unsigned size = WL.size();
2328 for (const Stmt *SubStmt : S->children()) {
2329 AddStmt(SubStmt);
2331 if (size == WL.size())
2332 return;
2333 // Now reverse the entries we just added. This will match the DFS
2334 // ordering performed by the worklist.
2335 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2336 std::reverse(I, E);
2338 namespace {
2339 class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2340 EnqueueVisitor *Visitor;
2341 /// Process clauses with list of variables.
2342 template <typename T> void VisitOMPClauseList(T *Node);
2344 public:
2345 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
2346 #define GEN_CLANG_CLAUSE_CLASS
2347 #define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2348 #include "llvm/Frontend/OpenMP/OMP.inc"
2349 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
2350 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
2353 void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2354 const OMPClauseWithPreInit *C) {
2355 Visitor->AddStmt(C->getPreInitStmt());
2358 void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2359 const OMPClauseWithPostUpdate *C) {
2360 VisitOMPClauseWithPreInit(C);
2361 Visitor->AddStmt(C->getPostUpdateExpr());
2364 void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2365 VisitOMPClauseWithPreInit(C);
2366 Visitor->AddStmt(C->getCondition());
2369 void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2370 Visitor->AddStmt(C->getCondition());
2373 void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2374 VisitOMPClauseWithPreInit(C);
2375 Visitor->AddStmt(C->getNumThreads());
2378 void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2379 Visitor->AddStmt(C->getSafelen());
2382 void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2383 Visitor->AddStmt(C->getSimdlen());
2386 void OMPClauseEnqueue::VisitOMPSizesClause(const OMPSizesClause *C) {
2387 for (auto E : C->getSizesRefs())
2388 Visitor->AddStmt(E);
2391 void OMPClauseEnqueue::VisitOMPPermutationClause(
2392 const OMPPermutationClause *C) {
2393 for (auto E : C->getArgsRefs())
2394 Visitor->AddStmt(E);
2397 void OMPClauseEnqueue::VisitOMPFullClause(const OMPFullClause *C) {}
2399 void OMPClauseEnqueue::VisitOMPPartialClause(const OMPPartialClause *C) {
2400 Visitor->AddStmt(C->getFactor());
2403 void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2404 Visitor->AddStmt(C->getAllocator());
2407 void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2408 Visitor->AddStmt(C->getNumForLoops());
2411 void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
2413 void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
2415 void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2416 VisitOMPClauseWithPreInit(C);
2417 Visitor->AddStmt(C->getChunkSize());
2420 void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2421 Visitor->AddStmt(C->getNumForLoops());
2424 void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2425 Visitor->AddStmt(C->getEventHandler());
2428 void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2430 void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2432 void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2434 void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2436 void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2438 void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2440 void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2442 void OMPClauseEnqueue::VisitOMPCompareClause(const OMPCompareClause *) {}
2444 void OMPClauseEnqueue::VisitOMPFailClause(const OMPFailClause *) {}
2446 void OMPClauseEnqueue::VisitOMPAbsentClause(const OMPAbsentClause *) {}
2448 void OMPClauseEnqueue::VisitOMPHoldsClause(const OMPHoldsClause *) {}
2450 void OMPClauseEnqueue::VisitOMPContainsClause(const OMPContainsClause *) {}
2452 void OMPClauseEnqueue::VisitOMPNoOpenMPClause(const OMPNoOpenMPClause *) {}
2454 void OMPClauseEnqueue::VisitOMPNoOpenMPRoutinesClause(
2455 const OMPNoOpenMPRoutinesClause *) {}
2457 void OMPClauseEnqueue::VisitOMPNoParallelismClause(
2458 const OMPNoParallelismClause *) {}
2460 void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2462 void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2464 void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2466 void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2468 void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2470 void OMPClauseEnqueue::VisitOMPWeakClause(const OMPWeakClause *) {}
2472 void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2474 void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2476 void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2478 void OMPClauseEnqueue::VisitOMPInitClause(const OMPInitClause *C) {
2479 VisitOMPClauseList(C);
2482 void OMPClauseEnqueue::VisitOMPUseClause(const OMPUseClause *C) {
2483 Visitor->AddStmt(C->getInteropVar());
2486 void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *C) {
2487 if (C->getInteropVar())
2488 Visitor->AddStmt(C->getInteropVar());
2491 void OMPClauseEnqueue::VisitOMPNovariantsClause(const OMPNovariantsClause *C) {
2492 Visitor->AddStmt(C->getCondition());
2495 void OMPClauseEnqueue::VisitOMPNocontextClause(const OMPNocontextClause *C) {
2496 Visitor->AddStmt(C->getCondition());
2499 void OMPClauseEnqueue::VisitOMPFilterClause(const OMPFilterClause *C) {
2500 VisitOMPClauseWithPreInit(C);
2501 Visitor->AddStmt(C->getThreadID());
2504 void OMPClauseEnqueue::VisitOMPAlignClause(const OMPAlignClause *C) {
2505 Visitor->AddStmt(C->getAlignment());
2508 void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2509 const OMPUnifiedAddressClause *) {}
2511 void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2512 const OMPUnifiedSharedMemoryClause *) {}
2514 void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2515 const OMPReverseOffloadClause *) {}
2517 void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2518 const OMPDynamicAllocatorsClause *) {}
2520 void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2521 const OMPAtomicDefaultMemOrderClause *) {}
2523 void OMPClauseEnqueue::VisitOMPAtClause(const OMPAtClause *) {}
2525 void OMPClauseEnqueue::VisitOMPSeverityClause(const OMPSeverityClause *) {}
2527 void OMPClauseEnqueue::VisitOMPMessageClause(const OMPMessageClause *) {}
2529 void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2530 Visitor->AddStmt(C->getDevice());
2533 void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2534 VisitOMPClauseList(C);
2535 VisitOMPClauseWithPreInit(C);
2538 void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2539 const OMPThreadLimitClause *C) {
2540 VisitOMPClauseList(C);
2541 VisitOMPClauseWithPreInit(C);
2544 void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2545 Visitor->AddStmt(C->getPriority());
2548 void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2549 Visitor->AddStmt(C->getGrainsize());
2552 void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2553 Visitor->AddStmt(C->getNumTasks());
2556 void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2557 Visitor->AddStmt(C->getHint());
2560 template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
2561 for (const auto *I : Node->varlist()) {
2562 Visitor->AddStmt(I);
2566 void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2567 VisitOMPClauseList(C);
2569 void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2570 VisitOMPClauseList(C);
2572 void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2573 VisitOMPClauseList(C);
2574 Visitor->AddStmt(C->getAllocator());
2576 void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
2577 VisitOMPClauseList(C);
2578 for (const auto *E : C->private_copies()) {
2579 Visitor->AddStmt(E);
2582 void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2583 const OMPFirstprivateClause *C) {
2584 VisitOMPClauseList(C);
2585 VisitOMPClauseWithPreInit(C);
2586 for (const auto *E : C->private_copies()) {
2587 Visitor->AddStmt(E);
2589 for (const auto *E : C->inits()) {
2590 Visitor->AddStmt(E);
2593 void OMPClauseEnqueue::VisitOMPLastprivateClause(
2594 const OMPLastprivateClause *C) {
2595 VisitOMPClauseList(C);
2596 VisitOMPClauseWithPostUpdate(C);
2597 for (auto *E : C->private_copies()) {
2598 Visitor->AddStmt(E);
2600 for (auto *E : C->source_exprs()) {
2601 Visitor->AddStmt(E);
2603 for (auto *E : C->destination_exprs()) {
2604 Visitor->AddStmt(E);
2606 for (auto *E : C->assignment_ops()) {
2607 Visitor->AddStmt(E);
2610 void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
2611 VisitOMPClauseList(C);
2613 void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2614 VisitOMPClauseList(C);
2615 VisitOMPClauseWithPostUpdate(C);
2616 for (auto *E : C->privates()) {
2617 Visitor->AddStmt(E);
2619 for (auto *E : C->lhs_exprs()) {
2620 Visitor->AddStmt(E);
2622 for (auto *E : C->rhs_exprs()) {
2623 Visitor->AddStmt(E);
2625 for (auto *E : C->reduction_ops()) {
2626 Visitor->AddStmt(E);
2628 if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
2629 for (auto *E : C->copy_ops()) {
2630 Visitor->AddStmt(E);
2632 for (auto *E : C->copy_array_temps()) {
2633 Visitor->AddStmt(E);
2635 for (auto *E : C->copy_array_elems()) {
2636 Visitor->AddStmt(E);
2640 void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2641 const OMPTaskReductionClause *C) {
2642 VisitOMPClauseList(C);
2643 VisitOMPClauseWithPostUpdate(C);
2644 for (auto *E : C->privates()) {
2645 Visitor->AddStmt(E);
2647 for (auto *E : C->lhs_exprs()) {
2648 Visitor->AddStmt(E);
2650 for (auto *E : C->rhs_exprs()) {
2651 Visitor->AddStmt(E);
2653 for (auto *E : C->reduction_ops()) {
2654 Visitor->AddStmt(E);
2657 void OMPClauseEnqueue::VisitOMPInReductionClause(
2658 const OMPInReductionClause *C) {
2659 VisitOMPClauseList(C);
2660 VisitOMPClauseWithPostUpdate(C);
2661 for (auto *E : C->privates()) {
2662 Visitor->AddStmt(E);
2664 for (auto *E : C->lhs_exprs()) {
2665 Visitor->AddStmt(E);
2667 for (auto *E : C->rhs_exprs()) {
2668 Visitor->AddStmt(E);
2670 for (auto *E : C->reduction_ops()) {
2671 Visitor->AddStmt(E);
2673 for (auto *E : C->taskgroup_descriptors())
2674 Visitor->AddStmt(E);
2676 void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2677 VisitOMPClauseList(C);
2678 VisitOMPClauseWithPostUpdate(C);
2679 for (const auto *E : C->privates()) {
2680 Visitor->AddStmt(E);
2682 for (const auto *E : C->inits()) {
2683 Visitor->AddStmt(E);
2685 for (const auto *E : C->updates()) {
2686 Visitor->AddStmt(E);
2688 for (const auto *E : C->finals()) {
2689 Visitor->AddStmt(E);
2691 Visitor->AddStmt(C->getStep());
2692 Visitor->AddStmt(C->getCalcStep());
2694 void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2695 VisitOMPClauseList(C);
2696 Visitor->AddStmt(C->getAlignment());
2698 void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2699 VisitOMPClauseList(C);
2700 for (auto *E : C->source_exprs()) {
2701 Visitor->AddStmt(E);
2703 for (auto *E : C->destination_exprs()) {
2704 Visitor->AddStmt(E);
2706 for (auto *E : C->assignment_ops()) {
2707 Visitor->AddStmt(E);
2710 void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2711 const OMPCopyprivateClause *C) {
2712 VisitOMPClauseList(C);
2713 for (auto *E : C->source_exprs()) {
2714 Visitor->AddStmt(E);
2716 for (auto *E : C->destination_exprs()) {
2717 Visitor->AddStmt(E);
2719 for (auto *E : C->assignment_ops()) {
2720 Visitor->AddStmt(E);
2723 void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2724 VisitOMPClauseList(C);
2726 void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2727 Visitor->AddStmt(C->getDepobj());
2729 void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2730 VisitOMPClauseList(C);
2732 void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2733 VisitOMPClauseList(C);
2735 void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2736 const OMPDistScheduleClause *C) {
2737 VisitOMPClauseWithPreInit(C);
2738 Visitor->AddStmt(C->getChunkSize());
2740 void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2741 const OMPDefaultmapClause * /*C*/) {}
2742 void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2743 VisitOMPClauseList(C);
2745 void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2746 VisitOMPClauseList(C);
2748 void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2749 const OMPUseDevicePtrClause *C) {
2750 VisitOMPClauseList(C);
2752 void OMPClauseEnqueue::VisitOMPUseDeviceAddrClause(
2753 const OMPUseDeviceAddrClause *C) {
2754 VisitOMPClauseList(C);
2756 void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2757 const OMPIsDevicePtrClause *C) {
2758 VisitOMPClauseList(C);
2760 void OMPClauseEnqueue::VisitOMPHasDeviceAddrClause(
2761 const OMPHasDeviceAddrClause *C) {
2762 VisitOMPClauseList(C);
2764 void OMPClauseEnqueue::VisitOMPNontemporalClause(
2765 const OMPNontemporalClause *C) {
2766 VisitOMPClauseList(C);
2767 for (const auto *E : C->private_refs())
2768 Visitor->AddStmt(E);
2770 void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
2771 void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
2772 const OMPUsesAllocatorsClause *C) {
2773 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
2774 const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);
2775 Visitor->AddStmt(D.Allocator);
2776 Visitor->AddStmt(D.AllocatorTraits);
2779 void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) {
2780 Visitor->AddStmt(C->getModifier());
2781 for (const Expr *E : C->varlist())
2782 Visitor->AddStmt(E);
2784 void OMPClauseEnqueue::VisitOMPBindClause(const OMPBindClause *C) {}
2785 void OMPClauseEnqueue::VisitOMPXDynCGroupMemClause(
2786 const OMPXDynCGroupMemClause *C) {
2787 VisitOMPClauseWithPreInit(C);
2788 Visitor->AddStmt(C->getSize());
2790 void OMPClauseEnqueue::VisitOMPDoacrossClause(const OMPDoacrossClause *C) {
2791 VisitOMPClauseList(C);
2793 void OMPClauseEnqueue::VisitOMPXAttributeClause(const OMPXAttributeClause *C) {
2795 void OMPClauseEnqueue::VisitOMPXBareClause(const OMPXBareClause *C) {}
2797 } // namespace
2799 void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2800 unsigned size = WL.size();
2801 OMPClauseEnqueue Visitor(this);
2802 Visitor.Visit(S);
2803 if (size == WL.size())
2804 return;
2805 // Now reverse the entries we just added. This will match the DFS
2806 // ordering performed by the worklist.
2807 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2808 std::reverse(I, E);
2811 namespace {
2812 class OpenACCClauseEnqueue : public OpenACCClauseVisitor<OpenACCClauseEnqueue> {
2813 EnqueueVisitor &Visitor;
2815 public:
2816 OpenACCClauseEnqueue(EnqueueVisitor &V) : Visitor(V) {}
2818 void VisitVarList(const OpenACCClauseWithVarList &C) {
2819 for (Expr *Var : C.getVarList())
2820 Visitor.AddStmt(Var);
2823 #define VISIT_CLAUSE(CLAUSE_NAME) \
2824 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &C);
2825 #include "clang/Basic/OpenACCClauses.def"
2828 void OpenACCClauseEnqueue::VisitDefaultClause(const OpenACCDefaultClause &C) {}
2829 void OpenACCClauseEnqueue::VisitIfClause(const OpenACCIfClause &C) {
2830 Visitor.AddStmt(C.getConditionExpr());
2832 void OpenACCClauseEnqueue::VisitSelfClause(const OpenACCSelfClause &C) {
2833 if (C.hasConditionExpr())
2834 Visitor.AddStmt(C.getConditionExpr());
2836 void OpenACCClauseEnqueue::VisitNumWorkersClause(
2837 const OpenACCNumWorkersClause &C) {
2838 Visitor.AddStmt(C.getIntExpr());
2840 void OpenACCClauseEnqueue::VisitVectorLengthClause(
2841 const OpenACCVectorLengthClause &C) {
2842 Visitor.AddStmt(C.getIntExpr());
2844 void OpenACCClauseEnqueue::VisitNumGangsClause(const OpenACCNumGangsClause &C) {
2845 for (Expr *IE : C.getIntExprs())
2846 Visitor.AddStmt(IE);
2849 void OpenACCClauseEnqueue::VisitTileClause(const OpenACCTileClause &C) {
2850 for (Expr *IE : C.getSizeExprs())
2851 Visitor.AddStmt(IE);
2854 void OpenACCClauseEnqueue::VisitPrivateClause(const OpenACCPrivateClause &C) {
2855 VisitVarList(C);
2858 void OpenACCClauseEnqueue::VisitFirstPrivateClause(
2859 const OpenACCFirstPrivateClause &C) {
2860 VisitVarList(C);
2863 void OpenACCClauseEnqueue::VisitPresentClause(const OpenACCPresentClause &C) {
2864 VisitVarList(C);
2866 void OpenACCClauseEnqueue::VisitNoCreateClause(const OpenACCNoCreateClause &C) {
2867 VisitVarList(C);
2869 void OpenACCClauseEnqueue::VisitCopyClause(const OpenACCCopyClause &C) {
2870 VisitVarList(C);
2872 void OpenACCClauseEnqueue::VisitCopyInClause(const OpenACCCopyInClause &C) {
2873 VisitVarList(C);
2875 void OpenACCClauseEnqueue::VisitCopyOutClause(const OpenACCCopyOutClause &C) {
2876 VisitVarList(C);
2878 void OpenACCClauseEnqueue::VisitCreateClause(const OpenACCCreateClause &C) {
2879 VisitVarList(C);
2881 void OpenACCClauseEnqueue::VisitAttachClause(const OpenACCAttachClause &C) {
2882 VisitVarList(C);
2884 void OpenACCClauseEnqueue::VisitDevicePtrClause(
2885 const OpenACCDevicePtrClause &C) {
2886 VisitVarList(C);
2888 void OpenACCClauseEnqueue::VisitAsyncClause(const OpenACCAsyncClause &C) {
2889 if (C.hasIntExpr())
2890 Visitor.AddStmt(C.getIntExpr());
2893 void OpenACCClauseEnqueue::VisitWorkerClause(const OpenACCWorkerClause &C) {
2894 if (C.hasIntExpr())
2895 Visitor.AddStmt(C.getIntExpr());
2898 void OpenACCClauseEnqueue::VisitVectorClause(const OpenACCVectorClause &C) {
2899 if (C.hasIntExpr())
2900 Visitor.AddStmt(C.getIntExpr());
2903 void OpenACCClauseEnqueue::VisitWaitClause(const OpenACCWaitClause &C) {
2904 if (const Expr *DevNumExpr = C.getDevNumExpr())
2905 Visitor.AddStmt(DevNumExpr);
2906 for (Expr *QE : C.getQueueIdExprs())
2907 Visitor.AddStmt(QE);
2909 void OpenACCClauseEnqueue::VisitDeviceTypeClause(
2910 const OpenACCDeviceTypeClause &C) {}
2911 void OpenACCClauseEnqueue::VisitReductionClause(
2912 const OpenACCReductionClause &C) {
2913 VisitVarList(C);
2915 void OpenACCClauseEnqueue::VisitAutoClause(const OpenACCAutoClause &C) {}
2916 void OpenACCClauseEnqueue::VisitIndependentClause(
2917 const OpenACCIndependentClause &C) {}
2918 void OpenACCClauseEnqueue::VisitSeqClause(const OpenACCSeqClause &C) {}
2919 void OpenACCClauseEnqueue::VisitCollapseClause(const OpenACCCollapseClause &C) {
2920 Visitor.AddStmt(C.getLoopCount());
2922 void OpenACCClauseEnqueue::VisitGangClause(const OpenACCGangClause &C) {
2923 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
2924 Visitor.AddStmt(C.getExpr(I).second);
2927 } // namespace
2929 void EnqueueVisitor::EnqueueChildren(const OpenACCClause *C) {
2930 unsigned size = WL.size();
2931 OpenACCClauseEnqueue Visitor(*this);
2932 Visitor.Visit(C);
2934 if (size == WL.size())
2935 return;
2936 // Now reverse the entries we just added. This will match the DFS
2937 // ordering performed by the worklist.
2938 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2939 std::reverse(I, E);
2942 void EnqueueVisitor::EnqueueChildren(const AnnotateAttr *A) {
2943 unsigned size = WL.size();
2944 for (const Expr *Arg : A->args()) {
2945 VisitStmt(Arg);
2947 if (size == WL.size())
2948 return;
2949 // Now reverse the entries we just added. This will match the DFS
2950 // ordering performed by the worklist.
2951 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2952 std::reverse(I, E);
2955 void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
2956 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2958 void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
2959 AddDecl(B->getBlockDecl());
2961 void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
2962 EnqueueChildren(E);
2963 AddTypeLoc(E->getTypeSourceInfo());
2965 void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2966 for (auto &I : llvm::reverse(S->body()))
2967 AddStmt(I);
2969 void EnqueueVisitor::VisitMSDependentExistsStmt(
2970 const MSDependentExistsStmt *S) {
2971 AddStmt(S->getSubStmt());
2972 AddDeclarationNameInfo(S);
2973 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2974 AddNestedNameSpecifierLoc(QualifierLoc);
2977 void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2978 const CXXDependentScopeMemberExpr *E) {
2979 if (E->hasExplicitTemplateArgs())
2980 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2981 AddDeclarationNameInfo(E);
2982 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2983 AddNestedNameSpecifierLoc(QualifierLoc);
2984 if (!E->isImplicitAccess())
2985 AddStmt(E->getBase());
2987 void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
2988 // Enqueue the initializer , if any.
2989 AddStmt(E->getInitializer());
2990 // Enqueue the array size, if any.
2991 AddStmt(E->getArraySize().value_or(nullptr));
2992 // Enqueue the allocated type.
2993 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2994 // Enqueue the placement arguments.
2995 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2996 AddStmt(E->getPlacementArg(I - 1));
2998 void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
2999 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
3000 AddStmt(CE->getArg(I - 1));
3001 AddStmt(CE->getCallee());
3002 AddStmt(CE->getArg(0));
3004 void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
3005 const CXXPseudoDestructorExpr *E) {
3006 // Visit the name of the type being destroyed.
3007 AddTypeLoc(E->getDestroyedTypeInfo());
3008 // Visit the scope type that looks disturbingly like the nested-name-specifier
3009 // but isn't.
3010 AddTypeLoc(E->getScopeTypeInfo());
3011 // Visit the nested-name-specifier.
3012 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
3013 AddNestedNameSpecifierLoc(QualifierLoc);
3014 // Visit base expression.
3015 AddStmt(E->getBase());
3017 void EnqueueVisitor::VisitCXXScalarValueInitExpr(
3018 const CXXScalarValueInitExpr *E) {
3019 AddTypeLoc(E->getTypeSourceInfo());
3021 void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
3022 const CXXTemporaryObjectExpr *E) {
3023 EnqueueChildren(E);
3024 AddTypeLoc(E->getTypeSourceInfo());
3026 void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
3027 EnqueueChildren(E);
3028 if (E->isTypeOperand())
3029 AddTypeLoc(E->getTypeOperandSourceInfo());
3032 void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
3033 const CXXUnresolvedConstructExpr *E) {
3034 EnqueueChildren(E);
3035 AddTypeLoc(E->getTypeSourceInfo());
3037 void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
3038 EnqueueChildren(E);
3039 if (E->isTypeOperand())
3040 AddTypeLoc(E->getTypeOperandSourceInfo());
3043 void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
3044 EnqueueChildren(S);
3045 AddDecl(S->getExceptionDecl());
3048 void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
3049 AddStmt(S->getBody());
3050 AddStmt(S->getRangeInit());
3051 AddDecl(S->getLoopVariable());
3054 void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
3055 if (DR->hasExplicitTemplateArgs())
3056 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
3057 WL.push_back(DeclRefExprParts(DR, Parent));
3059 void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
3060 const DependentScopeDeclRefExpr *E) {
3061 if (E->hasExplicitTemplateArgs())
3062 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
3063 AddDeclarationNameInfo(E);
3064 AddNestedNameSpecifierLoc(E->getQualifierLoc());
3066 void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
3067 unsigned size = WL.size();
3068 bool isFirst = true;
3069 for (const auto *D : S->decls()) {
3070 AddDecl(D, isFirst);
3071 isFirst = false;
3073 if (size == WL.size())
3074 return;
3075 // Now reverse the entries we just added. This will match the DFS
3076 // ordering performed by the worklist.
3077 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
3078 std::reverse(I, E);
3080 void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
3081 AddStmt(E->getInit());
3082 for (const DesignatedInitExpr::Designator &D :
3083 llvm::reverse(E->designators())) {
3084 if (D.isFieldDesignator()) {
3085 if (const FieldDecl *Field = D.getFieldDecl())
3086 AddMemberRef(Field, D.getFieldLoc());
3087 continue;
3089 if (D.isArrayDesignator()) {
3090 AddStmt(E->getArrayIndex(D));
3091 continue;
3093 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
3094 AddStmt(E->getArrayRangeEnd(D));
3095 AddStmt(E->getArrayRangeStart(D));
3098 void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
3099 EnqueueChildren(E);
3100 AddTypeLoc(E->getTypeInfoAsWritten());
3102 void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
3103 AddStmt(FS->getBody());
3104 AddStmt(FS->getInc());
3105 AddStmt(FS->getCond());
3106 AddDecl(FS->getConditionVariable());
3107 AddStmt(FS->getInit());
3109 void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
3110 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
3112 void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
3113 AddStmt(If->getElse());
3114 AddStmt(If->getThen());
3115 AddStmt(If->getCond());
3116 AddStmt(If->getInit());
3117 AddDecl(If->getConditionVariable());
3119 void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
3120 // We care about the syntactic form of the initializer list, only.
3121 if (InitListExpr *Syntactic = IE->getSyntacticForm())
3122 IE = Syntactic;
3123 EnqueueChildren(IE);
3125 void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
3126 WL.push_back(MemberExprParts(M, Parent));
3128 // If the base of the member access expression is an implicit 'this', don't
3129 // visit it.
3130 // FIXME: If we ever want to show these implicit accesses, this will be
3131 // unfortunate. However, clang_getCursor() relies on this behavior.
3132 if (M->isImplicitAccess())
3133 return;
3135 // Ignore base anonymous struct/union fields, otherwise they will shadow the
3136 // real field that we are interested in.
3137 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
3138 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
3139 if (FD->isAnonymousStructOrUnion()) {
3140 AddStmt(SubME->getBase());
3141 return;
3146 AddStmt(M->getBase());
3148 void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
3149 AddTypeLoc(E->getEncodedTypeSourceInfo());
3151 void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
3152 EnqueueChildren(M);
3153 AddTypeLoc(M->getClassReceiverTypeInfo());
3155 void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
3156 // Visit the components of the offsetof expression.
3157 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
3158 const OffsetOfNode &Node = E->getComponent(I - 1);
3159 switch (Node.getKind()) {
3160 case OffsetOfNode::Array:
3161 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
3162 break;
3163 case OffsetOfNode::Field:
3164 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
3165 break;
3166 case OffsetOfNode::Identifier:
3167 case OffsetOfNode::Base:
3168 continue;
3171 // Visit the type into which we're computing the offset.
3172 AddTypeLoc(E->getTypeSourceInfo());
3174 void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
3175 if (E->hasExplicitTemplateArgs())
3176 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
3177 WL.push_back(OverloadExprParts(E, Parent));
3179 void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
3180 const UnaryExprOrTypeTraitExpr *E) {
3181 EnqueueChildren(E);
3182 if (E->isArgumentType())
3183 AddTypeLoc(E->getArgumentTypeInfo());
3185 void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
3186 void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
3187 AddStmt(S->getBody());
3188 AddStmt(S->getCond());
3189 AddDecl(S->getConditionVariable());
3192 void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
3193 AddStmt(W->getBody());
3194 AddStmt(W->getCond());
3195 AddDecl(W->getConditionVariable());
3198 void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
3199 for (unsigned I = E->getNumArgs(); I > 0; --I)
3200 AddTypeLoc(E->getArg(I - 1));
3203 void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
3204 AddTypeLoc(E->getQueriedTypeSourceInfo());
3207 void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
3208 EnqueueChildren(E);
3211 void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
3212 VisitOverloadExpr(U);
3213 if (!U->isImplicitAccess())
3214 AddStmt(U->getBase());
3216 void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
3217 AddStmt(E->getSubExpr());
3218 AddTypeLoc(E->getWrittenTypeInfo());
3220 void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
3221 WL.push_back(SizeOfPackExprParts(E, Parent));
3223 void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
3224 // If the opaque value has a source expression, just transparently
3225 // visit that. This is useful for (e.g.) pseudo-object expressions.
3226 if (Expr *SourceExpr = E->getSourceExpr())
3227 return ConstStmtVisitor::Visit(SourceExpr);
3229 void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
3230 AddStmt(E->getBody());
3231 WL.push_back(LambdaExprParts(E, Parent));
3233 void EnqueueVisitor::VisitConceptSpecializationExpr(
3234 const ConceptSpecializationExpr *E) {
3235 WL.push_back(ConceptSpecializationExprVisit(E, Parent));
3237 void EnqueueVisitor::VisitRequiresExpr(const RequiresExpr *E) {
3238 WL.push_back(RequiresExprVisit(E, Parent));
3239 for (ParmVarDecl *VD : E->getLocalParameters())
3240 AddDecl(VD);
3242 void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr *E) {
3243 EnqueueChildren(E);
3245 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
3246 // Treat the expression like its syntactic form.
3247 ConstStmtVisitor::Visit(E->getSyntacticForm());
3250 void EnqueueVisitor::VisitOMPExecutableDirective(
3251 const OMPExecutableDirective *D) {
3252 EnqueueChildren(D);
3253 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
3254 E = D->clauses().end();
3255 I != E; ++I)
3256 EnqueueChildren(*I);
3259 void EnqueueVisitor::VisitOMPLoopBasedDirective(
3260 const OMPLoopBasedDirective *D) {
3261 VisitOMPExecutableDirective(D);
3264 void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
3265 VisitOMPLoopBasedDirective(D);
3268 void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
3269 VisitOMPExecutableDirective(D);
3272 void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
3273 VisitOMPLoopDirective(D);
3276 void EnqueueVisitor::VisitOMPLoopTransformationDirective(
3277 const OMPLoopTransformationDirective *D) {
3278 VisitOMPLoopBasedDirective(D);
3281 void EnqueueVisitor::VisitOMPTileDirective(const OMPTileDirective *D) {
3282 VisitOMPLoopTransformationDirective(D);
3285 void EnqueueVisitor::VisitOMPUnrollDirective(const OMPUnrollDirective *D) {
3286 VisitOMPLoopTransformationDirective(D);
3289 void EnqueueVisitor::VisitOMPReverseDirective(const OMPReverseDirective *D) {
3290 VisitOMPLoopTransformationDirective(D);
3293 void EnqueueVisitor::VisitOMPInterchangeDirective(
3294 const OMPInterchangeDirective *D) {
3295 VisitOMPLoopTransformationDirective(D);
3298 void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
3299 VisitOMPLoopDirective(D);
3302 void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
3303 VisitOMPLoopDirective(D);
3306 void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
3307 VisitOMPExecutableDirective(D);
3310 void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
3311 VisitOMPExecutableDirective(D);
3314 void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
3315 VisitOMPExecutableDirective(D);
3318 void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
3319 VisitOMPExecutableDirective(D);
3322 void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
3323 VisitOMPExecutableDirective(D);
3324 AddDeclarationNameInfo(D);
3327 void EnqueueVisitor::VisitOMPParallelForDirective(
3328 const OMPParallelForDirective *D) {
3329 VisitOMPLoopDirective(D);
3332 void EnqueueVisitor::VisitOMPParallelForSimdDirective(
3333 const OMPParallelForSimdDirective *D) {
3334 VisitOMPLoopDirective(D);
3337 void EnqueueVisitor::VisitOMPParallelMasterDirective(
3338 const OMPParallelMasterDirective *D) {
3339 VisitOMPExecutableDirective(D);
3342 void EnqueueVisitor::VisitOMPParallelMaskedDirective(
3343 const OMPParallelMaskedDirective *D) {
3344 VisitOMPExecutableDirective(D);
3347 void EnqueueVisitor::VisitOMPParallelSectionsDirective(
3348 const OMPParallelSectionsDirective *D) {
3349 VisitOMPExecutableDirective(D);
3352 void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
3353 VisitOMPExecutableDirective(D);
3356 void EnqueueVisitor::VisitOMPTaskyieldDirective(
3357 const OMPTaskyieldDirective *D) {
3358 VisitOMPExecutableDirective(D);
3361 void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
3362 VisitOMPExecutableDirective(D);
3365 void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
3366 VisitOMPExecutableDirective(D);
3369 void EnqueueVisitor::VisitOMPAssumeDirective(const OMPAssumeDirective *D) {
3370 VisitOMPExecutableDirective(D);
3373 void EnqueueVisitor::VisitOMPErrorDirective(const OMPErrorDirective *D) {
3374 VisitOMPExecutableDirective(D);
3377 void EnqueueVisitor::VisitOMPTaskgroupDirective(
3378 const OMPTaskgroupDirective *D) {
3379 VisitOMPExecutableDirective(D);
3380 if (const Expr *E = D->getReductionRef())
3381 VisitStmt(E);
3384 void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
3385 VisitOMPExecutableDirective(D);
3388 void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
3389 VisitOMPExecutableDirective(D);
3392 void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
3393 VisitOMPExecutableDirective(D);
3396 void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
3397 VisitOMPExecutableDirective(D);
3400 void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
3401 VisitOMPExecutableDirective(D);
3404 void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
3405 VisitOMPExecutableDirective(D);
3408 void EnqueueVisitor::VisitOMPTargetDataDirective(
3409 const OMPTargetDataDirective *D) {
3410 VisitOMPExecutableDirective(D);
3413 void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
3414 const OMPTargetEnterDataDirective *D) {
3415 VisitOMPExecutableDirective(D);
3418 void EnqueueVisitor::VisitOMPTargetExitDataDirective(
3419 const OMPTargetExitDataDirective *D) {
3420 VisitOMPExecutableDirective(D);
3423 void EnqueueVisitor::VisitOMPTargetParallelDirective(
3424 const OMPTargetParallelDirective *D) {
3425 VisitOMPExecutableDirective(D);
3428 void EnqueueVisitor::VisitOMPTargetParallelForDirective(
3429 const OMPTargetParallelForDirective *D) {
3430 VisitOMPLoopDirective(D);
3433 void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
3434 VisitOMPExecutableDirective(D);
3437 void EnqueueVisitor::VisitOMPCancellationPointDirective(
3438 const OMPCancellationPointDirective *D) {
3439 VisitOMPExecutableDirective(D);
3442 void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
3443 VisitOMPExecutableDirective(D);
3446 void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
3447 VisitOMPLoopDirective(D);
3450 void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
3451 const OMPTaskLoopSimdDirective *D) {
3452 VisitOMPLoopDirective(D);
3455 void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
3456 const OMPMasterTaskLoopDirective *D) {
3457 VisitOMPLoopDirective(D);
3460 void EnqueueVisitor::VisitOMPMaskedTaskLoopDirective(
3461 const OMPMaskedTaskLoopDirective *D) {
3462 VisitOMPLoopDirective(D);
3465 void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
3466 const OMPMasterTaskLoopSimdDirective *D) {
3467 VisitOMPLoopDirective(D);
3470 void EnqueueVisitor::VisitOMPMaskedTaskLoopSimdDirective(
3471 const OMPMaskedTaskLoopSimdDirective *D) {
3472 VisitOMPLoopDirective(D);
3475 void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
3476 const OMPParallelMasterTaskLoopDirective *D) {
3477 VisitOMPLoopDirective(D);
3480 void EnqueueVisitor::VisitOMPParallelMaskedTaskLoopDirective(
3481 const OMPParallelMaskedTaskLoopDirective *D) {
3482 VisitOMPLoopDirective(D);
3485 void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
3486 const OMPParallelMasterTaskLoopSimdDirective *D) {
3487 VisitOMPLoopDirective(D);
3490 void EnqueueVisitor::VisitOMPParallelMaskedTaskLoopSimdDirective(
3491 const OMPParallelMaskedTaskLoopSimdDirective *D) {
3492 VisitOMPLoopDirective(D);
3495 void EnqueueVisitor::VisitOMPDistributeDirective(
3496 const OMPDistributeDirective *D) {
3497 VisitOMPLoopDirective(D);
3500 void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
3501 const OMPDistributeParallelForDirective *D) {
3502 VisitOMPLoopDirective(D);
3505 void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
3506 const OMPDistributeParallelForSimdDirective *D) {
3507 VisitOMPLoopDirective(D);
3510 void EnqueueVisitor::VisitOMPDistributeSimdDirective(
3511 const OMPDistributeSimdDirective *D) {
3512 VisitOMPLoopDirective(D);
3515 void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
3516 const OMPTargetParallelForSimdDirective *D) {
3517 VisitOMPLoopDirective(D);
3520 void EnqueueVisitor::VisitOMPTargetSimdDirective(
3521 const OMPTargetSimdDirective *D) {
3522 VisitOMPLoopDirective(D);
3525 void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3526 const OMPTeamsDistributeDirective *D) {
3527 VisitOMPLoopDirective(D);
3530 void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3531 const OMPTeamsDistributeSimdDirective *D) {
3532 VisitOMPLoopDirective(D);
3535 void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3536 const OMPTeamsDistributeParallelForSimdDirective *D) {
3537 VisitOMPLoopDirective(D);
3540 void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3541 const OMPTeamsDistributeParallelForDirective *D) {
3542 VisitOMPLoopDirective(D);
3545 void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3546 const OMPTargetTeamsDirective *D) {
3547 VisitOMPExecutableDirective(D);
3550 void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3551 const OMPTargetTeamsDistributeDirective *D) {
3552 VisitOMPLoopDirective(D);
3555 void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3556 const OMPTargetTeamsDistributeParallelForDirective *D) {
3557 VisitOMPLoopDirective(D);
3560 void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3561 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3562 VisitOMPLoopDirective(D);
3565 void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3566 const OMPTargetTeamsDistributeSimdDirective *D) {
3567 VisitOMPLoopDirective(D);
3570 void EnqueueVisitor::VisitOpenACCComputeConstruct(
3571 const OpenACCComputeConstruct *C) {
3572 EnqueueChildren(C);
3573 for (auto *Clause : C->clauses())
3574 EnqueueChildren(Clause);
3577 void EnqueueVisitor::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *C) {
3578 EnqueueChildren(C);
3579 for (auto *Clause : C->clauses())
3580 EnqueueChildren(Clause);
3583 void EnqueueVisitor::VisitOpenACCCombinedConstruct(
3584 const OpenACCCombinedConstruct *C) {
3585 EnqueueChildren(C);
3586 for (auto *Clause : C->clauses())
3587 EnqueueChildren(Clause);
3590 void EnqueueVisitor::VisitAnnotateAttr(const AnnotateAttr *A) {
3591 EnqueueChildren(A);
3594 void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
3595 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3596 .ConstStmtVisitor::Visit(S);
3599 void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Attr *A) {
3600 // Parent is the attribute itself when this is indirectly called from
3601 // VisitChildren. Because we need to make a CXCursor for A, we need *its*
3602 // parent.
3603 auto AttrCursor = Parent;
3605 // Get the attribute's parent as stored in
3606 // cxcursor::MakeCXCursor(const Attr *A, const Decl *Parent, CXTranslationUnit
3607 // TU)
3608 const Decl *AttrParent = static_cast<const Decl *>(AttrCursor.data[1]);
3610 EnqueueVisitor(WL, MakeCXCursor(A, AttrParent, TU))
3611 .ConstAttrVisitor::Visit(A);
3614 bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3615 if (RegionOfInterest.isValid()) {
3616 SourceRange Range = getRawCursorExtent(C);
3617 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3618 return false;
3620 return true;
3623 bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3624 while (!WL.empty()) {
3625 // Dequeue the worklist item.
3626 VisitorJob LI = WL.pop_back_val();
3628 // Set the Parent field, then back to its old value once we're done.
3629 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
3631 switch (LI.getKind()) {
3632 case VisitorJob::DeclVisitKind: {
3633 const Decl *D = cast<DeclVisit>(&LI)->get();
3634 if (!D)
3635 continue;
3637 // For now, perform default visitation for Decls.
3638 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3639 cast<DeclVisit>(&LI)->isFirst())))
3640 return true;
3642 continue;
3644 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3645 for (const TemplateArgumentLoc &Arg :
3646 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3647 if (VisitTemplateArgumentLoc(Arg))
3648 return true;
3650 continue;
3652 case VisitorJob::TypeLocVisitKind: {
3653 // Perform default visitation for TypeLocs.
3654 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3655 return true;
3656 continue;
3658 case VisitorJob::LabelRefVisitKind: {
3659 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3660 if (LabelStmt *stmt = LS->getStmt()) {
3661 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3662 TU))) {
3663 return true;
3666 continue;
3669 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3670 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3671 if (VisitNestedNameSpecifierLoc(V->get()))
3672 return true;
3673 continue;
3676 case VisitorJob::DeclarationNameInfoVisitKind: {
3677 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3678 return true;
3679 continue;
3681 case VisitorJob::MemberRefVisitKind: {
3682 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3683 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3684 return true;
3685 continue;
3687 case VisitorJob::StmtVisitKind: {
3688 const Stmt *S = cast<StmtVisit>(&LI)->get();
3689 if (!S)
3690 continue;
3692 // Update the current cursor.
3693 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3694 if (!IsInRegionOfInterest(Cursor))
3695 continue;
3696 switch (Visitor(Cursor, Parent, ClientData)) {
3697 case CXChildVisit_Break:
3698 return true;
3699 case CXChildVisit_Continue:
3700 break;
3701 case CXChildVisit_Recurse:
3702 if (PostChildrenVisitor)
3703 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3704 EnqueueWorkList(WL, S);
3705 break;
3707 continue;
3709 case VisitorJob::MemberExprPartsKind: {
3710 // Handle the other pieces in the MemberExpr besides the base.
3711 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
3713 // Visit the nested-name-specifier
3714 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3715 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3716 return true;
3718 // Visit the declaration name.
3719 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3720 return true;
3722 // Visit the explicitly-specified template arguments, if any.
3723 if (M->hasExplicitTemplateArgs()) {
3724 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3725 *ArgEnd = Arg + M->getNumTemplateArgs();
3726 Arg != ArgEnd; ++Arg) {
3727 if (VisitTemplateArgumentLoc(*Arg))
3728 return true;
3731 continue;
3733 case VisitorJob::DeclRefExprPartsKind: {
3734 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3735 // Visit nested-name-specifier, if present.
3736 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3737 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3738 return true;
3739 // Visit declaration name.
3740 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3741 return true;
3742 continue;
3744 case VisitorJob::OverloadExprPartsKind: {
3745 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3746 // Visit the nested-name-specifier.
3747 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3748 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3749 return true;
3750 // Visit the declaration name.
3751 if (VisitDeclarationNameInfo(O->getNameInfo()))
3752 return true;
3753 // Visit the overloaded declaration reference.
3754 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3755 return true;
3756 continue;
3758 case VisitorJob::SizeOfPackExprPartsKind: {
3759 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3760 NamedDecl *Pack = E->getPack();
3761 if (isa<TemplateTypeParmDecl>(Pack)) {
3762 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3763 E->getPackLoc(), TU)))
3764 return true;
3766 continue;
3769 if (isa<TemplateTemplateParmDecl>(Pack)) {
3770 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3771 E->getPackLoc(), TU)))
3772 return true;
3774 continue;
3777 // Non-type template parameter packs and function parameter packs are
3778 // treated like DeclRefExpr cursors.
3779 continue;
3782 case VisitorJob::LambdaExprPartsKind: {
3783 // Visit non-init captures.
3784 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3785 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3786 CEnd = E->explicit_capture_end();
3787 C != CEnd; ++C) {
3788 if (!C->capturesVariable())
3789 continue;
3790 // TODO: handle structured bindings here ?
3791 if (!isa<VarDecl>(C->getCapturedVar()))
3792 continue;
3793 if (Visit(MakeCursorVariableRef(cast<VarDecl>(C->getCapturedVar()),
3794 C->getLocation(), TU)))
3795 return true;
3797 // Visit init captures
3798 for (auto InitExpr : E->capture_inits()) {
3799 if (InitExpr && Visit(InitExpr))
3800 return true;
3803 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3804 // Visit parameters and return type, if present.
3805 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3806 if (E->hasExplicitParameters()) {
3807 // Visit parameters.
3808 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3809 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3810 return true;
3812 if (E->hasExplicitResultType()) {
3813 // Visit result type.
3814 if (Visit(Proto.getReturnLoc()))
3815 return true;
3818 break;
3821 case VisitorJob::ConceptSpecializationExprVisitKind: {
3822 const ConceptSpecializationExpr *E =
3823 cast<ConceptSpecializationExprVisit>(&LI)->get();
3824 if (NestedNameSpecifierLoc QualifierLoc =
3825 E->getNestedNameSpecifierLoc()) {
3826 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3827 return true;
3830 if (E->getNamedConcept() &&
3831 Visit(MakeCursorTemplateRef(E->getNamedConcept(),
3832 E->getConceptNameLoc(), TU)))
3833 return true;
3835 if (auto Args = E->getTemplateArgsAsWritten()) {
3836 for (const auto &Arg : Args->arguments()) {
3837 if (VisitTemplateArgumentLoc(Arg))
3838 return true;
3841 break;
3844 case VisitorJob::RequiresExprVisitKind: {
3845 const RequiresExpr *E = cast<RequiresExprVisit>(&LI)->get();
3846 for (const concepts::Requirement *R : E->getRequirements())
3847 VisitConceptRequirement(*R);
3848 break;
3851 case VisitorJob::PostChildrenVisitKind:
3852 if (PostChildrenVisitor(Parent, ClientData))
3853 return true;
3854 break;
3857 return false;
3860 bool CursorVisitor::Visit(const Stmt *S) {
3861 VisitorWorkList *WL = nullptr;
3862 if (!WorkListFreeList.empty()) {
3863 WL = WorkListFreeList.back();
3864 WL->clear();
3865 WorkListFreeList.pop_back();
3866 } else {
3867 WL = new VisitorWorkList();
3868 WorkListCache.push_back(WL);
3870 EnqueueWorkList(*WL, S);
3871 bool result = RunVisitorWorkList(*WL);
3872 WorkListFreeList.push_back(WL);
3873 return result;
3876 bool CursorVisitor::Visit(const Attr *A) {
3877 VisitorWorkList *WL = nullptr;
3878 if (!WorkListFreeList.empty()) {
3879 WL = WorkListFreeList.back();
3880 WL->clear();
3881 WorkListFreeList.pop_back();
3882 } else {
3883 WL = new VisitorWorkList();
3884 WorkListCache.push_back(WL);
3886 EnqueueWorkList(*WL, A);
3887 bool result = RunVisitorWorkList(*WL);
3888 WorkListFreeList.push_back(WL);
3889 return result;
3892 namespace {
3893 typedef SmallVector<SourceRange, 4> RefNamePieces;
3894 RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3895 const DeclarationNameInfo &NI, SourceRange QLoc,
3896 const SourceRange *TemplateArgsLoc = nullptr) {
3897 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3898 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3899 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
3901 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
3903 RefNamePieces Pieces;
3905 if (WantQualifier && QLoc.isValid())
3906 Pieces.push_back(QLoc);
3908 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3909 Pieces.push_back(NI.getLoc());
3911 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3912 Pieces.push_back(*TemplateArgsLoc);
3914 if (Kind == DeclarationName::CXXOperatorName) {
3915 Pieces.push_back(NI.getInfo().getCXXOperatorNameBeginLoc());
3916 Pieces.push_back(NI.getInfo().getCXXOperatorNameEndLoc());
3919 if (WantSinglePiece) {
3920 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3921 Pieces.clear();
3922 Pieces.push_back(R);
3925 return Pieces;
3927 } // namespace
3929 //===----------------------------------------------------------------------===//
3930 // Misc. API hooks.
3931 //===----------------------------------------------------------------------===//
3933 namespace {
3934 struct RegisterFatalErrorHandler {
3935 RegisterFatalErrorHandler() {
3936 clang_install_aborting_llvm_fatal_error_handler();
3939 } // namespace
3941 static llvm::ManagedStatic<RegisterFatalErrorHandler>
3942 RegisterFatalErrorHandlerOnce;
3944 static CIndexer *clang_createIndex_Impl(
3945 int excludeDeclarationsFromPCH, int displayDiagnostics,
3946 unsigned char threadBackgroundPriorityForIndexing = CXChoice_Default,
3947 unsigned char threadBackgroundPriorityForEditing = CXChoice_Default) {
3948 // We use crash recovery to make some of our APIs more reliable, implicitly
3949 // enable it.
3950 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3951 llvm::CrashRecoveryContext::Enable();
3953 // Look through the managed static to trigger construction of the managed
3954 // static which registers our fatal error handler. This ensures it is only
3955 // registered once.
3956 (void)*RegisterFatalErrorHandlerOnce;
3958 // Initialize targets for clang module support.
3959 llvm::InitializeAllTargets();
3960 llvm::InitializeAllTargetMCs();
3961 llvm::InitializeAllAsmPrinters();
3962 llvm::InitializeAllAsmParsers();
3964 CIndexer *CIdxr = new CIndexer();
3966 if (excludeDeclarationsFromPCH)
3967 CIdxr->setOnlyLocalDecls();
3968 if (displayDiagnostics)
3969 CIdxr->setDisplayDiagnostics();
3971 unsigned GlobalOptions = CIdxr->getCXGlobalOptFlags();
3972 const auto updateGlobalOption =
3973 [&GlobalOptions](unsigned char Policy, CXGlobalOptFlags Flag,
3974 const char *EnvironmentVariableName) {
3975 switch (Policy) {
3976 case CXChoice_Enabled:
3977 GlobalOptions |= Flag;
3978 break;
3979 case CXChoice_Disabled:
3980 GlobalOptions &= ~Flag;
3981 break;
3982 case CXChoice_Default:
3983 default: // Fall back to default behavior if Policy is unsupported.
3984 if (getenv(EnvironmentVariableName))
3985 GlobalOptions |= Flag;
3988 updateGlobalOption(threadBackgroundPriorityForIndexing,
3989 CXGlobalOpt_ThreadBackgroundPriorityForIndexing,
3990 "LIBCLANG_BGPRIO_INDEX");
3991 updateGlobalOption(threadBackgroundPriorityForEditing,
3992 CXGlobalOpt_ThreadBackgroundPriorityForEditing,
3993 "LIBCLANG_BGPRIO_EDIT");
3994 CIdxr->setCXGlobalOptFlags(GlobalOptions);
3996 return CIdxr;
3999 CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
4000 int displayDiagnostics) {
4001 return clang_createIndex_Impl(excludeDeclarationsFromPCH, displayDiagnostics);
4004 void clang_disposeIndex(CXIndex CIdx) {
4005 if (CIdx)
4006 delete static_cast<CIndexer *>(CIdx);
4009 CXIndex clang_createIndexWithOptions(const CXIndexOptions *options) {
4010 // Adding new options to struct CXIndexOptions:
4011 // 1. If no other new option has been added in the same libclang version,
4012 // sizeof(CXIndexOptions) must increase for versioning purposes.
4013 // 2. Options should be added at the end of the struct in order to seamlessly
4014 // support older struct versions. If options->Size < sizeof(CXIndexOptions),
4015 // don't attempt to read the missing options and rely on the default values of
4016 // recently added options being reasonable. For example:
4017 // if (options->Size >= offsetof(CXIndexOptions, RecentlyAddedMember))
4018 // do_something(options->RecentlyAddedMember);
4020 // An exception: if a new option is small enough, it can be squeezed into the
4021 // /*Reserved*/ bits in CXIndexOptions. Since the default value of each option
4022 // is guaranteed to be 0 and the callers are advised to zero out the struct,
4023 // programs built against older libclang versions would implicitly set the new
4024 // options to default values, which should keep the behavior of previous
4025 // libclang versions and thus be backward-compatible.
4027 // If options->Size > sizeof(CXIndexOptions), the user may have set an option
4028 // we can't handle, in which case we return nullptr to report failure.
4029 // Replace `!=` with `>` here to support older struct versions. `!=` has the
4030 // advantage of catching more usage bugs and no disadvantages while there is a
4031 // single supported struct version (the initial version).
4032 if (options->Size != sizeof(CXIndexOptions))
4033 return nullptr;
4034 CIndexer *const CIdxr = clang_createIndex_Impl(
4035 options->ExcludeDeclarationsFromPCH, options->DisplayDiagnostics,
4036 options->ThreadBackgroundPriorityForIndexing,
4037 options->ThreadBackgroundPriorityForEditing);
4038 CIdxr->setStorePreamblesInMemory(options->StorePreamblesInMemory);
4039 CIdxr->setPreambleStoragePath(options->PreambleStoragePath);
4040 CIdxr->setInvocationEmissionPath(options->InvocationEmissionPath);
4041 return CIdxr;
4044 void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
4045 if (CIdx)
4046 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
4049 unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
4050 if (CIdx)
4051 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
4052 return 0;
4055 void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
4056 const char *Path) {
4057 if (CIdx)
4058 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
4061 void clang_toggleCrashRecovery(unsigned isEnabled) {
4062 if (isEnabled)
4063 llvm::CrashRecoveryContext::Enable();
4064 else
4065 llvm::CrashRecoveryContext::Disable();
4068 CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
4069 const char *ast_filename) {
4070 CXTranslationUnit TU;
4071 enum CXErrorCode Result =
4072 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
4073 (void)Result;
4074 assert((TU && Result == CXError_Success) ||
4075 (!TU && Result != CXError_Success));
4076 return TU;
4079 enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
4080 const char *ast_filename,
4081 CXTranslationUnit *out_TU) {
4082 if (out_TU)
4083 *out_TU = nullptr;
4085 if (!CIdx || !ast_filename || !out_TU)
4086 return CXError_InvalidArguments;
4088 LOG_FUNC_SECTION { *Log << ast_filename; }
4090 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
4091 FileSystemOptions FileSystemOpts;
4092 auto HSOpts = std::make_shared<HeaderSearchOptions>();
4094 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
4095 CompilerInstance::createDiagnostics(new DiagnosticOptions());
4096 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
4097 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
4098 ASTUnit::LoadEverything, Diags, FileSystemOpts, HSOpts,
4099 /*LangOpts=*/nullptr, CXXIdx->getOnlyLocalDecls(), CaptureDiagsKind::All,
4100 /*AllowASTWithCompilerErrors=*/true,
4101 /*UserFilesAreVolatile=*/true);
4102 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
4103 return *out_TU ? CXError_Success : CXError_Failure;
4106 unsigned clang_defaultEditingTranslationUnitOptions() {
4107 return CXTranslationUnit_PrecompiledPreamble |
4108 CXTranslationUnit_CacheCompletionResults;
4111 CXTranslationUnit clang_createTranslationUnitFromSourceFile(
4112 CXIndex CIdx, const char *source_filename, int num_command_line_args,
4113 const char *const *command_line_args, unsigned num_unsaved_files,
4114 struct CXUnsavedFile *unsaved_files) {
4115 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
4116 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
4117 num_command_line_args, unsaved_files,
4118 num_unsaved_files, Options);
4121 static CXErrorCode
4122 clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
4123 const char *const *command_line_args,
4124 int num_command_line_args,
4125 ArrayRef<CXUnsavedFile> unsaved_files,
4126 unsigned options, CXTranslationUnit *out_TU) {
4127 // Set up the initial return values.
4128 if (out_TU)
4129 *out_TU = nullptr;
4131 // Check arguments.
4132 if (!CIdx || !out_TU)
4133 return CXError_InvalidArguments;
4135 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
4137 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4138 setThreadBackgroundPriority();
4140 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
4141 bool CreatePreambleOnFirstParse =
4142 options & CXTranslationUnit_CreatePreambleOnFirstParse;
4143 // FIXME: Add a flag for modules.
4144 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
4145 CXTranslationUnit_SingleFileParse))
4146 ? TU_Prefix
4147 : TU_Complete;
4148 bool CacheCodeCompletionResults =
4149 options & CXTranslationUnit_CacheCompletionResults;
4150 bool IncludeBriefCommentsInCodeCompletion =
4151 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
4152 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
4153 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
4154 bool RetainExcludedCB =
4155 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
4156 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
4157 if (options & CXTranslationUnit_SkipFunctionBodies) {
4158 SkipFunctionBodies =
4159 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
4160 ? SkipFunctionBodiesScope::Preamble
4161 : SkipFunctionBodiesScope::PreambleAndMainFile;
4164 // Configure the diagnostics.
4165 std::unique_ptr<DiagnosticOptions> DiagOpts = CreateAndPopulateDiagOpts(
4166 llvm::ArrayRef(command_line_args, num_command_line_args));
4167 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
4168 CompilerInstance::createDiagnostics(DiagOpts.release()));
4170 if (options & CXTranslationUnit_KeepGoing)
4171 Diags->setFatalsAsError(true);
4173 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
4174 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
4175 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
4177 // Recover resources if we crash before exiting this function.
4178 llvm::CrashRecoveryContextCleanupRegistrar<
4179 DiagnosticsEngine,
4180 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
4181 DiagCleanup(Diags.get());
4183 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4184 new std::vector<ASTUnit::RemappedFile>());
4186 // Recover resources if we crash before exiting this function.
4187 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4188 RemappedCleanup(RemappedFiles.get());
4190 for (auto &UF : unsaved_files) {
4191 std::unique_ptr<llvm::MemoryBuffer> MB =
4192 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
4193 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
4196 std::unique_ptr<std::vector<const char *>> Args(
4197 new std::vector<const char *>());
4199 // Recover resources if we crash before exiting this method.
4200 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
4201 ArgsCleanup(Args.get());
4203 // Since the Clang C library is primarily used by batch tools dealing with
4204 // (often very broken) source code, where spell-checking can have a
4205 // significant negative impact on performance (particularly when
4206 // precompiled headers are involved), we disable it by default.
4207 // Only do this if we haven't found a spell-checking-related argument.
4208 bool FoundSpellCheckingArgument = false;
4209 for (int I = 0; I != num_command_line_args; ++I) {
4210 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
4211 strcmp(command_line_args[I], "-fspell-checking") == 0) {
4212 FoundSpellCheckingArgument = true;
4213 break;
4216 Args->insert(Args->end(), command_line_args,
4217 command_line_args + num_command_line_args);
4219 if (!FoundSpellCheckingArgument)
4220 Args->insert(Args->begin() + 1, "-fno-spell-checking");
4222 // The 'source_filename' argument is optional. If the caller does not
4223 // specify it then it is assumed that the source file is specified
4224 // in the actual argument list.
4225 // Put the source file after command_line_args otherwise if '-x' flag is
4226 // present it will be unused.
4227 if (source_filename)
4228 Args->push_back(source_filename);
4230 // Do we need the detailed preprocessing record?
4231 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
4232 Args->push_back("-Xclang");
4233 Args->push_back("-detailed-preprocessing-record");
4236 // Suppress any editor placeholder diagnostics.
4237 Args->push_back("-fallow-editor-placeholders");
4239 unsigned NumErrors = Diags->getClient()->getNumErrors();
4240 std::unique_ptr<ASTUnit> ErrUnit;
4241 // Unless the user specified that they want the preamble on the first parse
4242 // set it up to be created on the first reparse. This makes the first parse
4243 // faster, trading for a slower (first) reparse.
4244 unsigned PrecompilePreambleAfterNParses =
4245 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
4247 LibclangInvocationReporter InvocationReporter(
4248 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
4249 options, llvm::ArrayRef(*Args), /*InvocationArgs=*/{}, unsaved_files);
4250 std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromCommandLine(
4251 Args->data(), Args->data() + Args->size(),
4252 CXXIdx->getPCHContainerOperations(), Diags,
4253 CXXIdx->getClangResourcesPath(), CXXIdx->getStorePreamblesInMemory(),
4254 CXXIdx->getPreambleStoragePath(), CXXIdx->getOnlyLocalDecls(),
4255 CaptureDiagnostics, *RemappedFiles.get(),
4256 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
4257 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
4258 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
4259 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
4260 CXXIdx->getPCHContainerOperations()->getRawReader().getFormats().front(),
4261 &ErrUnit);
4263 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
4264 if (!Unit && !ErrUnit)
4265 return CXError_ASTReadError;
4267 if (NumErrors != Diags->getClient()->getNumErrors()) {
4268 // Make sure to check that 'Unit' is non-NULL.
4269 if (CXXIdx->getDisplayDiagnostics())
4270 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
4273 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
4274 return CXError_ASTReadError;
4276 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
4277 if (CXTranslationUnitImpl *TU = *out_TU) {
4278 TU->ParsingOptions = options;
4279 TU->Arguments.reserve(Args->size());
4280 for (const char *Arg : *Args)
4281 TU->Arguments.push_back(Arg);
4282 return CXError_Success;
4284 return CXError_Failure;
4287 CXTranslationUnit
4288 clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
4289 const char *const *command_line_args,
4290 int num_command_line_args,
4291 struct CXUnsavedFile *unsaved_files,
4292 unsigned num_unsaved_files, unsigned options) {
4293 CXTranslationUnit TU;
4294 enum CXErrorCode Result = clang_parseTranslationUnit2(
4295 CIdx, source_filename, command_line_args, num_command_line_args,
4296 unsaved_files, num_unsaved_files, options, &TU);
4297 (void)Result;
4298 assert((TU && Result == CXError_Success) ||
4299 (!TU && Result != CXError_Success));
4300 return TU;
4303 enum CXErrorCode clang_parseTranslationUnit2(
4304 CXIndex CIdx, const char *source_filename,
4305 const char *const *command_line_args, int num_command_line_args,
4306 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
4307 unsigned options, CXTranslationUnit *out_TU) {
4308 noteBottomOfStack();
4309 SmallVector<const char *, 4> Args;
4310 Args.push_back("clang");
4311 Args.append(command_line_args, command_line_args + num_command_line_args);
4312 return clang_parseTranslationUnit2FullArgv(
4313 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
4314 num_unsaved_files, options, out_TU);
4317 enum CXErrorCode clang_parseTranslationUnit2FullArgv(
4318 CXIndex CIdx, const char *source_filename,
4319 const char *const *command_line_args, int num_command_line_args,
4320 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
4321 unsigned options, CXTranslationUnit *out_TU) {
4322 LOG_FUNC_SECTION {
4323 *Log << source_filename << ": ";
4324 for (int i = 0; i != num_command_line_args; ++i)
4325 *Log << command_line_args[i] << " ";
4328 if (num_unsaved_files && !unsaved_files)
4329 return CXError_InvalidArguments;
4331 CXErrorCode result = CXError_Failure;
4332 auto ParseTranslationUnitImpl = [=, &result] {
4333 noteBottomOfStack();
4334 result = clang_parseTranslationUnit_Impl(
4335 CIdx, source_filename, command_line_args, num_command_line_args,
4336 llvm::ArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
4339 llvm::CrashRecoveryContext CRC;
4341 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
4342 fprintf(stderr, "libclang: crash detected during parsing: {\n");
4343 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
4344 fprintf(stderr, " 'command_line_args' : [");
4345 for (int i = 0; i != num_command_line_args; ++i) {
4346 if (i)
4347 fprintf(stderr, ", ");
4348 fprintf(stderr, "'%s'", command_line_args[i]);
4350 fprintf(stderr, "],\n");
4351 fprintf(stderr, " 'unsaved_files' : [");
4352 for (unsigned i = 0; i != num_unsaved_files; ++i) {
4353 if (i)
4354 fprintf(stderr, ", ");
4355 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
4356 unsaved_files[i].Length);
4358 fprintf(stderr, "],\n");
4359 fprintf(stderr, " 'options' : %d,\n", options);
4360 fprintf(stderr, "}\n");
4362 return CXError_Crashed;
4363 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4364 if (CXTranslationUnit *TU = out_TU)
4365 PrintLibclangResourceUsage(*TU);
4368 return result;
4371 CXString clang_Type_getObjCEncoding(CXType CT) {
4372 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
4373 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
4374 std::string encoding;
4375 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
4377 return cxstring::createDup(encoding);
4380 static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
4381 if (C.kind == CXCursor_MacroDefinition) {
4382 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
4383 return MDR->getName();
4384 } else if (C.kind == CXCursor_MacroExpansion) {
4385 MacroExpansionCursor ME = getCursorMacroExpansion(C);
4386 return ME.getName();
4388 return nullptr;
4391 unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
4392 const IdentifierInfo *II = getMacroIdentifier(C);
4393 if (!II) {
4394 return false;
4396 ASTUnit *ASTU = getCursorASTUnit(C);
4397 Preprocessor &PP = ASTU->getPreprocessor();
4398 if (const MacroInfo *MI = PP.getMacroInfo(II))
4399 return MI->isFunctionLike();
4400 return false;
4403 unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
4404 const IdentifierInfo *II = getMacroIdentifier(C);
4405 if (!II) {
4406 return false;
4408 ASTUnit *ASTU = getCursorASTUnit(C);
4409 Preprocessor &PP = ASTU->getPreprocessor();
4410 if (const MacroInfo *MI = PP.getMacroInfo(II))
4411 return MI->isBuiltinMacro();
4412 return false;
4415 unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
4416 const Decl *D = getCursorDecl(C);
4417 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
4418 if (!FD) {
4419 return false;
4421 return FD->isInlined();
4424 static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
4425 if (callExpr->getNumArgs() != 1) {
4426 return nullptr;
4429 StringLiteral *S = nullptr;
4430 auto *arg = callExpr->getArg(0);
4431 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
4432 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
4433 auto *subExpr = I->getSubExprAsWritten();
4435 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
4436 return nullptr;
4439 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
4440 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
4441 S = static_cast<StringLiteral *>(callExpr->getArg(0));
4442 } else {
4443 return nullptr;
4445 return S;
4448 struct ExprEvalResult {
4449 CXEvalResultKind EvalType;
4450 union {
4451 unsigned long long unsignedVal;
4452 long long intVal;
4453 double floatVal;
4454 char *stringVal;
4455 } EvalData;
4456 bool IsUnsignedInt;
4457 ~ExprEvalResult() {
4458 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
4459 EvalType != CXEval_Int) {
4460 delete[] EvalData.stringVal;
4465 void clang_EvalResult_dispose(CXEvalResult E) {
4466 delete static_cast<ExprEvalResult *>(E);
4469 CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
4470 if (!E) {
4471 return CXEval_UnExposed;
4473 return ((ExprEvalResult *)E)->EvalType;
4476 int clang_EvalResult_getAsInt(CXEvalResult E) {
4477 return clang_EvalResult_getAsLongLong(E);
4480 long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
4481 if (!E) {
4482 return 0;
4484 ExprEvalResult *Result = (ExprEvalResult *)E;
4485 if (Result->IsUnsignedInt)
4486 return Result->EvalData.unsignedVal;
4487 return Result->EvalData.intVal;
4490 unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
4491 return ((ExprEvalResult *)E)->IsUnsignedInt;
4494 unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
4495 if (!E) {
4496 return 0;
4499 ExprEvalResult *Result = (ExprEvalResult *)E;
4500 if (Result->IsUnsignedInt)
4501 return Result->EvalData.unsignedVal;
4502 return Result->EvalData.intVal;
4505 double clang_EvalResult_getAsDouble(CXEvalResult E) {
4506 if (!E) {
4507 return 0;
4509 return ((ExprEvalResult *)E)->EvalData.floatVal;
4512 const char *clang_EvalResult_getAsStr(CXEvalResult E) {
4513 if (!E) {
4514 return nullptr;
4516 return ((ExprEvalResult *)E)->EvalData.stringVal;
4519 static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
4520 Expr::EvalResult ER;
4521 ASTContext &ctx = getCursorContext(C);
4522 if (!expr)
4523 return nullptr;
4525 expr = expr->IgnoreParens();
4526 if (expr->isValueDependent())
4527 return nullptr;
4528 if (!expr->EvaluateAsRValue(ER, ctx))
4529 return nullptr;
4531 QualType rettype;
4532 CallExpr *callExpr;
4533 auto result = std::make_unique<ExprEvalResult>();
4534 result->EvalType = CXEval_UnExposed;
4535 result->IsUnsignedInt = false;
4537 if (ER.Val.isInt()) {
4538 result->EvalType = CXEval_Int;
4540 auto &val = ER.Val.getInt();
4541 if (val.isUnsigned()) {
4542 result->IsUnsignedInt = true;
4543 result->EvalData.unsignedVal = val.getZExtValue();
4544 } else {
4545 result->EvalData.intVal = val.getExtValue();
4548 return result.release();
4551 if (ER.Val.isFloat()) {
4552 llvm::SmallVector<char, 100> Buffer;
4553 ER.Val.getFloat().toString(Buffer);
4554 std::string floatStr(Buffer.data(), Buffer.size());
4555 result->EvalType = CXEval_Float;
4556 bool ignored;
4557 llvm::APFloat apFloat = ER.Val.getFloat();
4558 apFloat.convert(llvm::APFloat::IEEEdouble(),
4559 llvm::APFloat::rmNearestTiesToEven, &ignored);
4560 result->EvalData.floatVal = apFloat.convertToDouble();
4561 return result.release();
4564 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
4565 const auto *I = cast<ImplicitCastExpr>(expr);
4566 auto *subExpr = I->getSubExprAsWritten();
4567 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
4568 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
4569 const StringLiteral *StrE = nullptr;
4570 const ObjCStringLiteral *ObjCExpr;
4571 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
4573 if (ObjCExpr) {
4574 StrE = ObjCExpr->getString();
4575 result->EvalType = CXEval_ObjCStrLiteral;
4576 } else {
4577 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
4578 result->EvalType = CXEval_StrLiteral;
4581 std::string strRef(StrE->getString().str());
4582 result->EvalData.stringVal = new char[strRef.size() + 1];
4583 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
4584 strRef.size());
4585 result->EvalData.stringVal[strRef.size()] = '\0';
4586 return result.release();
4588 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
4589 expr->getStmtClass() == Stmt::StringLiteralClass) {
4590 const StringLiteral *StrE = nullptr;
4591 const ObjCStringLiteral *ObjCExpr;
4592 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
4594 if (ObjCExpr) {
4595 StrE = ObjCExpr->getString();
4596 result->EvalType = CXEval_ObjCStrLiteral;
4597 } else {
4598 StrE = cast<StringLiteral>(expr);
4599 result->EvalType = CXEval_StrLiteral;
4602 std::string strRef(StrE->getString().str());
4603 result->EvalData.stringVal = new char[strRef.size() + 1];
4604 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
4605 result->EvalData.stringVal[strRef.size()] = '\0';
4606 return result.release();
4609 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
4610 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
4612 rettype = CC->getType();
4613 if (rettype.getAsString() == "CFStringRef" &&
4614 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
4616 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
4617 StringLiteral *S = getCFSTR_value(callExpr);
4618 if (S) {
4619 std::string strLiteral(S->getString().str());
4620 result->EvalType = CXEval_CFStr;
4622 result->EvalData.stringVal = new char[strLiteral.size() + 1];
4623 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
4624 strLiteral.size());
4625 result->EvalData.stringVal[strLiteral.size()] = '\0';
4626 return result.release();
4630 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
4631 callExpr = static_cast<CallExpr *>(expr);
4632 rettype = callExpr->getCallReturnType(ctx);
4634 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
4635 return nullptr;
4637 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
4638 if (callExpr->getNumArgs() == 1 &&
4639 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
4640 return nullptr;
4641 } else if (rettype.getAsString() == "CFStringRef") {
4643 StringLiteral *S = getCFSTR_value(callExpr);
4644 if (S) {
4645 std::string strLiteral(S->getString().str());
4646 result->EvalType = CXEval_CFStr;
4647 result->EvalData.stringVal = new char[strLiteral.size() + 1];
4648 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
4649 strLiteral.size());
4650 result->EvalData.stringVal[strLiteral.size()] = '\0';
4651 return result.release();
4654 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
4655 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
4656 ValueDecl *V = D->getDecl();
4657 if (V->getKind() == Decl::Function) {
4658 std::string strName = V->getNameAsString();
4659 result->EvalType = CXEval_Other;
4660 result->EvalData.stringVal = new char[strName.size() + 1];
4661 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
4662 result->EvalData.stringVal[strName.size()] = '\0';
4663 return result.release();
4667 return nullptr;
4670 static const Expr *evaluateDeclExpr(const Decl *D) {
4671 if (!D)
4672 return nullptr;
4673 if (auto *Var = dyn_cast<VarDecl>(D))
4674 return Var->getInit();
4675 else if (auto *Field = dyn_cast<FieldDecl>(D))
4676 return Field->getInClassInitializer();
4677 return nullptr;
4680 static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4681 assert(CS && "invalid compound statement");
4682 for (auto *bodyIterator : CS->body()) {
4683 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4684 return E;
4686 return nullptr;
4689 CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
4690 const Expr *E = nullptr;
4691 if (clang_getCursorKind(C) == CXCursor_CompoundStmt)
4692 E = evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)));
4693 else if (clang_isDeclaration(C.kind))
4694 E = evaluateDeclExpr(getCursorDecl(C));
4695 else if (clang_isExpression(C.kind))
4696 E = getCursorExpr(C);
4697 if (E)
4698 return const_cast<CXEvalResult>(
4699 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4700 return nullptr;
4703 unsigned clang_Cursor_hasAttrs(CXCursor C) {
4704 const Decl *D = getCursorDecl(C);
4705 if (!D) {
4706 return 0;
4709 if (D->hasAttrs()) {
4710 return 1;
4713 return 0;
4715 unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4716 return CXSaveTranslationUnit_None;
4719 static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4720 const char *FileName,
4721 unsigned options) {
4722 CIndexer *CXXIdx = TU->CIdx;
4723 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4724 setThreadBackgroundPriority();
4726 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4727 return hadError ? CXSaveError_Unknown : CXSaveError_None;
4730 int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4731 unsigned options) {
4732 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
4734 if (isNotUsableTU(TU)) {
4735 LOG_BAD_TU(TU);
4736 return CXSaveError_InvalidTU;
4739 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4740 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4741 if (!CXXUnit->hasSema())
4742 return CXSaveError_InvalidTU;
4744 CXSaveError result;
4745 auto SaveTranslationUnitImpl = [=, &result]() {
4746 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4749 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
4750 SaveTranslationUnitImpl();
4752 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4753 PrintLibclangResourceUsage(TU);
4755 return result;
4758 // We have an AST that has invalid nodes due to compiler errors.
4759 // Use a crash recovery thread for protection.
4761 llvm::CrashRecoveryContext CRC;
4763 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
4764 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4765 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4766 fprintf(stderr, " 'options' : %d,\n", options);
4767 fprintf(stderr, "}\n");
4769 return CXSaveError_Unknown;
4771 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4772 PrintLibclangResourceUsage(TU);
4775 return result;
4778 void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4779 if (CTUnit) {
4780 // If the translation unit has been marked as unsafe to free, just discard
4781 // it.
4782 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4783 if (Unit && Unit->isUnsafeToFree())
4784 return;
4786 delete cxtu::getASTUnit(CTUnit);
4787 delete CTUnit->StringPool;
4788 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4789 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
4790 delete CTUnit->CommentToXML;
4791 delete CTUnit;
4795 unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4796 if (CTUnit) {
4797 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4799 if (Unit && Unit->isUnsafeToFree())
4800 return false;
4802 Unit->ResetForParse();
4803 return true;
4806 return false;
4809 unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4810 return CXReparse_None;
4813 static CXErrorCode
4814 clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4815 ArrayRef<CXUnsavedFile> unsaved_files,
4816 unsigned options) {
4817 // Check arguments.
4818 if (isNotUsableTU(TU)) {
4819 LOG_BAD_TU(TU);
4820 return CXError_InvalidArguments;
4823 // Reset the associated diagnostics.
4824 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
4825 TU->Diagnostics = nullptr;
4827 CIndexer *CXXIdx = TU->CIdx;
4828 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4829 setThreadBackgroundPriority();
4831 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4832 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4834 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4835 new std::vector<ASTUnit::RemappedFile>());
4837 // Recover resources if we crash before exiting this function.
4838 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4839 RemappedCleanup(RemappedFiles.get());
4841 for (auto &UF : unsaved_files) {
4842 std::unique_ptr<llvm::MemoryBuffer> MB =
4843 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
4844 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
4847 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4848 *RemappedFiles.get()))
4849 return CXError_Success;
4850 if (isASTReadError(CXXUnit))
4851 return CXError_ASTReadError;
4852 return CXError_Failure;
4855 int clang_reparseTranslationUnit(CXTranslationUnit TU,
4856 unsigned num_unsaved_files,
4857 struct CXUnsavedFile *unsaved_files,
4858 unsigned options) {
4859 LOG_FUNC_SECTION { *Log << TU; }
4861 if (num_unsaved_files && !unsaved_files)
4862 return CXError_InvalidArguments;
4864 CXErrorCode result;
4865 auto ReparseTranslationUnitImpl = [=, &result]() {
4866 result = clang_reparseTranslationUnit_Impl(
4867 TU, llvm::ArrayRef(unsaved_files, num_unsaved_files), options);
4870 llvm::CrashRecoveryContext CRC;
4872 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
4873 fprintf(stderr, "libclang: crash detected during reparsing\n");
4874 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
4875 return CXError_Crashed;
4876 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4877 PrintLibclangResourceUsage(TU);
4879 return result;
4882 CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
4883 if (isNotUsableTU(CTUnit)) {
4884 LOG_BAD_TU(CTUnit);
4885 return cxstring::createEmpty();
4888 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4889 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
4892 CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
4893 if (isNotUsableTU(TU)) {
4894 LOG_BAD_TU(TU);
4895 return clang_getNullCursor();
4898 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4899 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4902 CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4903 if (isNotUsableTU(CTUnit)) {
4904 LOG_BAD_TU(CTUnit);
4905 return nullptr;
4908 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
4909 impl->TranslationUnit = CTUnit;
4910 return impl;
4913 CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4914 if (!TargetInfo)
4915 return cxstring::createEmpty();
4917 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4918 assert(!isNotUsableTU(CTUnit) &&
4919 "Unexpected unusable translation unit in TargetInfo");
4921 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4922 std::string Triple =
4923 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
4924 return cxstring::createDup(Triple);
4927 int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4928 if (!TargetInfo)
4929 return -1;
4931 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4932 assert(!isNotUsableTU(CTUnit) &&
4933 "Unexpected unusable translation unit in TargetInfo");
4935 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4936 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4939 void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4940 if (!TargetInfo)
4941 return;
4943 delete TargetInfo;
4946 //===----------------------------------------------------------------------===//
4947 // CXFile Operations.
4948 //===----------------------------------------------------------------------===//
4950 CXString clang_getFileName(CXFile SFile) {
4951 if (!SFile)
4952 return cxstring::createNull();
4954 FileEntryRef FEnt = *cxfile::getFileEntryRef(SFile);
4955 return cxstring::createRef(FEnt.getName());
4958 time_t clang_getFileTime(CXFile SFile) {
4959 if (!SFile)
4960 return 0;
4962 FileEntryRef FEnt = *cxfile::getFileEntryRef(SFile);
4963 return FEnt.getModificationTime();
4966 CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
4967 if (isNotUsableTU(TU)) {
4968 LOG_BAD_TU(TU);
4969 return nullptr;
4972 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4974 FileManager &FMgr = CXXUnit->getFileManager();
4975 return cxfile::makeCXFile(FMgr.getOptionalFileRef(file_name));
4978 const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4979 size_t *size) {
4980 if (isNotUsableTU(TU)) {
4981 LOG_BAD_TU(TU);
4982 return nullptr;
4985 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4986 FileID fid = SM.translateFile(*cxfile::getFileEntryRef(file));
4987 std::optional<llvm::MemoryBufferRef> buf = SM.getBufferOrNone(fid);
4988 if (!buf) {
4989 if (size)
4990 *size = 0;
4991 return nullptr;
4993 if (size)
4994 *size = buf->getBufferSize();
4995 return buf->getBufferStart();
4998 unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
4999 if (isNotUsableTU(TU)) {
5000 LOG_BAD_TU(TU);
5001 return 0;
5004 if (!file)
5005 return 0;
5007 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
5008 FileEntryRef FEnt = *cxfile::getFileEntryRef(file);
5009 return CXXUnit->getPreprocessor()
5010 .getHeaderSearchInfo()
5011 .isFileMultipleIncludeGuarded(FEnt);
5014 int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
5015 if (!file || !outID)
5016 return 1;
5018 FileEntryRef FEnt = *cxfile::getFileEntryRef(file);
5019 const llvm::sys::fs::UniqueID &ID = FEnt.getUniqueID();
5020 outID->data[0] = ID.getDevice();
5021 outID->data[1] = ID.getFile();
5022 outID->data[2] = FEnt.getModificationTime();
5023 return 0;
5026 int clang_File_isEqual(CXFile file1, CXFile file2) {
5027 if (file1 == file2)
5028 return true;
5030 if (!file1 || !file2)
5031 return false;
5033 FileEntryRef FEnt1 = *cxfile::getFileEntryRef(file1);
5034 FileEntryRef FEnt2 = *cxfile::getFileEntryRef(file2);
5035 return FEnt1.getUniqueID() == FEnt2.getUniqueID();
5038 CXString clang_File_tryGetRealPathName(CXFile SFile) {
5039 if (!SFile)
5040 return cxstring::createNull();
5042 FileEntryRef FEnt = *cxfile::getFileEntryRef(SFile);
5043 return cxstring::createRef(FEnt.getFileEntry().tryGetRealPathName());
5046 //===----------------------------------------------------------------------===//
5047 // CXCursor Operations.
5048 //===----------------------------------------------------------------------===//
5050 static const Decl *getDeclFromExpr(const Stmt *E) {
5051 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
5052 return getDeclFromExpr(CE->getSubExpr());
5054 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
5055 return RefExpr->getDecl();
5056 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
5057 return ME->getMemberDecl();
5058 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
5059 return RE->getDecl();
5060 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
5061 if (PRE->isExplicitProperty())
5062 return PRE->getExplicitProperty();
5063 // It could be messaging both getter and setter as in:
5064 // ++myobj.myprop;
5065 // in which case prefer to associate the setter since it is less obvious
5066 // from inspecting the source that the setter is going to get called.
5067 if (PRE->isMessagingSetter())
5068 return PRE->getImplicitPropertySetter();
5069 return PRE->getImplicitPropertyGetter();
5071 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
5072 return getDeclFromExpr(POE->getSyntacticForm());
5073 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
5074 if (Expr *Src = OVE->getSourceExpr())
5075 return getDeclFromExpr(Src);
5077 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
5078 return getDeclFromExpr(CE->getCallee());
5079 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
5080 if (!CE->isElidable())
5081 return CE->getConstructor();
5082 if (const CXXInheritedCtorInitExpr *CE =
5083 dyn_cast<CXXInheritedCtorInitExpr>(E))
5084 return CE->getConstructor();
5085 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
5086 return OME->getMethodDecl();
5088 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
5089 return PE->getProtocol();
5090 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
5091 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
5092 return NTTP->getParameterPack();
5093 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
5094 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
5095 isa<ParmVarDecl>(SizeOfPack->getPack()))
5096 return SizeOfPack->getPack();
5098 return nullptr;
5101 static SourceLocation getLocationFromExpr(const Expr *E) {
5102 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
5103 return getLocationFromExpr(CE->getSubExpr());
5105 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
5106 return /*FIXME:*/ Msg->getLeftLoc();
5107 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
5108 return DRE->getLocation();
5109 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
5110 return Member->getMemberLoc();
5111 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
5112 return Ivar->getLocation();
5113 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
5114 return SizeOfPack->getPackLoc();
5115 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
5116 return PropRef->getLocation();
5118 return E->getBeginLoc();
5121 extern "C" {
5123 unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
5124 CXClientData client_data) {
5125 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
5126 /*VisitPreprocessorLast=*/false);
5127 return CursorVis.VisitChildren(parent);
5130 #ifndef __has_feature
5131 #define __has_feature(x) 0
5132 #endif
5133 #if __has_feature(blocks)
5134 typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
5135 CXCursor parent);
5137 static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
5138 CXClientData client_data) {
5139 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
5140 return block(cursor, parent);
5142 #else
5143 // If we are compiled with a compiler that doesn't have native blocks support,
5144 // define and call the block manually, so the
5145 typedef struct _CXChildVisitResult {
5146 void *isa;
5147 int flags;
5148 int reserved;
5149 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
5150 CXCursor);
5151 } * CXCursorVisitorBlock;
5153 static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
5154 CXClientData client_data) {
5155 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
5156 return block->invoke(block, cursor, parent);
5158 #endif
5160 unsigned clang_visitChildrenWithBlock(CXCursor parent,
5161 CXCursorVisitorBlock block) {
5162 return clang_visitChildren(parent, visitWithBlock, block);
5165 static CXString getDeclSpelling(const Decl *D) {
5166 if (!D)
5167 return cxstring::createEmpty();
5169 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
5170 if (!ND) {
5171 if (const ObjCPropertyImplDecl *PropImpl =
5172 dyn_cast<ObjCPropertyImplDecl>(D))
5173 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
5174 return cxstring::createDup(Property->getIdentifier()->getName());
5176 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
5177 if (Module *Mod = ImportD->getImportedModule())
5178 return cxstring::createDup(Mod->getFullModuleName());
5180 return cxstring::createEmpty();
5183 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
5184 return cxstring::createDup(OMD->getSelector().getAsString());
5186 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
5187 // No, this isn't the same as the code below. getIdentifier() is non-virtual
5188 // and returns different names. NamedDecl returns the class name and
5189 // ObjCCategoryImplDecl returns the category name.
5190 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
5192 if (isa<UsingDirectiveDecl>(D))
5193 return cxstring::createEmpty();
5195 SmallString<1024> S;
5196 llvm::raw_svector_ostream os(S);
5197 ND->printName(os);
5199 return cxstring::createDup(os.str());
5202 CXString clang_getCursorSpelling(CXCursor C) {
5203 if (clang_isTranslationUnit(C.kind))
5204 return clang_getTranslationUnitSpelling(getCursorTU(C));
5206 if (clang_isReference(C.kind)) {
5207 switch (C.kind) {
5208 case CXCursor_ObjCSuperClassRef: {
5209 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
5210 return cxstring::createRef(Super->getIdentifier()->getNameStart());
5212 case CXCursor_ObjCClassRef: {
5213 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5214 return cxstring::createRef(Class->getIdentifier()->getNameStart());
5216 case CXCursor_ObjCProtocolRef: {
5217 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
5218 assert(OID && "getCursorSpelling(): Missing protocol decl");
5219 return cxstring::createRef(OID->getIdentifier()->getNameStart());
5221 case CXCursor_CXXBaseSpecifier: {
5222 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
5223 return cxstring::createDup(B->getType().getAsString());
5225 case CXCursor_TypeRef: {
5226 const TypeDecl *Type = getCursorTypeRef(C).first;
5227 assert(Type && "Missing type decl");
5229 return cxstring::createDup(
5230 getCursorContext(C).getTypeDeclType(Type).getAsString());
5232 case CXCursor_TemplateRef: {
5233 const TemplateDecl *Template = getCursorTemplateRef(C).first;
5234 assert(Template && "Missing template decl");
5236 return cxstring::createDup(Template->getNameAsString());
5239 case CXCursor_NamespaceRef: {
5240 const NamedDecl *NS = getCursorNamespaceRef(C).first;
5241 assert(NS && "Missing namespace decl");
5243 return cxstring::createDup(NS->getNameAsString());
5246 case CXCursor_MemberRef: {
5247 const FieldDecl *Field = getCursorMemberRef(C).first;
5248 assert(Field && "Missing member decl");
5250 return cxstring::createDup(Field->getNameAsString());
5253 case CXCursor_LabelRef: {
5254 const LabelStmt *Label = getCursorLabelRef(C).first;
5255 assert(Label && "Missing label");
5257 return cxstring::createRef(Label->getName());
5260 case CXCursor_OverloadedDeclRef: {
5261 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
5262 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
5263 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
5264 return cxstring::createDup(ND->getNameAsString());
5265 return cxstring::createEmpty();
5267 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
5268 return cxstring::createDup(E->getName().getAsString());
5269 OverloadedTemplateStorage *Ovl =
5270 Storage.get<OverloadedTemplateStorage *>();
5271 if (Ovl->size() == 0)
5272 return cxstring::createEmpty();
5273 return cxstring::createDup((*Ovl->begin())->getNameAsString());
5276 case CXCursor_VariableRef: {
5277 const VarDecl *Var = getCursorVariableRef(C).first;
5278 assert(Var && "Missing variable decl");
5280 return cxstring::createDup(Var->getNameAsString());
5283 default:
5284 return cxstring::createRef("<not implemented>");
5288 if (clang_isExpression(C.kind)) {
5289 const Expr *E = getCursorExpr(C);
5291 if (C.kind == CXCursor_ObjCStringLiteral ||
5292 C.kind == CXCursor_StringLiteral) {
5293 const StringLiteral *SLit;
5294 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
5295 SLit = OSL->getString();
5296 } else {
5297 SLit = cast<StringLiteral>(E);
5299 SmallString<256> Buf;
5300 llvm::raw_svector_ostream OS(Buf);
5301 SLit->outputString(OS);
5302 return cxstring::createDup(OS.str());
5305 if (C.kind == CXCursor_BinaryOperator ||
5306 C.kind == CXCursor_CompoundAssignOperator) {
5307 return clang_Cursor_getBinaryOpcodeStr(clang_Cursor_getBinaryOpcode(C));
5310 const Decl *D = getDeclFromExpr(getCursorExpr(C));
5311 if (D)
5312 return getDeclSpelling(D);
5313 return cxstring::createEmpty();
5316 if (clang_isStatement(C.kind)) {
5317 const Stmt *S = getCursorStmt(C);
5318 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
5319 return cxstring::createRef(Label->getName());
5321 return cxstring::createEmpty();
5324 if (C.kind == CXCursor_MacroExpansion)
5325 return cxstring::createRef(
5326 getCursorMacroExpansion(C).getName()->getNameStart());
5328 if (C.kind == CXCursor_MacroDefinition)
5329 return cxstring::createRef(
5330 getCursorMacroDefinition(C)->getName()->getNameStart());
5332 if (C.kind == CXCursor_InclusionDirective)
5333 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
5335 if (clang_isDeclaration(C.kind))
5336 return getDeclSpelling(getCursorDecl(C));
5338 if (C.kind == CXCursor_AnnotateAttr) {
5339 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
5340 return cxstring::createDup(AA->getAnnotation());
5343 if (C.kind == CXCursor_AsmLabelAttr) {
5344 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
5345 return cxstring::createDup(AA->getLabel());
5348 if (C.kind == CXCursor_PackedAttr) {
5349 return cxstring::createRef("packed");
5352 if (C.kind == CXCursor_VisibilityAttr) {
5353 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
5354 switch (AA->getVisibility()) {
5355 case VisibilityAttr::VisibilityType::Default:
5356 return cxstring::createRef("default");
5357 case VisibilityAttr::VisibilityType::Hidden:
5358 return cxstring::createRef("hidden");
5359 case VisibilityAttr::VisibilityType::Protected:
5360 return cxstring::createRef("protected");
5362 llvm_unreachable("unknown visibility type");
5365 return cxstring::createEmpty();
5368 CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
5369 unsigned options) {
5370 if (clang_Cursor_isNull(C))
5371 return clang_getNullRange();
5373 ASTContext &Ctx = getCursorContext(C);
5375 if (clang_isStatement(C.kind)) {
5376 const Stmt *S = getCursorStmt(C);
5377 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
5378 if (pieceIndex > 0)
5379 return clang_getNullRange();
5380 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
5383 return clang_getNullRange();
5386 if (C.kind == CXCursor_ObjCMessageExpr) {
5387 if (const ObjCMessageExpr *ME =
5388 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
5389 if (pieceIndex >= ME->getNumSelectorLocs())
5390 return clang_getNullRange();
5391 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
5395 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
5396 C.kind == CXCursor_ObjCClassMethodDecl) {
5397 if (const ObjCMethodDecl *MD =
5398 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
5399 if (pieceIndex >= MD->getNumSelectorLocs())
5400 return clang_getNullRange();
5401 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
5405 if (C.kind == CXCursor_ObjCCategoryDecl ||
5406 C.kind == CXCursor_ObjCCategoryImplDecl) {
5407 if (pieceIndex > 0)
5408 return clang_getNullRange();
5409 if (const ObjCCategoryDecl *CD =
5410 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
5411 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
5412 if (const ObjCCategoryImplDecl *CID =
5413 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
5414 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
5417 if (C.kind == CXCursor_ModuleImportDecl) {
5418 if (pieceIndex > 0)
5419 return clang_getNullRange();
5420 if (const ImportDecl *ImportD =
5421 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
5422 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
5423 if (!Locs.empty())
5424 return cxloc::translateSourceRange(
5425 Ctx, SourceRange(Locs.front(), Locs.back()));
5427 return clang_getNullRange();
5430 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
5431 C.kind == CXCursor_ConversionFunction ||
5432 C.kind == CXCursor_FunctionDecl) {
5433 if (pieceIndex > 0)
5434 return clang_getNullRange();
5435 if (const FunctionDecl *FD =
5436 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
5437 DeclarationNameInfo FunctionName = FD->getNameInfo();
5438 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
5440 return clang_getNullRange();
5443 // FIXME: A CXCursor_InclusionDirective should give the location of the
5444 // filename, but we don't keep track of this.
5446 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
5447 // but we don't keep track of this.
5449 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
5450 // but we don't keep track of this.
5452 // Default handling, give the location of the cursor.
5454 if (pieceIndex > 0)
5455 return clang_getNullRange();
5457 CXSourceLocation CXLoc = clang_getCursorLocation(C);
5458 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
5459 return cxloc::translateSourceRange(Ctx, Loc);
5462 CXString clang_Cursor_getMangling(CXCursor C) {
5463 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
5464 return cxstring::createEmpty();
5466 // Mangling only works for functions and variables.
5467 const Decl *D = getCursorDecl(C);
5468 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
5469 return cxstring::createEmpty();
5471 ASTContext &Ctx = D->getASTContext();
5472 ASTNameGenerator ASTNameGen(Ctx);
5473 return cxstring::createDup(ASTNameGen.getName(D));
5476 CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
5477 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
5478 return nullptr;
5480 const Decl *D = getCursorDecl(C);
5481 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
5482 return nullptr;
5484 ASTContext &Ctx = D->getASTContext();
5485 ASTNameGenerator ASTNameGen(Ctx);
5486 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
5487 return cxstring::createSet(Manglings);
5490 CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
5491 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
5492 return nullptr;
5494 const Decl *D = getCursorDecl(C);
5495 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
5496 return nullptr;
5498 ASTContext &Ctx = D->getASTContext();
5499 ASTNameGenerator ASTNameGen(Ctx);
5500 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
5501 return cxstring::createSet(Manglings);
5504 CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
5505 if (clang_Cursor_isNull(C))
5506 return nullptr;
5507 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
5510 void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
5511 if (Policy)
5512 delete static_cast<PrintingPolicy *>(Policy);
5515 unsigned
5516 clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
5517 enum CXPrintingPolicyProperty Property) {
5518 if (!Policy)
5519 return 0;
5521 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
5522 switch (Property) {
5523 case CXPrintingPolicy_Indentation:
5524 return P->Indentation;
5525 case CXPrintingPolicy_SuppressSpecifiers:
5526 return P->SuppressSpecifiers;
5527 case CXPrintingPolicy_SuppressTagKeyword:
5528 return P->SuppressTagKeyword;
5529 case CXPrintingPolicy_IncludeTagDefinition:
5530 return P->IncludeTagDefinition;
5531 case CXPrintingPolicy_SuppressScope:
5532 return P->SuppressScope;
5533 case CXPrintingPolicy_SuppressUnwrittenScope:
5534 return P->SuppressUnwrittenScope;
5535 case CXPrintingPolicy_SuppressInitializers:
5536 return P->SuppressInitializers;
5537 case CXPrintingPolicy_ConstantArraySizeAsWritten:
5538 return P->ConstantArraySizeAsWritten;
5539 case CXPrintingPolicy_AnonymousTagLocations:
5540 return P->AnonymousTagLocations;
5541 case CXPrintingPolicy_SuppressStrongLifetime:
5542 return P->SuppressStrongLifetime;
5543 case CXPrintingPolicy_SuppressLifetimeQualifiers:
5544 return P->SuppressLifetimeQualifiers;
5545 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
5546 return P->SuppressTemplateArgsInCXXConstructors;
5547 case CXPrintingPolicy_Bool:
5548 return P->Bool;
5549 case CXPrintingPolicy_Restrict:
5550 return P->Restrict;
5551 case CXPrintingPolicy_Alignof:
5552 return P->Alignof;
5553 case CXPrintingPolicy_UnderscoreAlignof:
5554 return P->UnderscoreAlignof;
5555 case CXPrintingPolicy_UseVoidForZeroParams:
5556 return P->UseVoidForZeroParams;
5557 case CXPrintingPolicy_TerseOutput:
5558 return P->TerseOutput;
5559 case CXPrintingPolicy_PolishForDeclaration:
5560 return P->PolishForDeclaration;
5561 case CXPrintingPolicy_Half:
5562 return P->Half;
5563 case CXPrintingPolicy_MSWChar:
5564 return P->MSWChar;
5565 case CXPrintingPolicy_IncludeNewlines:
5566 return P->IncludeNewlines;
5567 case CXPrintingPolicy_MSVCFormatting:
5568 return P->MSVCFormatting;
5569 case CXPrintingPolicy_ConstantsAsWritten:
5570 return P->ConstantsAsWritten;
5571 case CXPrintingPolicy_SuppressImplicitBase:
5572 return P->SuppressImplicitBase;
5573 case CXPrintingPolicy_FullyQualifiedName:
5574 return P->FullyQualifiedName;
5577 assert(false && "Invalid CXPrintingPolicyProperty");
5578 return 0;
5581 void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
5582 enum CXPrintingPolicyProperty Property,
5583 unsigned Value) {
5584 if (!Policy)
5585 return;
5587 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
5588 switch (Property) {
5589 case CXPrintingPolicy_Indentation:
5590 P->Indentation = Value;
5591 return;
5592 case CXPrintingPolicy_SuppressSpecifiers:
5593 P->SuppressSpecifiers = Value;
5594 return;
5595 case CXPrintingPolicy_SuppressTagKeyword:
5596 P->SuppressTagKeyword = Value;
5597 return;
5598 case CXPrintingPolicy_IncludeTagDefinition:
5599 P->IncludeTagDefinition = Value;
5600 return;
5601 case CXPrintingPolicy_SuppressScope:
5602 P->SuppressScope = Value;
5603 return;
5604 case CXPrintingPolicy_SuppressUnwrittenScope:
5605 P->SuppressUnwrittenScope = Value;
5606 return;
5607 case CXPrintingPolicy_SuppressInitializers:
5608 P->SuppressInitializers = Value;
5609 return;
5610 case CXPrintingPolicy_ConstantArraySizeAsWritten:
5611 P->ConstantArraySizeAsWritten = Value;
5612 return;
5613 case CXPrintingPolicy_AnonymousTagLocations:
5614 P->AnonymousTagLocations = Value;
5615 return;
5616 case CXPrintingPolicy_SuppressStrongLifetime:
5617 P->SuppressStrongLifetime = Value;
5618 return;
5619 case CXPrintingPolicy_SuppressLifetimeQualifiers:
5620 P->SuppressLifetimeQualifiers = Value;
5621 return;
5622 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
5623 P->SuppressTemplateArgsInCXXConstructors = Value;
5624 return;
5625 case CXPrintingPolicy_Bool:
5626 P->Bool = Value;
5627 return;
5628 case CXPrintingPolicy_Restrict:
5629 P->Restrict = Value;
5630 return;
5631 case CXPrintingPolicy_Alignof:
5632 P->Alignof = Value;
5633 return;
5634 case CXPrintingPolicy_UnderscoreAlignof:
5635 P->UnderscoreAlignof = Value;
5636 return;
5637 case CXPrintingPolicy_UseVoidForZeroParams:
5638 P->UseVoidForZeroParams = Value;
5639 return;
5640 case CXPrintingPolicy_TerseOutput:
5641 P->TerseOutput = Value;
5642 return;
5643 case CXPrintingPolicy_PolishForDeclaration:
5644 P->PolishForDeclaration = Value;
5645 return;
5646 case CXPrintingPolicy_Half:
5647 P->Half = Value;
5648 return;
5649 case CXPrintingPolicy_MSWChar:
5650 P->MSWChar = Value;
5651 return;
5652 case CXPrintingPolicy_IncludeNewlines:
5653 P->IncludeNewlines = Value;
5654 return;
5655 case CXPrintingPolicy_MSVCFormatting:
5656 P->MSVCFormatting = Value;
5657 return;
5658 case CXPrintingPolicy_ConstantsAsWritten:
5659 P->ConstantsAsWritten = Value;
5660 return;
5661 case CXPrintingPolicy_SuppressImplicitBase:
5662 P->SuppressImplicitBase = Value;
5663 return;
5664 case CXPrintingPolicy_FullyQualifiedName:
5665 P->FullyQualifiedName = Value;
5666 return;
5669 assert(false && "Invalid CXPrintingPolicyProperty");
5672 CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
5673 if (clang_Cursor_isNull(C))
5674 return cxstring::createEmpty();
5676 if (clang_isDeclaration(C.kind)) {
5677 const Decl *D = getCursorDecl(C);
5678 if (!D)
5679 return cxstring::createEmpty();
5681 SmallString<128> Str;
5682 llvm::raw_svector_ostream OS(Str);
5683 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5684 D->print(OS, UserPolicy ? *UserPolicy
5685 : getCursorContext(C).getPrintingPolicy());
5687 return cxstring::createDup(OS.str());
5690 return cxstring::createEmpty();
5693 CXString clang_getCursorDisplayName(CXCursor C) {
5694 if (!clang_isDeclaration(C.kind))
5695 return clang_getCursorSpelling(C);
5697 const Decl *D = getCursorDecl(C);
5698 if (!D)
5699 return cxstring::createEmpty();
5701 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
5702 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
5703 D = FunTmpl->getTemplatedDecl();
5705 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
5706 SmallString<64> Str;
5707 llvm::raw_svector_ostream OS(Str);
5708 OS << *Function;
5709 if (Function->getPrimaryTemplate())
5710 OS << "<>";
5711 OS << "(";
5712 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5713 if (I)
5714 OS << ", ";
5715 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5718 if (Function->isVariadic()) {
5719 if (Function->getNumParams())
5720 OS << ", ";
5721 OS << "...";
5723 OS << ")";
5724 return cxstring::createDup(OS.str());
5727 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
5728 SmallString<64> Str;
5729 llvm::raw_svector_ostream OS(Str);
5730 OS << *ClassTemplate;
5731 OS << "<";
5732 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5733 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5734 if (I)
5735 OS << ", ";
5737 NamedDecl *Param = Params->getParam(I);
5738 if (Param->getIdentifier()) {
5739 OS << Param->getIdentifier()->getName();
5740 continue;
5743 // There is no parameter name, which makes this tricky. Try to come up
5744 // with something useful that isn't too long.
5745 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
5746 if (const auto *TC = TTP->getTypeConstraint()) {
5747 TC->getConceptNameInfo().printName(OS, Policy);
5748 if (TC->hasExplicitTemplateArgs())
5749 OS << "<...>";
5750 } else
5751 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5752 else if (NonTypeTemplateParmDecl *NTTP =
5753 dyn_cast<NonTypeTemplateParmDecl>(Param))
5754 OS << NTTP->getType().getAsString(Policy);
5755 else
5756 OS << "template<...> class";
5759 OS << ">";
5760 return cxstring::createDup(OS.str());
5763 if (const ClassTemplateSpecializationDecl *ClassSpec =
5764 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
5765 SmallString<128> Str;
5766 llvm::raw_svector_ostream OS(Str);
5767 OS << *ClassSpec;
5768 // If the template arguments were written explicitly, use them..
5769 if (const auto *ArgsWritten = ClassSpec->getTemplateArgsAsWritten()) {
5770 printTemplateArgumentList(
5771 OS, ArgsWritten->arguments(), Policy,
5772 ClassSpec->getSpecializedTemplate()->getTemplateParameters());
5773 } else {
5774 printTemplateArgumentList(
5775 OS, ClassSpec->getTemplateArgs().asArray(), Policy,
5776 ClassSpec->getSpecializedTemplate()->getTemplateParameters());
5778 return cxstring::createDup(OS.str());
5781 return clang_getCursorSpelling(C);
5784 CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5785 switch (Kind) {
5786 case CXCursor_FunctionDecl:
5787 return cxstring::createRef("FunctionDecl");
5788 case CXCursor_TypedefDecl:
5789 return cxstring::createRef("TypedefDecl");
5790 case CXCursor_EnumDecl:
5791 return cxstring::createRef("EnumDecl");
5792 case CXCursor_EnumConstantDecl:
5793 return cxstring::createRef("EnumConstantDecl");
5794 case CXCursor_StructDecl:
5795 return cxstring::createRef("StructDecl");
5796 case CXCursor_UnionDecl:
5797 return cxstring::createRef("UnionDecl");
5798 case CXCursor_ClassDecl:
5799 return cxstring::createRef("ClassDecl");
5800 case CXCursor_FieldDecl:
5801 return cxstring::createRef("FieldDecl");
5802 case CXCursor_VarDecl:
5803 return cxstring::createRef("VarDecl");
5804 case CXCursor_ParmDecl:
5805 return cxstring::createRef("ParmDecl");
5806 case CXCursor_ObjCInterfaceDecl:
5807 return cxstring::createRef("ObjCInterfaceDecl");
5808 case CXCursor_ObjCCategoryDecl:
5809 return cxstring::createRef("ObjCCategoryDecl");
5810 case CXCursor_ObjCProtocolDecl:
5811 return cxstring::createRef("ObjCProtocolDecl");
5812 case CXCursor_ObjCPropertyDecl:
5813 return cxstring::createRef("ObjCPropertyDecl");
5814 case CXCursor_ObjCIvarDecl:
5815 return cxstring::createRef("ObjCIvarDecl");
5816 case CXCursor_ObjCInstanceMethodDecl:
5817 return cxstring::createRef("ObjCInstanceMethodDecl");
5818 case CXCursor_ObjCClassMethodDecl:
5819 return cxstring::createRef("ObjCClassMethodDecl");
5820 case CXCursor_ObjCImplementationDecl:
5821 return cxstring::createRef("ObjCImplementationDecl");
5822 case CXCursor_ObjCCategoryImplDecl:
5823 return cxstring::createRef("ObjCCategoryImplDecl");
5824 case CXCursor_CXXMethod:
5825 return cxstring::createRef("CXXMethod");
5826 case CXCursor_UnexposedDecl:
5827 return cxstring::createRef("UnexposedDecl");
5828 case CXCursor_ObjCSuperClassRef:
5829 return cxstring::createRef("ObjCSuperClassRef");
5830 case CXCursor_ObjCProtocolRef:
5831 return cxstring::createRef("ObjCProtocolRef");
5832 case CXCursor_ObjCClassRef:
5833 return cxstring::createRef("ObjCClassRef");
5834 case CXCursor_TypeRef:
5835 return cxstring::createRef("TypeRef");
5836 case CXCursor_TemplateRef:
5837 return cxstring::createRef("TemplateRef");
5838 case CXCursor_NamespaceRef:
5839 return cxstring::createRef("NamespaceRef");
5840 case CXCursor_MemberRef:
5841 return cxstring::createRef("MemberRef");
5842 case CXCursor_LabelRef:
5843 return cxstring::createRef("LabelRef");
5844 case CXCursor_OverloadedDeclRef:
5845 return cxstring::createRef("OverloadedDeclRef");
5846 case CXCursor_VariableRef:
5847 return cxstring::createRef("VariableRef");
5848 case CXCursor_IntegerLiteral:
5849 return cxstring::createRef("IntegerLiteral");
5850 case CXCursor_FixedPointLiteral:
5851 return cxstring::createRef("FixedPointLiteral");
5852 case CXCursor_FloatingLiteral:
5853 return cxstring::createRef("FloatingLiteral");
5854 case CXCursor_ImaginaryLiteral:
5855 return cxstring::createRef("ImaginaryLiteral");
5856 case CXCursor_StringLiteral:
5857 return cxstring::createRef("StringLiteral");
5858 case CXCursor_CharacterLiteral:
5859 return cxstring::createRef("CharacterLiteral");
5860 case CXCursor_ParenExpr:
5861 return cxstring::createRef("ParenExpr");
5862 case CXCursor_UnaryOperator:
5863 return cxstring::createRef("UnaryOperator");
5864 case CXCursor_ArraySubscriptExpr:
5865 return cxstring::createRef("ArraySubscriptExpr");
5866 case CXCursor_ArraySectionExpr:
5867 return cxstring::createRef("ArraySectionExpr");
5868 case CXCursor_OMPArrayShapingExpr:
5869 return cxstring::createRef("OMPArrayShapingExpr");
5870 case CXCursor_OMPIteratorExpr:
5871 return cxstring::createRef("OMPIteratorExpr");
5872 case CXCursor_BinaryOperator:
5873 return cxstring::createRef("BinaryOperator");
5874 case CXCursor_CompoundAssignOperator:
5875 return cxstring::createRef("CompoundAssignOperator");
5876 case CXCursor_ConditionalOperator:
5877 return cxstring::createRef("ConditionalOperator");
5878 case CXCursor_CStyleCastExpr:
5879 return cxstring::createRef("CStyleCastExpr");
5880 case CXCursor_CompoundLiteralExpr:
5881 return cxstring::createRef("CompoundLiteralExpr");
5882 case CXCursor_InitListExpr:
5883 return cxstring::createRef("InitListExpr");
5884 case CXCursor_AddrLabelExpr:
5885 return cxstring::createRef("AddrLabelExpr");
5886 case CXCursor_StmtExpr:
5887 return cxstring::createRef("StmtExpr");
5888 case CXCursor_GenericSelectionExpr:
5889 return cxstring::createRef("GenericSelectionExpr");
5890 case CXCursor_GNUNullExpr:
5891 return cxstring::createRef("GNUNullExpr");
5892 case CXCursor_CXXStaticCastExpr:
5893 return cxstring::createRef("CXXStaticCastExpr");
5894 case CXCursor_CXXDynamicCastExpr:
5895 return cxstring::createRef("CXXDynamicCastExpr");
5896 case CXCursor_CXXReinterpretCastExpr:
5897 return cxstring::createRef("CXXReinterpretCastExpr");
5898 case CXCursor_CXXConstCastExpr:
5899 return cxstring::createRef("CXXConstCastExpr");
5900 case CXCursor_CXXFunctionalCastExpr:
5901 return cxstring::createRef("CXXFunctionalCastExpr");
5902 case CXCursor_CXXAddrspaceCastExpr:
5903 return cxstring::createRef("CXXAddrspaceCastExpr");
5904 case CXCursor_CXXTypeidExpr:
5905 return cxstring::createRef("CXXTypeidExpr");
5906 case CXCursor_CXXBoolLiteralExpr:
5907 return cxstring::createRef("CXXBoolLiteralExpr");
5908 case CXCursor_CXXNullPtrLiteralExpr:
5909 return cxstring::createRef("CXXNullPtrLiteralExpr");
5910 case CXCursor_CXXThisExpr:
5911 return cxstring::createRef("CXXThisExpr");
5912 case CXCursor_CXXThrowExpr:
5913 return cxstring::createRef("CXXThrowExpr");
5914 case CXCursor_CXXNewExpr:
5915 return cxstring::createRef("CXXNewExpr");
5916 case CXCursor_CXXDeleteExpr:
5917 return cxstring::createRef("CXXDeleteExpr");
5918 case CXCursor_UnaryExpr:
5919 return cxstring::createRef("UnaryExpr");
5920 case CXCursor_ObjCStringLiteral:
5921 return cxstring::createRef("ObjCStringLiteral");
5922 case CXCursor_ObjCBoolLiteralExpr:
5923 return cxstring::createRef("ObjCBoolLiteralExpr");
5924 case CXCursor_ObjCAvailabilityCheckExpr:
5925 return cxstring::createRef("ObjCAvailabilityCheckExpr");
5926 case CXCursor_ObjCSelfExpr:
5927 return cxstring::createRef("ObjCSelfExpr");
5928 case CXCursor_ObjCEncodeExpr:
5929 return cxstring::createRef("ObjCEncodeExpr");
5930 case CXCursor_ObjCSelectorExpr:
5931 return cxstring::createRef("ObjCSelectorExpr");
5932 case CXCursor_ObjCProtocolExpr:
5933 return cxstring::createRef("ObjCProtocolExpr");
5934 case CXCursor_ObjCBridgedCastExpr:
5935 return cxstring::createRef("ObjCBridgedCastExpr");
5936 case CXCursor_BlockExpr:
5937 return cxstring::createRef("BlockExpr");
5938 case CXCursor_PackExpansionExpr:
5939 return cxstring::createRef("PackExpansionExpr");
5940 case CXCursor_SizeOfPackExpr:
5941 return cxstring::createRef("SizeOfPackExpr");
5942 case CXCursor_PackIndexingExpr:
5943 return cxstring::createRef("PackIndexingExpr");
5944 case CXCursor_LambdaExpr:
5945 return cxstring::createRef("LambdaExpr");
5946 case CXCursor_UnexposedExpr:
5947 return cxstring::createRef("UnexposedExpr");
5948 case CXCursor_DeclRefExpr:
5949 return cxstring::createRef("DeclRefExpr");
5950 case CXCursor_MemberRefExpr:
5951 return cxstring::createRef("MemberRefExpr");
5952 case CXCursor_CallExpr:
5953 return cxstring::createRef("CallExpr");
5954 case CXCursor_ObjCMessageExpr:
5955 return cxstring::createRef("ObjCMessageExpr");
5956 case CXCursor_BuiltinBitCastExpr:
5957 return cxstring::createRef("BuiltinBitCastExpr");
5958 case CXCursor_ConceptSpecializationExpr:
5959 return cxstring::createRef("ConceptSpecializationExpr");
5960 case CXCursor_RequiresExpr:
5961 return cxstring::createRef("RequiresExpr");
5962 case CXCursor_CXXParenListInitExpr:
5963 return cxstring::createRef("CXXParenListInitExpr");
5964 case CXCursor_UnexposedStmt:
5965 return cxstring::createRef("UnexposedStmt");
5966 case CXCursor_DeclStmt:
5967 return cxstring::createRef("DeclStmt");
5968 case CXCursor_LabelStmt:
5969 return cxstring::createRef("LabelStmt");
5970 case CXCursor_CompoundStmt:
5971 return cxstring::createRef("CompoundStmt");
5972 case CXCursor_CaseStmt:
5973 return cxstring::createRef("CaseStmt");
5974 case CXCursor_DefaultStmt:
5975 return cxstring::createRef("DefaultStmt");
5976 case CXCursor_IfStmt:
5977 return cxstring::createRef("IfStmt");
5978 case CXCursor_SwitchStmt:
5979 return cxstring::createRef("SwitchStmt");
5980 case CXCursor_WhileStmt:
5981 return cxstring::createRef("WhileStmt");
5982 case CXCursor_DoStmt:
5983 return cxstring::createRef("DoStmt");
5984 case CXCursor_ForStmt:
5985 return cxstring::createRef("ForStmt");
5986 case CXCursor_GotoStmt:
5987 return cxstring::createRef("GotoStmt");
5988 case CXCursor_IndirectGotoStmt:
5989 return cxstring::createRef("IndirectGotoStmt");
5990 case CXCursor_ContinueStmt:
5991 return cxstring::createRef("ContinueStmt");
5992 case CXCursor_BreakStmt:
5993 return cxstring::createRef("BreakStmt");
5994 case CXCursor_ReturnStmt:
5995 return cxstring::createRef("ReturnStmt");
5996 case CXCursor_GCCAsmStmt:
5997 return cxstring::createRef("GCCAsmStmt");
5998 case CXCursor_MSAsmStmt:
5999 return cxstring::createRef("MSAsmStmt");
6000 case CXCursor_ObjCAtTryStmt:
6001 return cxstring::createRef("ObjCAtTryStmt");
6002 case CXCursor_ObjCAtCatchStmt:
6003 return cxstring::createRef("ObjCAtCatchStmt");
6004 case CXCursor_ObjCAtFinallyStmt:
6005 return cxstring::createRef("ObjCAtFinallyStmt");
6006 case CXCursor_ObjCAtThrowStmt:
6007 return cxstring::createRef("ObjCAtThrowStmt");
6008 case CXCursor_ObjCAtSynchronizedStmt:
6009 return cxstring::createRef("ObjCAtSynchronizedStmt");
6010 case CXCursor_ObjCAutoreleasePoolStmt:
6011 return cxstring::createRef("ObjCAutoreleasePoolStmt");
6012 case CXCursor_ObjCForCollectionStmt:
6013 return cxstring::createRef("ObjCForCollectionStmt");
6014 case CXCursor_CXXCatchStmt:
6015 return cxstring::createRef("CXXCatchStmt");
6016 case CXCursor_CXXTryStmt:
6017 return cxstring::createRef("CXXTryStmt");
6018 case CXCursor_CXXForRangeStmt:
6019 return cxstring::createRef("CXXForRangeStmt");
6020 case CXCursor_SEHTryStmt:
6021 return cxstring::createRef("SEHTryStmt");
6022 case CXCursor_SEHExceptStmt:
6023 return cxstring::createRef("SEHExceptStmt");
6024 case CXCursor_SEHFinallyStmt:
6025 return cxstring::createRef("SEHFinallyStmt");
6026 case CXCursor_SEHLeaveStmt:
6027 return cxstring::createRef("SEHLeaveStmt");
6028 case CXCursor_NullStmt:
6029 return cxstring::createRef("NullStmt");
6030 case CXCursor_InvalidFile:
6031 return cxstring::createRef("InvalidFile");
6032 case CXCursor_InvalidCode:
6033 return cxstring::createRef("InvalidCode");
6034 case CXCursor_NoDeclFound:
6035 return cxstring::createRef("NoDeclFound");
6036 case CXCursor_NotImplemented:
6037 return cxstring::createRef("NotImplemented");
6038 case CXCursor_TranslationUnit:
6039 return cxstring::createRef("TranslationUnit");
6040 case CXCursor_UnexposedAttr:
6041 return cxstring::createRef("UnexposedAttr");
6042 case CXCursor_IBActionAttr:
6043 return cxstring::createRef("attribute(ibaction)");
6044 case CXCursor_IBOutletAttr:
6045 return cxstring::createRef("attribute(iboutlet)");
6046 case CXCursor_IBOutletCollectionAttr:
6047 return cxstring::createRef("attribute(iboutletcollection)");
6048 case CXCursor_CXXFinalAttr:
6049 return cxstring::createRef("attribute(final)");
6050 case CXCursor_CXXOverrideAttr:
6051 return cxstring::createRef("attribute(override)");
6052 case CXCursor_AnnotateAttr:
6053 return cxstring::createRef("attribute(annotate)");
6054 case CXCursor_AsmLabelAttr:
6055 return cxstring::createRef("asm label");
6056 case CXCursor_PackedAttr:
6057 return cxstring::createRef("attribute(packed)");
6058 case CXCursor_PureAttr:
6059 return cxstring::createRef("attribute(pure)");
6060 case CXCursor_ConstAttr:
6061 return cxstring::createRef("attribute(const)");
6062 case CXCursor_NoDuplicateAttr:
6063 return cxstring::createRef("attribute(noduplicate)");
6064 case CXCursor_CUDAConstantAttr:
6065 return cxstring::createRef("attribute(constant)");
6066 case CXCursor_CUDADeviceAttr:
6067 return cxstring::createRef("attribute(device)");
6068 case CXCursor_CUDAGlobalAttr:
6069 return cxstring::createRef("attribute(global)");
6070 case CXCursor_CUDAHostAttr:
6071 return cxstring::createRef("attribute(host)");
6072 case CXCursor_CUDASharedAttr:
6073 return cxstring::createRef("attribute(shared)");
6074 case CXCursor_VisibilityAttr:
6075 return cxstring::createRef("attribute(visibility)");
6076 case CXCursor_DLLExport:
6077 return cxstring::createRef("attribute(dllexport)");
6078 case CXCursor_DLLImport:
6079 return cxstring::createRef("attribute(dllimport)");
6080 case CXCursor_NSReturnsRetained:
6081 return cxstring::createRef("attribute(ns_returns_retained)");
6082 case CXCursor_NSReturnsNotRetained:
6083 return cxstring::createRef("attribute(ns_returns_not_retained)");
6084 case CXCursor_NSReturnsAutoreleased:
6085 return cxstring::createRef("attribute(ns_returns_autoreleased)");
6086 case CXCursor_NSConsumesSelf:
6087 return cxstring::createRef("attribute(ns_consumes_self)");
6088 case CXCursor_NSConsumed:
6089 return cxstring::createRef("attribute(ns_consumed)");
6090 case CXCursor_ObjCException:
6091 return cxstring::createRef("attribute(objc_exception)");
6092 case CXCursor_ObjCNSObject:
6093 return cxstring::createRef("attribute(NSObject)");
6094 case CXCursor_ObjCIndependentClass:
6095 return cxstring::createRef("attribute(objc_independent_class)");
6096 case CXCursor_ObjCPreciseLifetime:
6097 return cxstring::createRef("attribute(objc_precise_lifetime)");
6098 case CXCursor_ObjCReturnsInnerPointer:
6099 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
6100 case CXCursor_ObjCRequiresSuper:
6101 return cxstring::createRef("attribute(objc_requires_super)");
6102 case CXCursor_ObjCRootClass:
6103 return cxstring::createRef("attribute(objc_root_class)");
6104 case CXCursor_ObjCSubclassingRestricted:
6105 return cxstring::createRef("attribute(objc_subclassing_restricted)");
6106 case CXCursor_ObjCExplicitProtocolImpl:
6107 return cxstring::createRef(
6108 "attribute(objc_protocol_requires_explicit_implementation)");
6109 case CXCursor_ObjCDesignatedInitializer:
6110 return cxstring::createRef("attribute(objc_designated_initializer)");
6111 case CXCursor_ObjCRuntimeVisible:
6112 return cxstring::createRef("attribute(objc_runtime_visible)");
6113 case CXCursor_ObjCBoxable:
6114 return cxstring::createRef("attribute(objc_boxable)");
6115 case CXCursor_FlagEnum:
6116 return cxstring::createRef("attribute(flag_enum)");
6117 case CXCursor_PreprocessingDirective:
6118 return cxstring::createRef("preprocessing directive");
6119 case CXCursor_MacroDefinition:
6120 return cxstring::createRef("macro definition");
6121 case CXCursor_MacroExpansion:
6122 return cxstring::createRef("macro expansion");
6123 case CXCursor_InclusionDirective:
6124 return cxstring::createRef("inclusion directive");
6125 case CXCursor_Namespace:
6126 return cxstring::createRef("Namespace");
6127 case CXCursor_LinkageSpec:
6128 return cxstring::createRef("LinkageSpec");
6129 case CXCursor_CXXBaseSpecifier:
6130 return cxstring::createRef("C++ base class specifier");
6131 case CXCursor_Constructor:
6132 return cxstring::createRef("CXXConstructor");
6133 case CXCursor_Destructor:
6134 return cxstring::createRef("CXXDestructor");
6135 case CXCursor_ConversionFunction:
6136 return cxstring::createRef("CXXConversion");
6137 case CXCursor_TemplateTypeParameter:
6138 return cxstring::createRef("TemplateTypeParameter");
6139 case CXCursor_NonTypeTemplateParameter:
6140 return cxstring::createRef("NonTypeTemplateParameter");
6141 case CXCursor_TemplateTemplateParameter:
6142 return cxstring::createRef("TemplateTemplateParameter");
6143 case CXCursor_FunctionTemplate:
6144 return cxstring::createRef("FunctionTemplate");
6145 case CXCursor_ClassTemplate:
6146 return cxstring::createRef("ClassTemplate");
6147 case CXCursor_ClassTemplatePartialSpecialization:
6148 return cxstring::createRef("ClassTemplatePartialSpecialization");
6149 case CXCursor_NamespaceAlias:
6150 return cxstring::createRef("NamespaceAlias");
6151 case CXCursor_UsingDirective:
6152 return cxstring::createRef("UsingDirective");
6153 case CXCursor_UsingDeclaration:
6154 return cxstring::createRef("UsingDeclaration");
6155 case CXCursor_TypeAliasDecl:
6156 return cxstring::createRef("TypeAliasDecl");
6157 case CXCursor_ObjCSynthesizeDecl:
6158 return cxstring::createRef("ObjCSynthesizeDecl");
6159 case CXCursor_ObjCDynamicDecl:
6160 return cxstring::createRef("ObjCDynamicDecl");
6161 case CXCursor_CXXAccessSpecifier:
6162 return cxstring::createRef("CXXAccessSpecifier");
6163 case CXCursor_ModuleImportDecl:
6164 return cxstring::createRef("ModuleImport");
6165 case CXCursor_OMPCanonicalLoop:
6166 return cxstring::createRef("OMPCanonicalLoop");
6167 case CXCursor_OMPMetaDirective:
6168 return cxstring::createRef("OMPMetaDirective");
6169 case CXCursor_OMPParallelDirective:
6170 return cxstring::createRef("OMPParallelDirective");
6171 case CXCursor_OMPSimdDirective:
6172 return cxstring::createRef("OMPSimdDirective");
6173 case CXCursor_OMPTileDirective:
6174 return cxstring::createRef("OMPTileDirective");
6175 case CXCursor_OMPUnrollDirective:
6176 return cxstring::createRef("OMPUnrollDirective");
6177 case CXCursor_OMPReverseDirective:
6178 return cxstring::createRef("OMPReverseDirective");
6179 case CXCursor_OMPInterchangeDirective:
6180 return cxstring::createRef("OMPInterchangeDirective");
6181 case CXCursor_OMPForDirective:
6182 return cxstring::createRef("OMPForDirective");
6183 case CXCursor_OMPForSimdDirective:
6184 return cxstring::createRef("OMPForSimdDirective");
6185 case CXCursor_OMPSectionsDirective:
6186 return cxstring::createRef("OMPSectionsDirective");
6187 case CXCursor_OMPSectionDirective:
6188 return cxstring::createRef("OMPSectionDirective");
6189 case CXCursor_OMPScopeDirective:
6190 return cxstring::createRef("OMPScopeDirective");
6191 case CXCursor_OMPSingleDirective:
6192 return cxstring::createRef("OMPSingleDirective");
6193 case CXCursor_OMPMasterDirective:
6194 return cxstring::createRef("OMPMasterDirective");
6195 case CXCursor_OMPCriticalDirective:
6196 return cxstring::createRef("OMPCriticalDirective");
6197 case CXCursor_OMPParallelForDirective:
6198 return cxstring::createRef("OMPParallelForDirective");
6199 case CXCursor_OMPParallelForSimdDirective:
6200 return cxstring::createRef("OMPParallelForSimdDirective");
6201 case CXCursor_OMPParallelMasterDirective:
6202 return cxstring::createRef("OMPParallelMasterDirective");
6203 case CXCursor_OMPParallelMaskedDirective:
6204 return cxstring::createRef("OMPParallelMaskedDirective");
6205 case CXCursor_OMPParallelSectionsDirective:
6206 return cxstring::createRef("OMPParallelSectionsDirective");
6207 case CXCursor_OMPTaskDirective:
6208 return cxstring::createRef("OMPTaskDirective");
6209 case CXCursor_OMPTaskyieldDirective:
6210 return cxstring::createRef("OMPTaskyieldDirective");
6211 case CXCursor_OMPBarrierDirective:
6212 return cxstring::createRef("OMPBarrierDirective");
6213 case CXCursor_OMPTaskwaitDirective:
6214 return cxstring::createRef("OMPTaskwaitDirective");
6215 case CXCursor_OMPAssumeDirective:
6216 return cxstring::createRef("OMPAssumeDirective");
6217 case CXCursor_OMPErrorDirective:
6218 return cxstring::createRef("OMPErrorDirective");
6219 case CXCursor_OMPTaskgroupDirective:
6220 return cxstring::createRef("OMPTaskgroupDirective");
6221 case CXCursor_OMPFlushDirective:
6222 return cxstring::createRef("OMPFlushDirective");
6223 case CXCursor_OMPDepobjDirective:
6224 return cxstring::createRef("OMPDepobjDirective");
6225 case CXCursor_OMPScanDirective:
6226 return cxstring::createRef("OMPScanDirective");
6227 case CXCursor_OMPOrderedDirective:
6228 return cxstring::createRef("OMPOrderedDirective");
6229 case CXCursor_OMPAtomicDirective:
6230 return cxstring::createRef("OMPAtomicDirective");
6231 case CXCursor_OMPTargetDirective:
6232 return cxstring::createRef("OMPTargetDirective");
6233 case CXCursor_OMPTargetDataDirective:
6234 return cxstring::createRef("OMPTargetDataDirective");
6235 case CXCursor_OMPTargetEnterDataDirective:
6236 return cxstring::createRef("OMPTargetEnterDataDirective");
6237 case CXCursor_OMPTargetExitDataDirective:
6238 return cxstring::createRef("OMPTargetExitDataDirective");
6239 case CXCursor_OMPTargetParallelDirective:
6240 return cxstring::createRef("OMPTargetParallelDirective");
6241 case CXCursor_OMPTargetParallelForDirective:
6242 return cxstring::createRef("OMPTargetParallelForDirective");
6243 case CXCursor_OMPTargetUpdateDirective:
6244 return cxstring::createRef("OMPTargetUpdateDirective");
6245 case CXCursor_OMPTeamsDirective:
6246 return cxstring::createRef("OMPTeamsDirective");
6247 case CXCursor_OMPCancellationPointDirective:
6248 return cxstring::createRef("OMPCancellationPointDirective");
6249 case CXCursor_OMPCancelDirective:
6250 return cxstring::createRef("OMPCancelDirective");
6251 case CXCursor_OMPTaskLoopDirective:
6252 return cxstring::createRef("OMPTaskLoopDirective");
6253 case CXCursor_OMPTaskLoopSimdDirective:
6254 return cxstring::createRef("OMPTaskLoopSimdDirective");
6255 case CXCursor_OMPMasterTaskLoopDirective:
6256 return cxstring::createRef("OMPMasterTaskLoopDirective");
6257 case CXCursor_OMPMaskedTaskLoopDirective:
6258 return cxstring::createRef("OMPMaskedTaskLoopDirective");
6259 case CXCursor_OMPMasterTaskLoopSimdDirective:
6260 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
6261 case CXCursor_OMPMaskedTaskLoopSimdDirective:
6262 return cxstring::createRef("OMPMaskedTaskLoopSimdDirective");
6263 case CXCursor_OMPParallelMasterTaskLoopDirective:
6264 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
6265 case CXCursor_OMPParallelMaskedTaskLoopDirective:
6266 return cxstring::createRef("OMPParallelMaskedTaskLoopDirective");
6267 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
6268 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
6269 case CXCursor_OMPParallelMaskedTaskLoopSimdDirective:
6270 return cxstring::createRef("OMPParallelMaskedTaskLoopSimdDirective");
6271 case CXCursor_OMPDistributeDirective:
6272 return cxstring::createRef("OMPDistributeDirective");
6273 case CXCursor_OMPDistributeParallelForDirective:
6274 return cxstring::createRef("OMPDistributeParallelForDirective");
6275 case CXCursor_OMPDistributeParallelForSimdDirective:
6276 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
6277 case CXCursor_OMPDistributeSimdDirective:
6278 return cxstring::createRef("OMPDistributeSimdDirective");
6279 case CXCursor_OMPTargetParallelForSimdDirective:
6280 return cxstring::createRef("OMPTargetParallelForSimdDirective");
6281 case CXCursor_OMPTargetSimdDirective:
6282 return cxstring::createRef("OMPTargetSimdDirective");
6283 case CXCursor_OMPTeamsDistributeDirective:
6284 return cxstring::createRef("OMPTeamsDistributeDirective");
6285 case CXCursor_OMPTeamsDistributeSimdDirective:
6286 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
6287 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
6288 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
6289 case CXCursor_OMPTeamsDistributeParallelForDirective:
6290 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
6291 case CXCursor_OMPTargetTeamsDirective:
6292 return cxstring::createRef("OMPTargetTeamsDirective");
6293 case CXCursor_OMPTargetTeamsDistributeDirective:
6294 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
6295 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
6296 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
6297 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
6298 return cxstring::createRef(
6299 "OMPTargetTeamsDistributeParallelForSimdDirective");
6300 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
6301 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
6302 case CXCursor_OMPInteropDirective:
6303 return cxstring::createRef("OMPInteropDirective");
6304 case CXCursor_OMPDispatchDirective:
6305 return cxstring::createRef("OMPDispatchDirective");
6306 case CXCursor_OMPMaskedDirective:
6307 return cxstring::createRef("OMPMaskedDirective");
6308 case CXCursor_OMPGenericLoopDirective:
6309 return cxstring::createRef("OMPGenericLoopDirective");
6310 case CXCursor_OMPTeamsGenericLoopDirective:
6311 return cxstring::createRef("OMPTeamsGenericLoopDirective");
6312 case CXCursor_OMPTargetTeamsGenericLoopDirective:
6313 return cxstring::createRef("OMPTargetTeamsGenericLoopDirective");
6314 case CXCursor_OMPParallelGenericLoopDirective:
6315 return cxstring::createRef("OMPParallelGenericLoopDirective");
6316 case CXCursor_OMPTargetParallelGenericLoopDirective:
6317 return cxstring::createRef("OMPTargetParallelGenericLoopDirective");
6318 case CXCursor_OverloadCandidate:
6319 return cxstring::createRef("OverloadCandidate");
6320 case CXCursor_TypeAliasTemplateDecl:
6321 return cxstring::createRef("TypeAliasTemplateDecl");
6322 case CXCursor_StaticAssert:
6323 return cxstring::createRef("StaticAssert");
6324 case CXCursor_FriendDecl:
6325 return cxstring::createRef("FriendDecl");
6326 case CXCursor_ConvergentAttr:
6327 return cxstring::createRef("attribute(convergent)");
6328 case CXCursor_WarnUnusedAttr:
6329 return cxstring::createRef("attribute(warn_unused)");
6330 case CXCursor_WarnUnusedResultAttr:
6331 return cxstring::createRef("attribute(warn_unused_result)");
6332 case CXCursor_AlignedAttr:
6333 return cxstring::createRef("attribute(aligned)");
6334 case CXCursor_ConceptDecl:
6335 return cxstring::createRef("ConceptDecl");
6336 case CXCursor_OpenACCComputeConstruct:
6337 return cxstring::createRef("OpenACCComputeConstruct");
6338 case CXCursor_OpenACCLoopConstruct:
6339 return cxstring::createRef("OpenACCLoopConstruct");
6340 case CXCursor_OpenACCCombinedConstruct:
6341 return cxstring::createRef("OpenACCCombinedConstruct");
6344 llvm_unreachable("Unhandled CXCursorKind");
6347 struct GetCursorData {
6348 SourceLocation TokenBeginLoc;
6349 bool PointsAtMacroArgExpansion;
6350 bool VisitedObjCPropertyImplDecl;
6351 SourceLocation VisitedDeclaratorDeclStartLoc;
6352 CXCursor &BestCursor;
6354 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
6355 CXCursor &outputCursor)
6356 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
6357 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
6358 VisitedObjCPropertyImplDecl = false;
6362 static enum CXChildVisitResult
6363 GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
6364 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
6365 CXCursor *BestCursor = &Data->BestCursor;
6367 // If we point inside a macro argument we should provide info of what the
6368 // token is so use the actual cursor, don't replace it with a macro expansion
6369 // cursor.
6370 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
6371 return CXChildVisit_Recurse;
6373 if (clang_isDeclaration(cursor.kind)) {
6374 // Avoid having the implicit methods override the property decls.
6375 if (const ObjCMethodDecl *MD =
6376 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
6377 if (MD->isImplicit())
6378 return CXChildVisit_Break;
6380 } else if (const ObjCInterfaceDecl *ID =
6381 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
6382 // Check that when we have multiple @class references in the same line,
6383 // that later ones do not override the previous ones.
6384 // If we have:
6385 // @class Foo, Bar;
6386 // source ranges for both start at '@', so 'Bar' will end up overriding
6387 // 'Foo' even though the cursor location was at 'Foo'.
6388 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
6389 BestCursor->kind == CXCursor_ObjCClassRef)
6390 if (const ObjCInterfaceDecl *PrevID =
6391 dyn_cast_or_null<ObjCInterfaceDecl>(
6392 getCursorDecl(*BestCursor))) {
6393 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
6394 !ID->isThisDeclarationADefinition())
6395 return CXChildVisit_Break;
6398 } else if (const DeclaratorDecl *DD =
6399 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
6400 SourceLocation StartLoc = DD->getSourceRange().getBegin();
6401 // Check that when we have multiple declarators in the same line,
6402 // that later ones do not override the previous ones.
6403 // If we have:
6404 // int Foo, Bar;
6405 // source ranges for both start at 'int', so 'Bar' will end up overriding
6406 // 'Foo' even though the cursor location was at 'Foo'.
6407 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
6408 return CXChildVisit_Break;
6409 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
6411 } else if (const ObjCPropertyImplDecl *PropImp =
6412 dyn_cast_or_null<ObjCPropertyImplDecl>(
6413 getCursorDecl(cursor))) {
6414 (void)PropImp;
6415 // Check that when we have multiple @synthesize in the same line,
6416 // that later ones do not override the previous ones.
6417 // If we have:
6418 // @synthesize Foo, Bar;
6419 // source ranges for both start at '@', so 'Bar' will end up overriding
6420 // 'Foo' even though the cursor location was at 'Foo'.
6421 if (Data->VisitedObjCPropertyImplDecl)
6422 return CXChildVisit_Break;
6423 Data->VisitedObjCPropertyImplDecl = true;
6427 if (clang_isExpression(cursor.kind) &&
6428 clang_isDeclaration(BestCursor->kind)) {
6429 if (const Decl *D = getCursorDecl(*BestCursor)) {
6430 // Avoid having the cursor of an expression replace the declaration cursor
6431 // when the expression source range overlaps the declaration range.
6432 // This can happen for C++ constructor expressions whose range generally
6433 // include the variable declaration, e.g.:
6434 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
6435 // cursor.
6436 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
6437 D->getLocation() == Data->TokenBeginLoc)
6438 return CXChildVisit_Break;
6442 // If our current best cursor is the construction of a temporary object,
6443 // don't replace that cursor with a type reference, because we want
6444 // clang_getCursor() to point at the constructor.
6445 if (clang_isExpression(BestCursor->kind) &&
6446 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
6447 cursor.kind == CXCursor_TypeRef) {
6448 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
6449 // as having the actual point on the type reference.
6450 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
6451 return CXChildVisit_Recurse;
6454 // If we already have an Objective-C superclass reference, don't
6455 // update it further.
6456 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
6457 return CXChildVisit_Break;
6459 *BestCursor = cursor;
6460 return CXChildVisit_Recurse;
6463 CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
6464 if (isNotUsableTU(TU)) {
6465 LOG_BAD_TU(TU);
6466 return clang_getNullCursor();
6469 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6470 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6472 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
6473 CXCursor Result = cxcursor::getCursor(TU, SLoc);
6475 LOG_FUNC_SECTION {
6476 CXFile SearchFile;
6477 unsigned SearchLine, SearchColumn;
6478 CXFile ResultFile;
6479 unsigned ResultLine, ResultColumn;
6480 CXString SearchFileName, ResultFileName, KindSpelling, USR;
6481 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
6482 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
6484 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
6485 nullptr);
6486 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
6487 nullptr);
6488 SearchFileName = clang_getFileName(SearchFile);
6489 ResultFileName = clang_getFileName(ResultFile);
6490 KindSpelling = clang_getCursorKindSpelling(Result.kind);
6491 USR = clang_getCursorUSR(Result);
6492 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
6493 SearchLine, SearchColumn,
6494 clang_getCString(KindSpelling))
6495 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
6496 ResultLine, ResultColumn, clang_getCString(USR),
6497 IsDef);
6498 clang_disposeString(SearchFileName);
6499 clang_disposeString(ResultFileName);
6500 clang_disposeString(KindSpelling);
6501 clang_disposeString(USR);
6503 CXCursor Definition = clang_getCursorDefinition(Result);
6504 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
6505 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
6506 CXString DefinitionKindSpelling =
6507 clang_getCursorKindSpelling(Definition.kind);
6508 CXFile DefinitionFile;
6509 unsigned DefinitionLine, DefinitionColumn;
6510 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
6511 &DefinitionColumn, nullptr);
6512 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
6513 *Log << llvm::format(" -> %s(%s:%d:%d)",
6514 clang_getCString(DefinitionKindSpelling),
6515 clang_getCString(DefinitionFileName), DefinitionLine,
6516 DefinitionColumn);
6517 clang_disposeString(DefinitionFileName);
6518 clang_disposeString(DefinitionKindSpelling);
6522 return Result;
6525 CXCursor clang_getNullCursor(void) {
6526 return MakeCXCursorInvalid(CXCursor_InvalidFile);
6529 unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
6530 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
6531 // can't set consistently. For example, when visiting a DeclStmt we will set
6532 // it but we don't set it on the result of clang_getCursorDefinition for
6533 // a reference of the same declaration.
6534 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
6535 // when visiting a DeclStmt currently, the AST should be enhanced to be able
6536 // to provide that kind of info.
6537 if (clang_isDeclaration(X.kind))
6538 X.data[1] = nullptr;
6539 if (clang_isDeclaration(Y.kind))
6540 Y.data[1] = nullptr;
6542 return X == Y;
6545 unsigned clang_hashCursor(CXCursor C) {
6546 unsigned Index = 0;
6547 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
6548 Index = 1;
6550 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
6551 std::make_pair(C.kind, C.data[Index]));
6554 unsigned clang_isInvalid(enum CXCursorKind K) {
6555 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
6558 unsigned clang_isDeclaration(enum CXCursorKind K) {
6559 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
6560 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
6563 unsigned clang_isInvalidDeclaration(CXCursor C) {
6564 if (clang_isDeclaration(C.kind)) {
6565 if (const Decl *D = getCursorDecl(C))
6566 return D->isInvalidDecl();
6569 return 0;
6572 unsigned clang_isReference(enum CXCursorKind K) {
6573 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
6576 unsigned clang_isExpression(enum CXCursorKind K) {
6577 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
6580 unsigned clang_isStatement(enum CXCursorKind K) {
6581 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
6584 unsigned clang_isAttribute(enum CXCursorKind K) {
6585 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
6588 unsigned clang_isTranslationUnit(enum CXCursorKind K) {
6589 return K == CXCursor_TranslationUnit;
6592 unsigned clang_isPreprocessing(enum CXCursorKind K) {
6593 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
6596 unsigned clang_isUnexposed(enum CXCursorKind K) {
6597 switch (K) {
6598 case CXCursor_UnexposedDecl:
6599 case CXCursor_UnexposedExpr:
6600 case CXCursor_UnexposedStmt:
6601 case CXCursor_UnexposedAttr:
6602 return true;
6603 default:
6604 return false;
6608 CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
6610 CXSourceLocation clang_getCursorLocation(CXCursor C) {
6611 if (clang_isReference(C.kind)) {
6612 switch (C.kind) {
6613 case CXCursor_ObjCSuperClassRef: {
6614 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
6615 getCursorObjCSuperClassRef(C);
6616 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6619 case CXCursor_ObjCProtocolRef: {
6620 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
6621 getCursorObjCProtocolRef(C);
6622 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6625 case CXCursor_ObjCClassRef: {
6626 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
6627 getCursorObjCClassRef(C);
6628 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6631 case CXCursor_TypeRef: {
6632 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
6633 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6636 case CXCursor_TemplateRef: {
6637 std::pair<const TemplateDecl *, SourceLocation> P =
6638 getCursorTemplateRef(C);
6639 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6642 case CXCursor_NamespaceRef: {
6643 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
6644 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6647 case CXCursor_MemberRef: {
6648 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
6649 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6652 case CXCursor_VariableRef: {
6653 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
6654 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6657 case CXCursor_CXXBaseSpecifier: {
6658 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
6659 if (!BaseSpec)
6660 return clang_getNullLocation();
6662 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
6663 return cxloc::translateSourceLocation(
6664 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
6666 return cxloc::translateSourceLocation(getCursorContext(C),
6667 BaseSpec->getBeginLoc());
6670 case CXCursor_LabelRef: {
6671 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
6672 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
6675 case CXCursor_OverloadedDeclRef:
6676 return cxloc::translateSourceLocation(
6677 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
6679 default:
6680 // FIXME: Need a way to enumerate all non-reference cases.
6681 llvm_unreachable("Missed a reference kind");
6685 if (clang_isExpression(C.kind))
6686 return cxloc::translateSourceLocation(
6687 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
6689 if (clang_isStatement(C.kind))
6690 return cxloc::translateSourceLocation(getCursorContext(C),
6691 getCursorStmt(C)->getBeginLoc());
6693 if (C.kind == CXCursor_PreprocessingDirective) {
6694 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
6695 return cxloc::translateSourceLocation(getCursorContext(C), L);
6698 if (C.kind == CXCursor_MacroExpansion) {
6699 SourceLocation L =
6700 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
6701 return cxloc::translateSourceLocation(getCursorContext(C), L);
6704 if (C.kind == CXCursor_MacroDefinition) {
6705 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
6706 return cxloc::translateSourceLocation(getCursorContext(C), L);
6709 if (C.kind == CXCursor_InclusionDirective) {
6710 SourceLocation L =
6711 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
6712 return cxloc::translateSourceLocation(getCursorContext(C), L);
6715 if (clang_isAttribute(C.kind)) {
6716 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
6717 return cxloc::translateSourceLocation(getCursorContext(C), L);
6720 if (!clang_isDeclaration(C.kind))
6721 return clang_getNullLocation();
6723 const Decl *D = getCursorDecl(C);
6724 if (!D)
6725 return clang_getNullLocation();
6727 SourceLocation Loc = D->getLocation();
6728 // FIXME: Multiple variables declared in a single declaration
6729 // currently lack the information needed to correctly determine their
6730 // ranges when accounting for the type-specifier. We use context
6731 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6732 // and if so, whether it is the first decl.
6733 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6734 if (!cxcursor::isFirstInDeclGroup(C))
6735 Loc = VD->getLocation();
6738 // For ObjC methods, give the start location of the method name.
6739 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6740 Loc = MD->getSelectorStartLoc();
6742 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
6745 } // end extern "C"
6747 CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6748 assert(TU);
6750 // Guard against an invalid SourceLocation, or we may assert in one
6751 // of the following calls.
6752 if (SLoc.isInvalid())
6753 return clang_getNullCursor();
6755 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6757 // Translate the given source location to make it point at the beginning of
6758 // the token under the cursor.
6759 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6760 CXXUnit->getASTContext().getLangOpts());
6762 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6763 if (SLoc.isValid()) {
6764 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6765 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
6766 /*VisitPreprocessorLast=*/true,
6767 /*VisitIncludedEntities=*/false,
6768 SourceLocation(SLoc));
6769 CursorVis.visitFileRegion();
6772 return Result;
6775 static SourceRange getRawCursorExtent(CXCursor C) {
6776 if (clang_isReference(C.kind)) {
6777 switch (C.kind) {
6778 case CXCursor_ObjCSuperClassRef:
6779 return getCursorObjCSuperClassRef(C).second;
6781 case CXCursor_ObjCProtocolRef:
6782 return getCursorObjCProtocolRef(C).second;
6784 case CXCursor_ObjCClassRef:
6785 return getCursorObjCClassRef(C).second;
6787 case CXCursor_TypeRef:
6788 return getCursorTypeRef(C).second;
6790 case CXCursor_TemplateRef:
6791 return getCursorTemplateRef(C).second;
6793 case CXCursor_NamespaceRef:
6794 return getCursorNamespaceRef(C).second;
6796 case CXCursor_MemberRef:
6797 return getCursorMemberRef(C).second;
6799 case CXCursor_CXXBaseSpecifier:
6800 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6802 case CXCursor_LabelRef:
6803 return getCursorLabelRef(C).second;
6805 case CXCursor_OverloadedDeclRef:
6806 return getCursorOverloadedDeclRef(C).second;
6808 case CXCursor_VariableRef:
6809 return getCursorVariableRef(C).second;
6811 default:
6812 // FIXME: Need a way to enumerate all non-reference cases.
6813 llvm_unreachable("Missed a reference kind");
6817 if (clang_isExpression(C.kind))
6818 return getCursorExpr(C)->getSourceRange();
6820 if (clang_isStatement(C.kind))
6821 return getCursorStmt(C)->getSourceRange();
6823 if (clang_isAttribute(C.kind))
6824 return getCursorAttr(C)->getRange();
6826 if (C.kind == CXCursor_PreprocessingDirective)
6827 return cxcursor::getCursorPreprocessingDirective(C);
6829 if (C.kind == CXCursor_MacroExpansion) {
6830 ASTUnit *TU = getCursorASTUnit(C);
6831 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
6832 return TU->mapRangeFromPreamble(Range);
6835 if (C.kind == CXCursor_MacroDefinition) {
6836 ASTUnit *TU = getCursorASTUnit(C);
6837 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6838 return TU->mapRangeFromPreamble(Range);
6841 if (C.kind == CXCursor_InclusionDirective) {
6842 ASTUnit *TU = getCursorASTUnit(C);
6843 SourceRange Range =
6844 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
6845 return TU->mapRangeFromPreamble(Range);
6848 if (C.kind == CXCursor_TranslationUnit) {
6849 ASTUnit *TU = getCursorASTUnit(C);
6850 FileID MainID = TU->getSourceManager().getMainFileID();
6851 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6852 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6853 return SourceRange(Start, End);
6856 if (clang_isDeclaration(C.kind)) {
6857 const Decl *D = cxcursor::getCursorDecl(C);
6858 if (!D)
6859 return SourceRange();
6861 SourceRange R = D->getSourceRange();
6862 // FIXME: Multiple variables declared in a single declaration
6863 // currently lack the information needed to correctly determine their
6864 // ranges when accounting for the type-specifier. We use context
6865 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6866 // and if so, whether it is the first decl.
6867 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6868 if (!cxcursor::isFirstInDeclGroup(C))
6869 R.setBegin(VD->getLocation());
6871 return R;
6873 return SourceRange();
6876 /// Retrieves the "raw" cursor extent, which is then extended to include
6877 /// the decl-specifier-seq for declarations.
6878 static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6879 if (clang_isDeclaration(C.kind)) {
6880 const Decl *D = cxcursor::getCursorDecl(C);
6881 if (!D)
6882 return SourceRange();
6884 SourceRange R = D->getSourceRange();
6886 // Adjust the start of the location for declarations preceded by
6887 // declaration specifiers.
6888 SourceLocation StartLoc;
6889 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6890 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
6891 StartLoc = TI->getTypeLoc().getBeginLoc();
6892 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
6893 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
6894 StartLoc = TI->getTypeLoc().getBeginLoc();
6897 if (StartLoc.isValid() && R.getBegin().isValid() &&
6898 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6899 R.setBegin(StartLoc);
6901 // FIXME: Multiple variables declared in a single declaration
6902 // currently lack the information needed to correctly determine their
6903 // ranges when accounting for the type-specifier. We use context
6904 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6905 // and if so, whether it is the first decl.
6906 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6907 if (!cxcursor::isFirstInDeclGroup(C))
6908 R.setBegin(VD->getLocation());
6911 return R;
6914 return getRawCursorExtent(C);
6917 CXSourceRange clang_getCursorExtent(CXCursor C) {
6918 SourceRange R = getRawCursorExtent(C);
6919 if (R.isInvalid())
6920 return clang_getNullRange();
6922 return cxloc::translateSourceRange(getCursorContext(C), R);
6925 CXCursor clang_getCursorReferenced(CXCursor C) {
6926 if (clang_isInvalid(C.kind))
6927 return clang_getNullCursor();
6929 CXTranslationUnit tu = getCursorTU(C);
6930 if (clang_isDeclaration(C.kind)) {
6931 const Decl *D = getCursorDecl(C);
6932 if (!D)
6933 return clang_getNullCursor();
6934 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
6935 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
6936 if (const ObjCPropertyImplDecl *PropImpl =
6937 dyn_cast<ObjCPropertyImplDecl>(D))
6938 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6939 return MakeCXCursor(Property, tu);
6941 return C;
6944 if (clang_isExpression(C.kind)) {
6945 const Expr *E = getCursorExpr(C);
6946 const Decl *D = getDeclFromExpr(E);
6947 if (D) {
6948 CXCursor declCursor = MakeCXCursor(D, tu);
6949 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6950 declCursor);
6951 return declCursor;
6954 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
6955 return MakeCursorOverloadedDeclRef(Ovl, tu);
6957 return clang_getNullCursor();
6960 if (clang_isStatement(C.kind)) {
6961 const Stmt *S = getCursorStmt(C);
6962 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
6963 if (LabelDecl *label = Goto->getLabel())
6964 if (LabelStmt *labelS = label->getStmt())
6965 return MakeCXCursor(labelS, getCursorDecl(C), tu);
6967 return clang_getNullCursor();
6970 if (C.kind == CXCursor_MacroExpansion) {
6971 if (const MacroDefinitionRecord *Def =
6972 getCursorMacroExpansion(C).getDefinition())
6973 return MakeMacroDefinitionCursor(Def, tu);
6976 if (!clang_isReference(C.kind))
6977 return clang_getNullCursor();
6979 switch (C.kind) {
6980 case CXCursor_ObjCSuperClassRef:
6981 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
6983 case CXCursor_ObjCProtocolRef: {
6984 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6985 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6986 return MakeCXCursor(Def, tu);
6988 return MakeCXCursor(Prot, tu);
6991 case CXCursor_ObjCClassRef: {
6992 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6993 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6994 return MakeCXCursor(Def, tu);
6996 return MakeCXCursor(Class, tu);
6999 case CXCursor_TypeRef:
7000 return MakeCXCursor(getCursorTypeRef(C).first, tu);
7002 case CXCursor_TemplateRef:
7003 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
7005 case CXCursor_NamespaceRef:
7006 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
7008 case CXCursor_MemberRef:
7009 return MakeCXCursor(getCursorMemberRef(C).first, tu);
7011 case CXCursor_CXXBaseSpecifier: {
7012 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
7013 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
7016 case CXCursor_LabelRef:
7017 // FIXME: We end up faking the "parent" declaration here because we
7018 // don't want to make CXCursor larger.
7019 return MakeCXCursor(
7020 getCursorLabelRef(C).first,
7021 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
7023 case CXCursor_OverloadedDeclRef:
7024 return C;
7026 case CXCursor_VariableRef:
7027 return MakeCXCursor(getCursorVariableRef(C).first, tu);
7029 default:
7030 // We would prefer to enumerate all non-reference cursor kinds here.
7031 llvm_unreachable("Unhandled reference cursor kind");
7035 CXCursor clang_getCursorDefinition(CXCursor C) {
7036 if (clang_isInvalid(C.kind))
7037 return clang_getNullCursor();
7039 CXTranslationUnit TU = getCursorTU(C);
7041 bool WasReference = false;
7042 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
7043 C = clang_getCursorReferenced(C);
7044 WasReference = true;
7047 if (C.kind == CXCursor_MacroExpansion)
7048 return clang_getCursorReferenced(C);
7050 if (!clang_isDeclaration(C.kind))
7051 return clang_getNullCursor();
7053 const Decl *D = getCursorDecl(C);
7054 if (!D)
7055 return clang_getNullCursor();
7057 switch (D->getKind()) {
7058 // Declaration kinds that don't really separate the notions of
7059 // declaration and definition.
7060 case Decl::Namespace:
7061 case Decl::Typedef:
7062 case Decl::TypeAlias:
7063 case Decl::TypeAliasTemplate:
7064 case Decl::TemplateTypeParm:
7065 case Decl::EnumConstant:
7066 case Decl::Field:
7067 case Decl::Binding:
7068 case Decl::MSProperty:
7069 case Decl::MSGuid:
7070 case Decl::HLSLBuffer:
7071 case Decl::UnnamedGlobalConstant:
7072 case Decl::TemplateParamObject:
7073 case Decl::IndirectField:
7074 case Decl::ObjCIvar:
7075 case Decl::ObjCAtDefsField:
7076 case Decl::ImplicitParam:
7077 case Decl::ParmVar:
7078 case Decl::NonTypeTemplateParm:
7079 case Decl::TemplateTemplateParm:
7080 case Decl::ObjCCategoryImpl:
7081 case Decl::ObjCImplementation:
7082 case Decl::AccessSpec:
7083 case Decl::LinkageSpec:
7084 case Decl::Export:
7085 case Decl::ObjCPropertyImpl:
7086 case Decl::FileScopeAsm:
7087 case Decl::TopLevelStmt:
7088 case Decl::StaticAssert:
7089 case Decl::Block:
7090 case Decl::Captured:
7091 case Decl::OMPCapturedExpr:
7092 case Decl::Label: // FIXME: Is this right??
7093 case Decl::CXXDeductionGuide:
7094 case Decl::Import:
7095 case Decl::OMPThreadPrivate:
7096 case Decl::OMPAllocate:
7097 case Decl::OMPDeclareReduction:
7098 case Decl::OMPDeclareMapper:
7099 case Decl::OMPRequires:
7100 case Decl::ObjCTypeParam:
7101 case Decl::BuiltinTemplate:
7102 case Decl::PragmaComment:
7103 case Decl::PragmaDetectMismatch:
7104 case Decl::UsingPack:
7105 case Decl::Concept:
7106 case Decl::ImplicitConceptSpecialization:
7107 case Decl::LifetimeExtendedTemporary:
7108 case Decl::RequiresExprBody:
7109 case Decl::UnresolvedUsingIfExists:
7110 return C;
7112 // Declaration kinds that don't make any sense here, but are
7113 // nonetheless harmless.
7114 case Decl::Empty:
7115 case Decl::TranslationUnit:
7116 case Decl::ExternCContext:
7117 break;
7119 // Declaration kinds for which the definition is not resolvable.
7120 case Decl::UnresolvedUsingTypename:
7121 case Decl::UnresolvedUsingValue:
7122 break;
7124 case Decl::UsingDirective:
7125 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
7126 TU);
7128 case Decl::NamespaceAlias:
7129 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
7131 case Decl::Enum:
7132 case Decl::Record:
7133 case Decl::CXXRecord:
7134 case Decl::ClassTemplateSpecialization:
7135 case Decl::ClassTemplatePartialSpecialization:
7136 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
7137 return MakeCXCursor(Def, TU);
7138 return clang_getNullCursor();
7140 case Decl::Function:
7141 case Decl::CXXMethod:
7142 case Decl::CXXConstructor:
7143 case Decl::CXXDestructor:
7144 case Decl::CXXConversion: {
7145 const FunctionDecl *Def = nullptr;
7146 if (cast<FunctionDecl>(D)->getBody(Def))
7147 return MakeCXCursor(Def, TU);
7148 return clang_getNullCursor();
7151 case Decl::Var:
7152 case Decl::VarTemplateSpecialization:
7153 case Decl::VarTemplatePartialSpecialization:
7154 case Decl::Decomposition: {
7155 // Ask the variable if it has a definition.
7156 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
7157 return MakeCXCursor(Def, TU);
7158 return clang_getNullCursor();
7161 case Decl::FunctionTemplate: {
7162 const FunctionDecl *Def = nullptr;
7163 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
7164 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
7165 return clang_getNullCursor();
7168 case Decl::ClassTemplate: {
7169 if (RecordDecl *Def =
7170 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
7171 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
7172 TU);
7173 return clang_getNullCursor();
7176 case Decl::VarTemplate: {
7177 if (VarDecl *Def =
7178 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
7179 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
7180 return clang_getNullCursor();
7183 case Decl::Using:
7184 case Decl::UsingEnum:
7185 return MakeCursorOverloadedDeclRef(cast<BaseUsingDecl>(D), D->getLocation(),
7186 TU);
7188 case Decl::UsingShadow:
7189 case Decl::ConstructorUsingShadow:
7190 return clang_getCursorDefinition(
7191 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
7193 case Decl::ObjCMethod: {
7194 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
7195 if (Method->isThisDeclarationADefinition())
7196 return C;
7198 // Dig out the method definition in the associated
7199 // @implementation, if we have it.
7200 // FIXME: The ASTs should make finding the definition easier.
7201 if (const ObjCInterfaceDecl *Class =
7202 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
7203 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
7204 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
7205 Method->getSelector(), Method->isInstanceMethod()))
7206 if (Def->isThisDeclarationADefinition())
7207 return MakeCXCursor(Def, TU);
7209 return clang_getNullCursor();
7212 case Decl::ObjCCategory:
7213 if (ObjCCategoryImplDecl *Impl =
7214 cast<ObjCCategoryDecl>(D)->getImplementation())
7215 return MakeCXCursor(Impl, TU);
7216 return clang_getNullCursor();
7218 case Decl::ObjCProtocol:
7219 if (const ObjCProtocolDecl *Def =
7220 cast<ObjCProtocolDecl>(D)->getDefinition())
7221 return MakeCXCursor(Def, TU);
7222 return clang_getNullCursor();
7224 case Decl::ObjCInterface: {
7225 // There are two notions of a "definition" for an Objective-C
7226 // class: the interface and its implementation. When we resolved a
7227 // reference to an Objective-C class, produce the @interface as
7228 // the definition; when we were provided with the interface,
7229 // produce the @implementation as the definition.
7230 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
7231 if (WasReference) {
7232 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
7233 return MakeCXCursor(Def, TU);
7234 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
7235 return MakeCXCursor(Impl, TU);
7236 return clang_getNullCursor();
7239 case Decl::ObjCProperty:
7240 // FIXME: We don't really know where to find the
7241 // ObjCPropertyImplDecls that implement this property.
7242 return clang_getNullCursor();
7244 case Decl::ObjCCompatibleAlias:
7245 if (const ObjCInterfaceDecl *Class =
7246 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
7247 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
7248 return MakeCXCursor(Def, TU);
7250 return clang_getNullCursor();
7252 case Decl::Friend:
7253 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
7254 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
7255 return clang_getNullCursor();
7257 case Decl::FriendTemplate:
7258 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
7259 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
7260 return clang_getNullCursor();
7263 return clang_getNullCursor();
7266 unsigned clang_isCursorDefinition(CXCursor C) {
7267 if (!clang_isDeclaration(C.kind))
7268 return 0;
7270 return clang_getCursorDefinition(C) == C;
7273 CXCursor clang_getCanonicalCursor(CXCursor C) {
7274 if (!clang_isDeclaration(C.kind))
7275 return C;
7277 if (const Decl *D = getCursorDecl(C)) {
7278 if (const ObjCCategoryImplDecl *CatImplD =
7279 dyn_cast<ObjCCategoryImplDecl>(D))
7280 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
7281 return MakeCXCursor(CatD, getCursorTU(C));
7283 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
7284 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
7285 return MakeCXCursor(IFD, getCursorTU(C));
7287 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
7290 return C;
7293 int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
7294 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
7297 unsigned clang_getNumOverloadedDecls(CXCursor C) {
7298 if (C.kind != CXCursor_OverloadedDeclRef)
7299 return 0;
7301 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
7302 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
7303 return E->getNumDecls();
7305 if (OverloadedTemplateStorage *S =
7306 Storage.dyn_cast<OverloadedTemplateStorage *>())
7307 return S->size();
7309 const Decl *D = Storage.get<const Decl *>();
7310 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
7311 return Using->shadow_size();
7313 return 0;
7316 CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
7317 if (cursor.kind != CXCursor_OverloadedDeclRef)
7318 return clang_getNullCursor();
7320 if (index >= clang_getNumOverloadedDecls(cursor))
7321 return clang_getNullCursor();
7323 CXTranslationUnit TU = getCursorTU(cursor);
7324 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
7325 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
7326 return MakeCXCursor(E->decls_begin()[index], TU);
7328 if (OverloadedTemplateStorage *S =
7329 Storage.dyn_cast<OverloadedTemplateStorage *>())
7330 return MakeCXCursor(S->begin()[index], TU);
7332 const Decl *D = Storage.get<const Decl *>();
7333 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
7334 // FIXME: This is, unfortunately, linear time.
7335 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
7336 std::advance(Pos, index);
7337 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
7340 return clang_getNullCursor();
7343 void clang_getDefinitionSpellingAndExtent(
7344 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
7345 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
7346 assert(getCursorDecl(C) && "CXCursor has null decl");
7347 const auto *FD = cast<FunctionDecl>(getCursorDecl(C));
7348 const auto *Body = cast<CompoundStmt>(FD->getBody());
7350 SourceManager &SM = FD->getASTContext().getSourceManager();
7351 *startBuf = SM.getCharacterData(Body->getLBracLoc());
7352 *endBuf = SM.getCharacterData(Body->getRBracLoc());
7353 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
7354 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
7355 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
7356 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
7359 CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
7360 unsigned PieceIndex) {
7361 RefNamePieces Pieces;
7363 switch (C.kind) {
7364 case CXCursor_MemberRefExpr:
7365 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
7366 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
7367 E->getQualifierLoc().getSourceRange());
7368 break;
7370 case CXCursor_DeclRefExpr:
7371 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
7372 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
7373 Pieces =
7374 buildPieces(NameFlags, false, E->getNameInfo(),
7375 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
7377 break;
7379 case CXCursor_CallExpr:
7380 if (const CXXOperatorCallExpr *OCE =
7381 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
7382 const Expr *Callee = OCE->getCallee();
7383 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
7384 Callee = ICE->getSubExpr();
7386 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
7387 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
7388 DRE->getQualifierLoc().getSourceRange());
7390 break;
7392 default:
7393 break;
7396 if (Pieces.empty()) {
7397 if (PieceIndex == 0)
7398 return clang_getCursorExtent(C);
7399 } else if (PieceIndex < Pieces.size()) {
7400 SourceRange R = Pieces[PieceIndex];
7401 if (R.isValid())
7402 return cxloc::translateSourceRange(getCursorContext(C), R);
7405 return clang_getNullRange();
7408 void clang_enableStackTraces(void) {
7409 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
7410 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
7413 void clang_executeOnThread(void (*fn)(void *), void *user_data,
7414 unsigned stack_size) {
7415 llvm::thread Thread(stack_size == 0 ? clang::DesiredStackSize
7416 : std::optional<unsigned>(stack_size),
7417 fn, user_data);
7418 Thread.join();
7421 //===----------------------------------------------------------------------===//
7422 // Token-based Operations.
7423 //===----------------------------------------------------------------------===//
7425 /* CXToken layout:
7426 * int_data[0]: a CXTokenKind
7427 * int_data[1]: starting token location
7428 * int_data[2]: token length
7429 * int_data[3]: reserved
7430 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
7431 * otherwise unused.
7433 CXTokenKind clang_getTokenKind(CXToken CXTok) {
7434 return static_cast<CXTokenKind>(CXTok.int_data[0]);
7437 CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
7438 switch (clang_getTokenKind(CXTok)) {
7439 case CXToken_Identifier:
7440 case CXToken_Keyword:
7441 // We know we have an IdentifierInfo*, so use that.
7442 return cxstring::createRef(
7443 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
7445 case CXToken_Literal: {
7446 // We have stashed the starting pointer in the ptr_data field. Use it.
7447 const char *Text = static_cast<const char *>(CXTok.ptr_data);
7448 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
7451 case CXToken_Punctuation:
7452 case CXToken_Comment:
7453 break;
7456 if (isNotUsableTU(TU)) {
7457 LOG_BAD_TU(TU);
7458 return cxstring::createEmpty();
7461 // We have to find the starting buffer pointer the hard way, by
7462 // deconstructing the source location.
7463 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7464 if (!CXXUnit)
7465 return cxstring::createEmpty();
7467 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
7468 std::pair<FileID, unsigned> LocInfo =
7469 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
7470 bool Invalid = false;
7471 StringRef Buffer =
7472 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
7473 if (Invalid)
7474 return cxstring::createEmpty();
7476 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
7479 CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
7480 if (isNotUsableTU(TU)) {
7481 LOG_BAD_TU(TU);
7482 return clang_getNullLocation();
7485 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7486 if (!CXXUnit)
7487 return clang_getNullLocation();
7489 return cxloc::translateSourceLocation(
7490 CXXUnit->getASTContext(),
7491 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
7494 CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
7495 if (isNotUsableTU(TU)) {
7496 LOG_BAD_TU(TU);
7497 return clang_getNullRange();
7500 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7501 if (!CXXUnit)
7502 return clang_getNullRange();
7504 return cxloc::translateSourceRange(
7505 CXXUnit->getASTContext(),
7506 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
7509 static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
7510 SmallVectorImpl<CXToken> &CXTokens) {
7511 SourceManager &SourceMgr = CXXUnit->getSourceManager();
7512 std::pair<FileID, unsigned> BeginLocInfo =
7513 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
7514 std::pair<FileID, unsigned> EndLocInfo =
7515 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
7517 // Cannot tokenize across files.
7518 if (BeginLocInfo.first != EndLocInfo.first)
7519 return;
7521 // Create a lexer
7522 bool Invalid = false;
7523 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7524 if (Invalid)
7525 return;
7527 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
7528 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7529 Buffer.data() + BeginLocInfo.second, Buffer.end());
7530 Lex.SetCommentRetentionState(true);
7532 // Lex tokens until we hit the end of the range.
7533 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
7534 Token Tok;
7535 bool previousWasAt = false;
7536 do {
7537 // Lex the next token
7538 Lex.LexFromRawLexer(Tok);
7539 if (Tok.is(tok::eof))
7540 break;
7542 // Initialize the CXToken.
7543 CXToken CXTok;
7545 // - Common fields
7546 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
7547 CXTok.int_data[2] = Tok.getLength();
7548 CXTok.int_data[3] = 0;
7550 // - Kind-specific fields
7551 if (Tok.isLiteral()) {
7552 CXTok.int_data[0] = CXToken_Literal;
7553 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
7554 } else if (Tok.is(tok::raw_identifier)) {
7555 // Lookup the identifier to determine whether we have a keyword.
7556 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
7558 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
7559 CXTok.int_data[0] = CXToken_Keyword;
7560 } else {
7561 CXTok.int_data[0] =
7562 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
7564 CXTok.ptr_data = II;
7565 } else if (Tok.is(tok::comment)) {
7566 CXTok.int_data[0] = CXToken_Comment;
7567 CXTok.ptr_data = nullptr;
7568 } else {
7569 CXTok.int_data[0] = CXToken_Punctuation;
7570 CXTok.ptr_data = nullptr;
7572 CXTokens.push_back(CXTok);
7573 previousWasAt = Tok.is(tok::at);
7574 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
7577 CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
7578 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
7580 if (isNotUsableTU(TU)) {
7581 LOG_BAD_TU(TU);
7582 return nullptr;
7585 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7586 if (!CXXUnit)
7587 return nullptr;
7589 SourceLocation Begin = cxloc::translateSourceLocation(Location);
7590 if (Begin.isInvalid())
7591 return nullptr;
7592 SourceManager &SM = CXXUnit->getSourceManager();
7593 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
7594 DecomposedEnd.second +=
7595 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
7597 SourceLocation End =
7598 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
7600 SmallVector<CXToken, 32> CXTokens;
7601 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
7603 if (CXTokens.empty())
7604 return nullptr;
7606 CXTokens.resize(1);
7607 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
7609 memmove(Token, CXTokens.data(), sizeof(CXToken));
7610 return Token;
7613 void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
7614 unsigned *NumTokens) {
7615 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
7617 if (Tokens)
7618 *Tokens = nullptr;
7619 if (NumTokens)
7620 *NumTokens = 0;
7622 if (isNotUsableTU(TU)) {
7623 LOG_BAD_TU(TU);
7624 return;
7627 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7628 if (!CXXUnit || !Tokens || !NumTokens)
7629 return;
7631 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
7633 SourceRange R = cxloc::translateCXSourceRange(Range);
7634 if (R.isInvalid())
7635 return;
7637 SmallVector<CXToken, 32> CXTokens;
7638 getTokens(CXXUnit, R, CXTokens);
7640 if (CXTokens.empty())
7641 return;
7643 *Tokens = static_cast<CXToken *>(
7644 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
7645 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
7646 *NumTokens = CXTokens.size();
7649 void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
7650 unsigned NumTokens) {
7651 free(Tokens);
7654 //===----------------------------------------------------------------------===//
7655 // Token annotation APIs.
7656 //===----------------------------------------------------------------------===//
7658 static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7659 CXCursor parent,
7660 CXClientData client_data);
7661 static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7662 CXClientData client_data);
7664 namespace {
7665 class AnnotateTokensWorker {
7666 CXToken *Tokens;
7667 CXCursor *Cursors;
7668 unsigned NumTokens;
7669 unsigned TokIdx;
7670 unsigned PreprocessingTokIdx;
7671 CursorVisitor AnnotateVis;
7672 SourceManager &SrcMgr;
7673 bool HasContextSensitiveKeywords;
7675 struct PostChildrenAction {
7676 CXCursor cursor;
7677 enum Action { Invalid, Ignore, Postpone } action;
7679 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
7681 struct PostChildrenInfo {
7682 CXCursor Cursor;
7683 SourceRange CursorRange;
7684 unsigned BeforeReachingCursorIdx;
7685 unsigned BeforeChildrenTokenIdx;
7686 PostChildrenActions ChildActions;
7688 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
7690 CXToken &getTok(unsigned Idx) {
7691 assert(Idx < NumTokens);
7692 return Tokens[Idx];
7694 const CXToken &getTok(unsigned Idx) const {
7695 assert(Idx < NumTokens);
7696 return Tokens[Idx];
7698 bool MoreTokens() const { return TokIdx < NumTokens; }
7699 unsigned NextToken() const { return TokIdx; }
7700 void AdvanceToken() { ++TokIdx; }
7701 SourceLocation GetTokenLoc(unsigned tokI) {
7702 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
7704 bool isFunctionMacroToken(unsigned tokI) const {
7705 return getTok(tokI).int_data[3] != 0;
7707 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
7708 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
7711 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
7712 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
7713 SourceRange);
7715 public:
7716 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
7717 CXTranslationUnit TU, SourceRange RegionOfInterest)
7718 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
7719 PreprocessingTokIdx(0),
7720 AnnotateVis(TU, AnnotateTokensVisitor, this,
7721 /*VisitPreprocessorLast=*/true,
7722 /*VisitIncludedEntities=*/false, RegionOfInterest,
7723 /*VisitDeclsOnly=*/false,
7724 AnnotateTokensPostChildrenVisitor),
7725 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
7726 HasContextSensitiveKeywords(false) {}
7728 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
7729 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
7730 bool IsIgnoredChildCursor(CXCursor cursor) const;
7731 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
7733 bool postVisitChildren(CXCursor cursor);
7734 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
7735 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
7737 void AnnotateTokens();
7739 /// Determine whether the annotator saw any cursors that have
7740 /// context-sensitive keywords.
7741 bool hasContextSensitiveKeywords() const {
7742 return HasContextSensitiveKeywords;
7745 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
7747 } // namespace
7749 void AnnotateTokensWorker::AnnotateTokens() {
7750 // Walk the AST within the region of interest, annotating tokens
7751 // along the way.
7752 AnnotateVis.visitFileRegion();
7755 bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7756 if (PostChildrenInfos.empty())
7757 return false;
7759 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7760 if (ChildAction.cursor == cursor &&
7761 ChildAction.action == PostChildrenAction::Ignore) {
7762 return true;
7766 return false;
7769 const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7770 if (!clang_isExpression(Cursor.kind))
7771 return nullptr;
7773 const Expr *E = getCursorExpr(Cursor);
7774 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7775 const OverloadedOperatorKind Kind = OCE->getOperator();
7776 if (Kind == OO_Call || Kind == OO_Subscript)
7777 return OCE;
7780 return nullptr;
7783 AnnotateTokensWorker::PostChildrenActions
7784 AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7785 PostChildrenActions actions;
7787 // The DeclRefExpr of CXXOperatorCallExpr referring to the custom operator is
7788 // visited before the arguments to the operator call. For the Call and
7789 // Subscript operator the range of this DeclRefExpr includes the whole call
7790 // expression, so that all tokens in that range would be mapped to the
7791 // operator function, including the tokens of the arguments. To avoid that,
7792 // ensure to visit this DeclRefExpr as last node.
7793 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7794 const Expr *Callee = OCE->getCallee();
7795 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7796 const Expr *SubExpr = ICE->getSubExpr();
7797 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
7798 const Decl *parentDecl = getCursorDecl(Cursor);
7799 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7801 // Visit the DeclRefExpr as last.
7802 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7803 actions.push_back({cxChild, PostChildrenAction::Postpone});
7805 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7806 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7807 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7808 actions.push_back({cxChild, PostChildrenAction::Ignore});
7813 return actions;
7816 static inline void updateCursorAnnotation(CXCursor &Cursor,
7817 const CXCursor &updateC) {
7818 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
7819 return;
7820 Cursor = updateC;
7823 /// It annotates and advances tokens with a cursor until the comparison
7824 //// between the cursor location and the source range is the same as
7825 /// \arg compResult.
7827 /// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7828 /// Pass RangeOverlap to annotate tokens inside a range.
7829 void AnnotateTokensWorker::annotateAndAdvanceTokens(
7830 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
7831 while (MoreTokens()) {
7832 const unsigned I = NextToken();
7833 if (isFunctionMacroToken(I))
7834 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7835 return;
7837 SourceLocation TokLoc = GetTokenLoc(I);
7838 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7839 updateCursorAnnotation(Cursors[I], updateC);
7840 AdvanceToken();
7841 continue;
7843 break;
7847 /// Special annotation handling for macro argument tokens.
7848 /// \returns true if it advanced beyond all macro tokens, false otherwise.
7849 bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
7850 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
7851 assert(MoreTokens());
7852 assert(isFunctionMacroToken(NextToken()) &&
7853 "Should be called only for macro arg tokens");
7855 // This works differently than annotateAndAdvanceTokens; because expanded
7856 // macro arguments can have arbitrary translation-unit source order, we do not
7857 // advance the token index one by one until a token fails the range test.
7858 // We only advance once past all of the macro arg tokens if all of them
7859 // pass the range test. If one of them fails we keep the token index pointing
7860 // at the start of the macro arg tokens so that the failing token will be
7861 // annotated by a subsequent annotation try.
7863 bool atLeastOneCompFail = false;
7865 unsigned I = NextToken();
7866 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7867 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7868 if (TokLoc.isFileID())
7869 continue; // not macro arg token, it's parens or comma.
7870 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7871 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7872 Cursors[I] = updateC;
7873 } else
7874 atLeastOneCompFail = true;
7877 if (atLeastOneCompFail)
7878 return false;
7880 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7881 return true;
7884 enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7885 CXCursor parent) {
7886 SourceRange cursorRange = getRawCursorExtent(cursor);
7887 if (cursorRange.isInvalid())
7888 return CXChildVisit_Recurse;
7890 if (IsIgnoredChildCursor(cursor))
7891 return CXChildVisit_Continue;
7893 if (!HasContextSensitiveKeywords) {
7894 // Objective-C properties can have context-sensitive keywords.
7895 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
7896 if (const ObjCPropertyDecl *Property =
7897 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7898 HasContextSensitiveKeywords =
7899 Property->getPropertyAttributesAsWritten() != 0;
7901 // Objective-C methods can have context-sensitive keywords.
7902 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7903 cursor.kind == CXCursor_ObjCClassMethodDecl) {
7904 if (const ObjCMethodDecl *Method =
7905 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
7906 if (Method->getObjCDeclQualifier())
7907 HasContextSensitiveKeywords = true;
7908 else {
7909 for (const auto *P : Method->parameters()) {
7910 if (P->getObjCDeclQualifier()) {
7911 HasContextSensitiveKeywords = true;
7912 break;
7918 // C++ methods can have context-sensitive keywords.
7919 else if (cursor.kind == CXCursor_CXXMethod) {
7920 if (const CXXMethodDecl *Method =
7921 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
7922 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7923 HasContextSensitiveKeywords = true;
7926 // C++ classes can have context-sensitive keywords.
7927 else if (cursor.kind == CXCursor_StructDecl ||
7928 cursor.kind == CXCursor_ClassDecl ||
7929 cursor.kind == CXCursor_ClassTemplate ||
7930 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
7931 if (const Decl *D = getCursorDecl(cursor))
7932 if (D->hasAttr<FinalAttr>())
7933 HasContextSensitiveKeywords = true;
7937 // Don't override a property annotation with its getter/setter method.
7938 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7939 parent.kind == CXCursor_ObjCPropertyDecl)
7940 return CXChildVisit_Continue;
7942 if (clang_isPreprocessing(cursor.kind)) {
7943 // Items in the preprocessing record are kept separate from items in
7944 // declarations, so we keep a separate token index.
7945 unsigned SavedTokIdx = TokIdx;
7946 TokIdx = PreprocessingTokIdx;
7948 // Skip tokens up until we catch up to the beginning of the preprocessing
7949 // entry.
7950 while (MoreTokens()) {
7951 const unsigned I = NextToken();
7952 SourceLocation TokLoc = GetTokenLoc(I);
7953 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7954 case RangeBefore:
7955 AdvanceToken();
7956 continue;
7957 case RangeAfter:
7958 case RangeOverlap:
7959 break;
7961 break;
7964 // Look at all of the tokens within this range.
7965 while (MoreTokens()) {
7966 const unsigned I = NextToken();
7967 SourceLocation TokLoc = GetTokenLoc(I);
7968 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7969 case RangeBefore:
7970 llvm_unreachable("Infeasible");
7971 case RangeAfter:
7972 break;
7973 case RangeOverlap:
7974 // For macro expansions, just note where the beginning of the macro
7975 // expansion occurs.
7976 if (cursor.kind == CXCursor_MacroExpansion) {
7977 if (TokLoc == cursorRange.getBegin())
7978 Cursors[I] = cursor;
7979 AdvanceToken();
7980 break;
7982 // We may have already annotated macro names inside macro definitions.
7983 if (Cursors[I].kind != CXCursor_MacroExpansion)
7984 Cursors[I] = cursor;
7985 AdvanceToken();
7986 continue;
7988 break;
7991 // Save the preprocessing token index; restore the non-preprocessing
7992 // token index.
7993 PreprocessingTokIdx = TokIdx;
7994 TokIdx = SavedTokIdx;
7995 return CXChildVisit_Recurse;
7998 if (cursorRange.isInvalid())
7999 return CXChildVisit_Continue;
8001 unsigned BeforeReachingCursorIdx = NextToken();
8002 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
8003 const enum CXCursorKind K = clang_getCursorKind(parent);
8004 const CXCursor updateC =
8005 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
8006 // Attributes are annotated out-of-order, skip tokens until we reach it.
8007 clang_isAttribute(cursor.kind))
8008 ? clang_getNullCursor()
8009 : parent;
8011 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
8013 // Avoid having the cursor of an expression "overwrite" the annotation of the
8014 // variable declaration that it belongs to.
8015 // This can happen for C++ constructor expressions whose range generally
8016 // include the variable declaration, e.g.:
8017 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
8018 if (clang_isExpression(cursorK) && MoreTokens()) {
8019 const Expr *E = getCursorExpr(cursor);
8020 if (const Decl *D = getCursorDecl(cursor)) {
8021 const unsigned I = NextToken();
8022 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
8023 E->getBeginLoc() == D->getLocation() &&
8024 E->getBeginLoc() == GetTokenLoc(I)) {
8025 updateCursorAnnotation(Cursors[I], updateC);
8026 AdvanceToken();
8031 // Before recursing into the children keep some state that we are going
8032 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
8033 // extra work after the child nodes are visited.
8034 // Note that we don't call VisitChildren here to avoid traversing statements
8035 // code-recursively which can blow the stack.
8037 PostChildrenInfo Info;
8038 Info.Cursor = cursor;
8039 Info.CursorRange = cursorRange;
8040 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
8041 Info.BeforeChildrenTokenIdx = NextToken();
8042 Info.ChildActions = DetermineChildActions(cursor);
8043 PostChildrenInfos.push_back(Info);
8045 return CXChildVisit_Recurse;
8048 bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
8049 if (PostChildrenInfos.empty())
8050 return false;
8051 const PostChildrenInfo &Info = PostChildrenInfos.back();
8052 if (!clang_equalCursors(Info.Cursor, cursor))
8053 return false;
8055 HandlePostPonedChildCursors(Info);
8057 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
8058 const unsigned AfterChildren = NextToken();
8059 SourceRange cursorRange = Info.CursorRange;
8061 // Scan the tokens that are at the end of the cursor, but are not captured
8062 // but the child cursors.
8063 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
8065 // Scan the tokens that are at the beginning of the cursor, but are not
8066 // capture by the child cursors.
8067 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
8068 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
8069 break;
8071 Cursors[I] = cursor;
8074 // Attributes are annotated out-of-order, rewind TokIdx to when we first
8075 // encountered the attribute cursor.
8076 if (clang_isAttribute(cursor.kind))
8077 TokIdx = Info.BeforeReachingCursorIdx;
8079 PostChildrenInfos.pop_back();
8080 return false;
8083 void AnnotateTokensWorker::HandlePostPonedChildCursors(
8084 const PostChildrenInfo &Info) {
8085 for (const auto &ChildAction : Info.ChildActions) {
8086 if (ChildAction.action == PostChildrenAction::Postpone) {
8087 HandlePostPonedChildCursor(ChildAction.cursor,
8088 Info.BeforeChildrenTokenIdx);
8093 void AnnotateTokensWorker::HandlePostPonedChildCursor(
8094 CXCursor Cursor, unsigned StartTokenIndex) {
8095 unsigned I = StartTokenIndex;
8097 // The bracket tokens of a Call or Subscript operator are mapped to
8098 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
8099 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
8100 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
8101 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
8102 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
8103 if (clang_Range_isNull(CXRefNameRange))
8104 break; // All ranges handled.
8106 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
8107 while (I < NumTokens) {
8108 const SourceLocation TokenLocation = GetTokenLoc(I);
8109 if (!TokenLocation.isValid())
8110 break;
8112 // Adapt the end range, because LocationCompare() reports
8113 // RangeOverlap even for the not-inclusive end location.
8114 const SourceLocation fixedEnd =
8115 RefNameRange.getEnd().getLocWithOffset(-1);
8116 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
8118 const RangeComparisonResult ComparisonResult =
8119 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
8121 if (ComparisonResult == RangeOverlap) {
8122 Cursors[I++] = Cursor;
8123 } else if (ComparisonResult == RangeBefore) {
8124 ++I; // Not relevant token, check next one.
8125 } else if (ComparisonResult == RangeAfter) {
8126 break; // All tokens updated for current range, check next.
8132 static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
8133 CXCursor parent,
8134 CXClientData client_data) {
8135 return static_cast<AnnotateTokensWorker *>(client_data)
8136 ->Visit(cursor, parent);
8139 static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
8140 CXClientData client_data) {
8141 return static_cast<AnnotateTokensWorker *>(client_data)
8142 ->postVisitChildren(cursor);
8145 namespace {
8147 /// Uses the macro expansions in the preprocessing record to find
8148 /// and mark tokens that are macro arguments. This info is used by the
8149 /// AnnotateTokensWorker.
8150 class MarkMacroArgTokensVisitor {
8151 SourceManager &SM;
8152 CXToken *Tokens;
8153 unsigned NumTokens;
8154 unsigned CurIdx;
8156 public:
8157 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
8158 unsigned numTokens)
8159 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
8161 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
8162 if (cursor.kind != CXCursor_MacroExpansion)
8163 return CXChildVisit_Continue;
8165 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
8166 if (macroRange.getBegin() == macroRange.getEnd())
8167 return CXChildVisit_Continue; // it's not a function macro.
8169 for (; CurIdx < NumTokens; ++CurIdx) {
8170 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
8171 macroRange.getBegin()))
8172 break;
8175 if (CurIdx == NumTokens)
8176 return CXChildVisit_Break;
8178 for (; CurIdx < NumTokens; ++CurIdx) {
8179 SourceLocation tokLoc = getTokenLoc(CurIdx);
8180 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
8181 break;
8183 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
8186 if (CurIdx == NumTokens)
8187 return CXChildVisit_Break;
8189 return CXChildVisit_Continue;
8192 private:
8193 CXToken &getTok(unsigned Idx) {
8194 assert(Idx < NumTokens);
8195 return Tokens[Idx];
8197 const CXToken &getTok(unsigned Idx) const {
8198 assert(Idx < NumTokens);
8199 return Tokens[Idx];
8202 SourceLocation getTokenLoc(unsigned tokI) {
8203 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
8206 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
8207 // The third field is reserved and currently not used. Use it here
8208 // to mark macro arg expanded tokens with their expanded locations.
8209 getTok(tokI).int_data[3] = loc.getRawEncoding();
8213 } // end anonymous namespace
8215 static CXChildVisitResult
8216 MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
8217 CXClientData client_data) {
8218 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
8219 ->visit(cursor, parent);
8222 /// Used by \c annotatePreprocessorTokens.
8223 /// \returns true if lexing was finished, false otherwise.
8224 static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
8225 unsigned NumTokens) {
8226 if (NextIdx >= NumTokens)
8227 return true;
8229 ++NextIdx;
8230 Lex.LexFromRawLexer(Tok);
8231 return Tok.is(tok::eof);
8234 static void annotatePreprocessorTokens(CXTranslationUnit TU,
8235 SourceRange RegionOfInterest,
8236 CXCursor *Cursors, CXToken *Tokens,
8237 unsigned NumTokens) {
8238 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
8240 Preprocessor &PP = CXXUnit->getPreprocessor();
8241 SourceManager &SourceMgr = CXXUnit->getSourceManager();
8242 std::pair<FileID, unsigned> BeginLocInfo =
8243 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
8244 std::pair<FileID, unsigned> EndLocInfo =
8245 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
8247 if (BeginLocInfo.first != EndLocInfo.first)
8248 return;
8250 StringRef Buffer;
8251 bool Invalid = false;
8252 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
8253 if (Buffer.empty() || Invalid)
8254 return;
8256 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
8257 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
8258 Buffer.data() + BeginLocInfo.second, Buffer.end());
8259 Lex.SetCommentRetentionState(true);
8261 unsigned NextIdx = 0;
8262 // Lex tokens in raw mode until we hit the end of the range, to avoid
8263 // entering #includes or expanding macros.
8264 while (true) {
8265 Token Tok;
8266 if (lexNext(Lex, Tok, NextIdx, NumTokens))
8267 break;
8268 unsigned TokIdx = NextIdx - 1;
8269 assert(Tok.getLocation() ==
8270 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
8272 reprocess:
8273 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
8274 // We have found a preprocessing directive. Annotate the tokens
8275 // appropriately.
8277 // FIXME: Some simple tests here could identify macro definitions and
8278 // #undefs, to provide specific cursor kinds for those.
8280 SourceLocation BeginLoc = Tok.getLocation();
8281 if (lexNext(Lex, Tok, NextIdx, NumTokens))
8282 break;
8284 MacroInfo *MI = nullptr;
8285 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
8286 if (lexNext(Lex, Tok, NextIdx, NumTokens))
8287 break;
8289 if (Tok.is(tok::raw_identifier)) {
8290 IdentifierInfo &II =
8291 PP.getIdentifierTable().get(Tok.getRawIdentifier());
8292 SourceLocation MappedTokLoc =
8293 CXXUnit->mapLocationToPreamble(Tok.getLocation());
8294 MI = getMacroInfo(II, MappedTokLoc, TU);
8298 bool finished = false;
8299 do {
8300 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
8301 finished = true;
8302 break;
8304 // If we are in a macro definition, check if the token was ever a
8305 // macro name and annotate it if that's the case.
8306 if (MI) {
8307 SourceLocation SaveLoc = Tok.getLocation();
8308 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
8309 MacroDefinitionRecord *MacroDef =
8310 checkForMacroInMacroDefinition(MI, Tok, TU);
8311 Tok.setLocation(SaveLoc);
8312 if (MacroDef)
8313 Cursors[NextIdx - 1] =
8314 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
8316 } while (!Tok.isAtStartOfLine());
8318 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
8319 assert(TokIdx <= LastIdx);
8320 SourceLocation EndLoc =
8321 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
8322 CXCursor Cursor =
8323 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
8325 for (; TokIdx <= LastIdx; ++TokIdx)
8326 updateCursorAnnotation(Cursors[TokIdx], Cursor);
8328 if (finished)
8329 break;
8330 goto reprocess;
8335 // This gets run a separate thread to avoid stack blowout.
8336 static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
8337 CXToken *Tokens, unsigned NumTokens,
8338 CXCursor *Cursors) {
8339 CIndexer *CXXIdx = TU->CIdx;
8340 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
8341 setThreadBackgroundPriority();
8343 // Determine the region of interest, which contains all of the tokens.
8344 SourceRange RegionOfInterest;
8345 RegionOfInterest.setBegin(
8346 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
8347 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
8348 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
8350 // Relex the tokens within the source range to look for preprocessing
8351 // directives.
8352 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
8354 // If begin location points inside a macro argument, set it to the expansion
8355 // location so we can have the full context when annotating semantically.
8357 SourceManager &SM = CXXUnit->getSourceManager();
8358 SourceLocation Loc =
8359 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
8360 if (Loc.isMacroID())
8361 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
8364 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
8365 // Search and mark tokens that are macro argument expansions.
8366 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
8367 NumTokens);
8368 CursorVisitor MacroArgMarker(
8369 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
8370 /*VisitPreprocessorLast=*/true,
8371 /*VisitIncludedEntities=*/false, RegionOfInterest);
8372 MacroArgMarker.visitPreprocessedEntitiesInRegion();
8375 // Annotate all of the source locations in the region of interest that map to
8376 // a specific cursor.
8377 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
8379 // FIXME: We use a ridiculous stack size here because the data-recursion
8380 // algorithm uses a large stack frame than the non-data recursive version,
8381 // and AnnotationTokensWorker currently transforms the data-recursion
8382 // algorithm back into a traditional recursion by explicitly calling
8383 // VisitChildren(). We will need to remove this explicit recursive call.
8384 W.AnnotateTokens();
8386 // If we ran into any entities that involve context-sensitive keywords,
8387 // take another pass through the tokens to mark them as such.
8388 if (W.hasContextSensitiveKeywords()) {
8389 for (unsigned I = 0; I != NumTokens; ++I) {
8390 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
8391 continue;
8393 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
8394 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
8395 if (const ObjCPropertyDecl *Property =
8396 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
8397 if (Property->getPropertyAttributesAsWritten() != 0 &&
8398 llvm::StringSwitch<bool>(II->getName())
8399 .Case("readonly", true)
8400 .Case("assign", true)
8401 .Case("unsafe_unretained", true)
8402 .Case("readwrite", true)
8403 .Case("retain", true)
8404 .Case("copy", true)
8405 .Case("nonatomic", true)
8406 .Case("atomic", true)
8407 .Case("getter", true)
8408 .Case("setter", true)
8409 .Case("strong", true)
8410 .Case("weak", true)
8411 .Case("class", true)
8412 .Default(false))
8413 Tokens[I].int_data[0] = CXToken_Keyword;
8415 continue;
8418 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
8419 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
8420 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
8421 if (llvm::StringSwitch<bool>(II->getName())
8422 .Case("in", true)
8423 .Case("out", true)
8424 .Case("inout", true)
8425 .Case("oneway", true)
8426 .Case("bycopy", true)
8427 .Case("byref", true)
8428 .Default(false))
8429 Tokens[I].int_data[0] = CXToken_Keyword;
8430 continue;
8433 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
8434 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
8435 Tokens[I].int_data[0] = CXToken_Keyword;
8436 continue;
8442 void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
8443 unsigned NumTokens, CXCursor *Cursors) {
8444 if (isNotUsableTU(TU)) {
8445 LOG_BAD_TU(TU);
8446 return;
8448 if (NumTokens == 0 || !Tokens || !Cursors) {
8449 LOG_FUNC_SECTION { *Log << "<null input>"; }
8450 return;
8453 LOG_FUNC_SECTION {
8454 *Log << TU << ' ';
8455 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
8456 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
8457 *Log << clang_getRange(bloc, eloc);
8460 // Any token we don't specifically annotate will have a NULL cursor.
8461 CXCursor C = clang_getNullCursor();
8462 for (unsigned I = 0; I != NumTokens; ++I)
8463 Cursors[I] = C;
8465 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
8466 if (!CXXUnit)
8467 return;
8469 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
8471 auto AnnotateTokensImpl = [=]() {
8472 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
8474 llvm::CrashRecoveryContext CRC;
8475 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
8476 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
8480 //===----------------------------------------------------------------------===//
8481 // Operations for querying linkage of a cursor.
8482 //===----------------------------------------------------------------------===//
8484 CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
8485 if (!clang_isDeclaration(cursor.kind))
8486 return CXLinkage_Invalid;
8488 const Decl *D = cxcursor::getCursorDecl(cursor);
8489 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
8490 switch (ND->getLinkageInternal()) {
8491 case Linkage::Invalid:
8492 return CXLinkage_Invalid;
8493 case Linkage::None:
8494 case Linkage::VisibleNone:
8495 return CXLinkage_NoLinkage;
8496 case Linkage::Internal:
8497 return CXLinkage_Internal;
8498 case Linkage::UniqueExternal:
8499 return CXLinkage_UniqueExternal;
8500 case Linkage::Module:
8501 case Linkage::External:
8502 return CXLinkage_External;
8505 return CXLinkage_Invalid;
8508 //===----------------------------------------------------------------------===//
8509 // Operations for querying visibility of a cursor.
8510 //===----------------------------------------------------------------------===//
8512 CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
8513 if (!clang_isDeclaration(cursor.kind))
8514 return CXVisibility_Invalid;
8516 const Decl *D = cxcursor::getCursorDecl(cursor);
8517 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
8518 switch (ND->getVisibility()) {
8519 case HiddenVisibility:
8520 return CXVisibility_Hidden;
8521 case ProtectedVisibility:
8522 return CXVisibility_Protected;
8523 case DefaultVisibility:
8524 return CXVisibility_Default;
8527 return CXVisibility_Invalid;
8530 //===----------------------------------------------------------------------===//
8531 // Operations for querying language of a cursor.
8532 //===----------------------------------------------------------------------===//
8534 static CXLanguageKind getDeclLanguage(const Decl *D) {
8535 if (!D)
8536 return CXLanguage_C;
8538 switch (D->getKind()) {
8539 default:
8540 break;
8541 case Decl::ImplicitParam:
8542 case Decl::ObjCAtDefsField:
8543 case Decl::ObjCCategory:
8544 case Decl::ObjCCategoryImpl:
8545 case Decl::ObjCCompatibleAlias:
8546 case Decl::ObjCImplementation:
8547 case Decl::ObjCInterface:
8548 case Decl::ObjCIvar:
8549 case Decl::ObjCMethod:
8550 case Decl::ObjCProperty:
8551 case Decl::ObjCPropertyImpl:
8552 case Decl::ObjCProtocol:
8553 case Decl::ObjCTypeParam:
8554 return CXLanguage_ObjC;
8555 case Decl::CXXConstructor:
8556 case Decl::CXXConversion:
8557 case Decl::CXXDestructor:
8558 case Decl::CXXMethod:
8559 case Decl::CXXRecord:
8560 case Decl::ClassTemplate:
8561 case Decl::ClassTemplatePartialSpecialization:
8562 case Decl::ClassTemplateSpecialization:
8563 case Decl::Friend:
8564 case Decl::FriendTemplate:
8565 case Decl::FunctionTemplate:
8566 case Decl::LinkageSpec:
8567 case Decl::Namespace:
8568 case Decl::NamespaceAlias:
8569 case Decl::NonTypeTemplateParm:
8570 case Decl::StaticAssert:
8571 case Decl::TemplateTemplateParm:
8572 case Decl::TemplateTypeParm:
8573 case Decl::UnresolvedUsingTypename:
8574 case Decl::UnresolvedUsingValue:
8575 case Decl::Using:
8576 case Decl::UsingDirective:
8577 case Decl::UsingShadow:
8578 return CXLanguage_CPlusPlus;
8581 return CXLanguage_C;
8584 static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
8585 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
8586 return CXAvailability_NotAvailable;
8588 switch (D->getAvailability()) {
8589 case AR_Available:
8590 case AR_NotYetIntroduced:
8591 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
8592 return getCursorAvailabilityForDecl(
8593 cast<Decl>(EnumConst->getDeclContext()));
8594 return CXAvailability_Available;
8596 case AR_Deprecated:
8597 return CXAvailability_Deprecated;
8599 case AR_Unavailable:
8600 return CXAvailability_NotAvailable;
8603 llvm_unreachable("Unknown availability kind!");
8606 enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
8607 if (clang_isDeclaration(cursor.kind))
8608 if (const Decl *D = cxcursor::getCursorDecl(cursor))
8609 return getCursorAvailabilityForDecl(D);
8611 return CXAvailability_Available;
8614 static CXVersion convertVersion(VersionTuple In) {
8615 CXVersion Out = {-1, -1, -1};
8616 if (In.empty())
8617 return Out;
8619 Out.Major = In.getMajor();
8621 std::optional<unsigned> Minor = In.getMinor();
8622 if (Minor)
8623 Out.Minor = *Minor;
8624 else
8625 return Out;
8627 std::optional<unsigned> Subminor = In.getSubminor();
8628 if (Subminor)
8629 Out.Subminor = *Subminor;
8631 return Out;
8634 static void getCursorPlatformAvailabilityForDecl(
8635 const Decl *D, int *always_deprecated, CXString *deprecated_message,
8636 int *always_unavailable, CXString *unavailable_message,
8637 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
8638 bool HadAvailAttr = false;
8639 for (auto A : D->attrs()) {
8640 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
8641 HadAvailAttr = true;
8642 if (always_deprecated)
8643 *always_deprecated = 1;
8644 if (deprecated_message) {
8645 clang_disposeString(*deprecated_message);
8646 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
8648 continue;
8651 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
8652 HadAvailAttr = true;
8653 if (always_unavailable)
8654 *always_unavailable = 1;
8655 if (unavailable_message) {
8656 clang_disposeString(*unavailable_message);
8657 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
8659 continue;
8662 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
8663 AvailabilityAttrs.push_back(Avail);
8664 HadAvailAttr = true;
8668 if (!HadAvailAttr)
8669 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
8670 return getCursorPlatformAvailabilityForDecl(
8671 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
8672 deprecated_message, always_unavailable, unavailable_message,
8673 AvailabilityAttrs);
8675 // If no availability attributes are found, inherit the attribute from the
8676 // containing decl or the class or category interface decl.
8677 if (AvailabilityAttrs.empty()) {
8678 const ObjCContainerDecl *CD = nullptr;
8679 const DeclContext *DC = D->getDeclContext();
8681 if (auto *IMD = dyn_cast<ObjCImplementationDecl>(D))
8682 CD = IMD->getClassInterface();
8683 else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D))
8684 CD = CatD->getClassInterface();
8685 else if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(D))
8686 CD = IMD->getCategoryDecl();
8687 else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(DC))
8688 CD = ID;
8689 else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(DC))
8690 CD = CatD;
8691 else if (auto *IMD = dyn_cast<ObjCImplementationDecl>(DC))
8692 CD = IMD->getClassInterface();
8693 else if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(DC))
8694 CD = IMD->getCategoryDecl();
8695 else if (auto *PD = dyn_cast<ObjCProtocolDecl>(DC))
8696 CD = PD;
8698 if (CD)
8699 getCursorPlatformAvailabilityForDecl(
8700 CD, always_deprecated, deprecated_message, always_unavailable,
8701 unavailable_message, AvailabilityAttrs);
8702 return;
8705 llvm::sort(
8706 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
8707 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
8709 ASTContext &Ctx = D->getASTContext();
8710 auto It = std::unique(
8711 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
8712 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
8713 if (LHS->getPlatform() != RHS->getPlatform())
8714 return false;
8716 if (LHS->getIntroduced() == RHS->getIntroduced() &&
8717 LHS->getDeprecated() == RHS->getDeprecated() &&
8718 LHS->getObsoleted() == RHS->getObsoleted() &&
8719 LHS->getMessage() == RHS->getMessage() &&
8720 LHS->getReplacement() == RHS->getReplacement())
8721 return true;
8723 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
8724 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
8725 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
8726 return false;
8728 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
8729 LHS->setIntroduced(Ctx, RHS->getIntroduced());
8731 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
8732 LHS->setDeprecated(Ctx, RHS->getDeprecated());
8733 if (LHS->getMessage().empty())
8734 LHS->setMessage(Ctx, RHS->getMessage());
8735 if (LHS->getReplacement().empty())
8736 LHS->setReplacement(Ctx, RHS->getReplacement());
8739 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
8740 LHS->setObsoleted(Ctx, RHS->getObsoleted());
8741 if (LHS->getMessage().empty())
8742 LHS->setMessage(Ctx, RHS->getMessage());
8743 if (LHS->getReplacement().empty())
8744 LHS->setReplacement(Ctx, RHS->getReplacement());
8747 return true;
8749 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
8752 int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
8753 CXString *deprecated_message,
8754 int *always_unavailable,
8755 CXString *unavailable_message,
8756 CXPlatformAvailability *availability,
8757 int availability_size) {
8758 if (always_deprecated)
8759 *always_deprecated = 0;
8760 if (deprecated_message)
8761 *deprecated_message = cxstring::createEmpty();
8762 if (always_unavailable)
8763 *always_unavailable = 0;
8764 if (unavailable_message)
8765 *unavailable_message = cxstring::createEmpty();
8767 if (!clang_isDeclaration(cursor.kind))
8768 return 0;
8770 const Decl *D = cxcursor::getCursorDecl(cursor);
8771 if (!D)
8772 return 0;
8774 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
8775 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8776 always_unavailable, unavailable_message,
8777 AvailabilityAttrs);
8778 for (const auto &Avail : llvm::enumerate(
8779 llvm::ArrayRef(AvailabilityAttrs).take_front(availability_size))) {
8780 availability[Avail.index()].Platform =
8781 cxstring::createDup(Avail.value()->getPlatform()->getName());
8782 availability[Avail.index()].Introduced =
8783 convertVersion(Avail.value()->getIntroduced());
8784 availability[Avail.index()].Deprecated =
8785 convertVersion(Avail.value()->getDeprecated());
8786 availability[Avail.index()].Obsoleted =
8787 convertVersion(Avail.value()->getObsoleted());
8788 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8789 availability[Avail.index()].Message =
8790 cxstring::createDup(Avail.value()->getMessage());
8793 return AvailabilityAttrs.size();
8796 void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8797 clang_disposeString(availability->Platform);
8798 clang_disposeString(availability->Message);
8801 CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8802 if (clang_isDeclaration(cursor.kind))
8803 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8805 return CXLanguage_Invalid;
8808 CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8809 const Decl *D = cxcursor::getCursorDecl(cursor);
8810 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8811 switch (VD->getTLSKind()) {
8812 case VarDecl::TLS_None:
8813 return CXTLS_None;
8814 case VarDecl::TLS_Dynamic:
8815 return CXTLS_Dynamic;
8816 case VarDecl::TLS_Static:
8817 return CXTLS_Static;
8821 return CXTLS_None;
8824 /// If the given cursor is the "templated" declaration
8825 /// describing a class or function template, return the class or
8826 /// function template.
8827 static const Decl *maybeGetTemplateCursor(const Decl *D) {
8828 if (!D)
8829 return nullptr;
8831 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8832 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8833 return FunTmpl;
8835 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
8836 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8837 return ClassTmpl;
8839 return D;
8842 enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8843 StorageClass sc = SC_None;
8844 const Decl *D = getCursorDecl(C);
8845 if (D) {
8846 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8847 sc = FD->getStorageClass();
8848 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8849 sc = VD->getStorageClass();
8850 } else {
8851 return CX_SC_Invalid;
8853 } else {
8854 return CX_SC_Invalid;
8856 switch (sc) {
8857 case SC_None:
8858 return CX_SC_None;
8859 case SC_Extern:
8860 return CX_SC_Extern;
8861 case SC_Static:
8862 return CX_SC_Static;
8863 case SC_PrivateExtern:
8864 return CX_SC_PrivateExtern;
8865 case SC_Auto:
8866 return CX_SC_Auto;
8867 case SC_Register:
8868 return CX_SC_Register;
8870 llvm_unreachable("Unhandled storage class!");
8873 CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8874 if (clang_isDeclaration(cursor.kind)) {
8875 if (const Decl *D = getCursorDecl(cursor)) {
8876 const DeclContext *DC = D->getDeclContext();
8877 if (!DC)
8878 return clang_getNullCursor();
8880 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
8881 getCursorTU(cursor));
8885 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
8886 if (const Decl *D = getCursorDecl(cursor))
8887 return MakeCXCursor(D, getCursorTU(cursor));
8890 return clang_getNullCursor();
8893 CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8894 if (clang_isDeclaration(cursor.kind)) {
8895 if (const Decl *D = getCursorDecl(cursor)) {
8896 const DeclContext *DC = D->getLexicalDeclContext();
8897 if (!DC)
8898 return clang_getNullCursor();
8900 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
8901 getCursorTU(cursor));
8905 // FIXME: Note that we can't easily compute the lexical context of a
8906 // statement or expression, so we return nothing.
8907 return clang_getNullCursor();
8910 CXFile clang_getIncludedFile(CXCursor cursor) {
8911 if (cursor.kind != CXCursor_InclusionDirective)
8912 return nullptr;
8914 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
8915 return cxfile::makeCXFile(ID->getFile());
8918 unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8919 if (C.kind != CXCursor_ObjCPropertyDecl)
8920 return CXObjCPropertyAttr_noattr;
8922 unsigned Result = CXObjCPropertyAttr_noattr;
8923 const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));
8924 ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
8926 #define SET_CXOBJCPROP_ATTR(A) \
8927 if (Attr & ObjCPropertyAttribute::kind_##A) \
8928 Result |= CXObjCPropertyAttr_##A
8929 SET_CXOBJCPROP_ATTR(readonly);
8930 SET_CXOBJCPROP_ATTR(getter);
8931 SET_CXOBJCPROP_ATTR(assign);
8932 SET_CXOBJCPROP_ATTR(readwrite);
8933 SET_CXOBJCPROP_ATTR(retain);
8934 SET_CXOBJCPROP_ATTR(copy);
8935 SET_CXOBJCPROP_ATTR(nonatomic);
8936 SET_CXOBJCPROP_ATTR(setter);
8937 SET_CXOBJCPROP_ATTR(atomic);
8938 SET_CXOBJCPROP_ATTR(weak);
8939 SET_CXOBJCPROP_ATTR(strong);
8940 SET_CXOBJCPROP_ATTR(unsafe_unretained);
8941 SET_CXOBJCPROP_ATTR(class);
8942 #undef SET_CXOBJCPROP_ATTR
8944 return Result;
8947 CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8948 if (C.kind != CXCursor_ObjCPropertyDecl)
8949 return cxstring::createNull();
8951 const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));
8952 Selector sel = PD->getGetterName();
8953 if (sel.isNull())
8954 return cxstring::createNull();
8956 return cxstring::createDup(sel.getAsString());
8959 CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8960 if (C.kind != CXCursor_ObjCPropertyDecl)
8961 return cxstring::createNull();
8963 const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));
8964 Selector sel = PD->getSetterName();
8965 if (sel.isNull())
8966 return cxstring::createNull();
8968 return cxstring::createDup(sel.getAsString());
8971 unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8972 if (!clang_isDeclaration(C.kind))
8973 return CXObjCDeclQualifier_None;
8975 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8976 const Decl *D = getCursorDecl(C);
8977 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8978 QT = MD->getObjCDeclQualifier();
8979 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8980 QT = PD->getObjCDeclQualifier();
8981 if (QT == Decl::OBJC_TQ_None)
8982 return CXObjCDeclQualifier_None;
8984 unsigned Result = CXObjCDeclQualifier_None;
8985 if (QT & Decl::OBJC_TQ_In)
8986 Result |= CXObjCDeclQualifier_In;
8987 if (QT & Decl::OBJC_TQ_Inout)
8988 Result |= CXObjCDeclQualifier_Inout;
8989 if (QT & Decl::OBJC_TQ_Out)
8990 Result |= CXObjCDeclQualifier_Out;
8991 if (QT & Decl::OBJC_TQ_Bycopy)
8992 Result |= CXObjCDeclQualifier_Bycopy;
8993 if (QT & Decl::OBJC_TQ_Byref)
8994 Result |= CXObjCDeclQualifier_Byref;
8995 if (QT & Decl::OBJC_TQ_Oneway)
8996 Result |= CXObjCDeclQualifier_Oneway;
8998 return Result;
9001 unsigned clang_Cursor_isObjCOptional(CXCursor C) {
9002 if (!clang_isDeclaration(C.kind))
9003 return 0;
9005 const Decl *D = getCursorDecl(C);
9006 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
9007 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
9008 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
9009 return MD->getImplementationControl() ==
9010 ObjCImplementationControl::Optional;
9012 return 0;
9015 unsigned clang_Cursor_isVariadic(CXCursor C) {
9016 if (!clang_isDeclaration(C.kind))
9017 return 0;
9019 const Decl *D = getCursorDecl(C);
9020 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
9021 return FD->isVariadic();
9022 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
9023 return MD->isVariadic();
9025 return 0;
9028 unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
9029 CXString *definedIn,
9030 unsigned *isGenerated) {
9031 if (!clang_isDeclaration(C.kind))
9032 return 0;
9034 const Decl *D = getCursorDecl(C);
9036 if (auto *attr = D->getExternalSourceSymbolAttr()) {
9037 if (language)
9038 *language = cxstring::createDup(attr->getLanguage());
9039 if (definedIn)
9040 *definedIn = cxstring::createDup(attr->getDefinedIn());
9041 if (isGenerated)
9042 *isGenerated = attr->getGeneratedDeclaration();
9043 return 1;
9045 return 0;
9048 enum CX_BinaryOperatorKind clang_Cursor_getBinaryOpcode(CXCursor C) {
9049 if (C.kind != CXCursor_BinaryOperator &&
9050 C.kind != CXCursor_CompoundAssignOperator) {
9051 return CX_BO_Invalid;
9054 const Expr *D = getCursorExpr(C);
9055 if (const auto *BinOp = dyn_cast<BinaryOperator>(D)) {
9056 switch (BinOp->getOpcode()) {
9057 #define BINARY_OPERATION(Name, Spelling) \
9058 case BO_##Name: \
9059 return CX_BO_##Name;
9060 #include "clang/AST/OperationKinds.def"
9064 return CX_BO_Invalid;
9067 CXString clang_Cursor_getBinaryOpcodeStr(enum CX_BinaryOperatorKind Op) {
9068 if (Op > CX_BO_LAST)
9069 return cxstring::createEmpty();
9071 return cxstring::createDup(
9072 // BinaryOperator::getOpcodeStr has no case for CX_BO_Invalid,
9073 // so subtract 1
9074 BinaryOperator::getOpcodeStr(static_cast<BinaryOperatorKind>(Op - 1)));
9077 CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
9078 if (!clang_isDeclaration(C.kind))
9079 return clang_getNullRange();
9081 const Decl *D = getCursorDecl(C);
9082 ASTContext &Context = getCursorContext(C);
9083 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
9084 if (!RC)
9085 return clang_getNullRange();
9087 return cxloc::translateSourceRange(Context, RC->getSourceRange());
9090 CXString clang_Cursor_getRawCommentText(CXCursor C) {
9091 if (!clang_isDeclaration(C.kind))
9092 return cxstring::createNull();
9094 const Decl *D = getCursorDecl(C);
9095 ASTContext &Context = getCursorContext(C);
9096 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
9097 StringRef RawText =
9098 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
9100 // Don't duplicate the string because RawText points directly into source
9101 // code.
9102 return cxstring::createRef(RawText);
9105 CXString clang_Cursor_getBriefCommentText(CXCursor C) {
9106 if (!clang_isDeclaration(C.kind))
9107 return cxstring::createNull();
9109 const Decl *D = getCursorDecl(C);
9110 const ASTContext &Context = getCursorContext(C);
9111 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
9113 if (RC) {
9114 StringRef BriefText = RC->getBriefText(Context);
9116 // Don't duplicate the string because RawComment ensures that this memory
9117 // will not go away.
9118 return cxstring::createRef(BriefText);
9121 return cxstring::createNull();
9124 CXModule clang_Cursor_getModule(CXCursor C) {
9125 if (C.kind == CXCursor_ModuleImportDecl) {
9126 if (const ImportDecl *ImportD =
9127 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
9128 return ImportD->getImportedModule();
9131 return nullptr;
9134 CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
9135 if (isNotUsableTU(TU)) {
9136 LOG_BAD_TU(TU);
9137 return nullptr;
9139 if (!File)
9140 return nullptr;
9141 FileEntryRef FE = *cxfile::getFileEntryRef(File);
9143 ASTUnit &Unit = *cxtu::getASTUnit(TU);
9144 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
9145 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
9147 return Header.getModule();
9150 CXFile clang_Module_getASTFile(CXModule CXMod) {
9151 if (!CXMod)
9152 return nullptr;
9153 Module *Mod = static_cast<Module *>(CXMod);
9154 return cxfile::makeCXFile(Mod->getASTFile());
9157 CXModule clang_Module_getParent(CXModule CXMod) {
9158 if (!CXMod)
9159 return nullptr;
9160 Module *Mod = static_cast<Module *>(CXMod);
9161 return Mod->Parent;
9164 CXString clang_Module_getName(CXModule CXMod) {
9165 if (!CXMod)
9166 return cxstring::createEmpty();
9167 Module *Mod = static_cast<Module *>(CXMod);
9168 return cxstring::createDup(Mod->Name);
9171 CXString clang_Module_getFullName(CXModule CXMod) {
9172 if (!CXMod)
9173 return cxstring::createEmpty();
9174 Module *Mod = static_cast<Module *>(CXMod);
9175 return cxstring::createDup(Mod->getFullModuleName());
9178 int clang_Module_isSystem(CXModule CXMod) {
9179 if (!CXMod)
9180 return 0;
9181 Module *Mod = static_cast<Module *>(CXMod);
9182 return Mod->IsSystem;
9185 unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
9186 CXModule CXMod) {
9187 if (isNotUsableTU(TU)) {
9188 LOG_BAD_TU(TU);
9189 return 0;
9191 if (!CXMod)
9192 return 0;
9193 Module *Mod = static_cast<Module *>(CXMod);
9194 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
9195 ArrayRef<FileEntryRef> TopHeaders = Mod->getTopHeaders(FileMgr);
9196 return TopHeaders.size();
9199 CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
9200 unsigned Index) {
9201 if (isNotUsableTU(TU)) {
9202 LOG_BAD_TU(TU);
9203 return nullptr;
9205 if (!CXMod)
9206 return nullptr;
9207 Module *Mod = static_cast<Module *>(CXMod);
9208 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
9210 ArrayRef<FileEntryRef> TopHeaders = Mod->getTopHeaders(FileMgr);
9211 if (Index < TopHeaders.size())
9212 return cxfile::makeCXFile(TopHeaders[Index]);
9214 return nullptr;
9217 //===----------------------------------------------------------------------===//
9218 // C++ AST instrospection.
9219 //===----------------------------------------------------------------------===//
9221 unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
9222 if (!clang_isDeclaration(C.kind))
9223 return 0;
9225 const Decl *D = cxcursor::getCursorDecl(C);
9226 const CXXConstructorDecl *Constructor =
9227 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
9228 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
9231 unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
9232 if (!clang_isDeclaration(C.kind))
9233 return 0;
9235 const Decl *D = cxcursor::getCursorDecl(C);
9236 const CXXConstructorDecl *Constructor =
9237 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
9238 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
9241 unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
9242 if (!clang_isDeclaration(C.kind))
9243 return 0;
9245 const Decl *D = cxcursor::getCursorDecl(C);
9246 const CXXConstructorDecl *Constructor =
9247 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
9248 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
9251 unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
9252 if (!clang_isDeclaration(C.kind))
9253 return 0;
9255 const Decl *D = cxcursor::getCursorDecl(C);
9256 const CXXConstructorDecl *Constructor =
9257 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
9258 // Passing 'false' excludes constructors marked 'explicit'.
9259 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
9262 unsigned clang_CXXField_isMutable(CXCursor C) {
9263 if (!clang_isDeclaration(C.kind))
9264 return 0;
9266 if (const auto D = cxcursor::getCursorDecl(C))
9267 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
9268 return FD->isMutable() ? 1 : 0;
9269 return 0;
9272 unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
9273 if (!clang_isDeclaration(C.kind))
9274 return 0;
9276 const Decl *D = cxcursor::getCursorDecl(C);
9277 const CXXMethodDecl *Method =
9278 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9279 return (Method && Method->isPureVirtual()) ? 1 : 0;
9282 unsigned clang_CXXMethod_isConst(CXCursor C) {
9283 if (!clang_isDeclaration(C.kind))
9284 return 0;
9286 const Decl *D = cxcursor::getCursorDecl(C);
9287 const CXXMethodDecl *Method =
9288 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9289 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
9292 unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
9293 if (!clang_isDeclaration(C.kind))
9294 return 0;
9296 const Decl *D = cxcursor::getCursorDecl(C);
9297 const CXXMethodDecl *Method =
9298 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9299 return (Method && Method->isDefaulted()) ? 1 : 0;
9302 unsigned clang_CXXMethod_isDeleted(CXCursor C) {
9303 if (!clang_isDeclaration(C.kind))
9304 return 0;
9306 const Decl *D = cxcursor::getCursorDecl(C);
9307 const CXXMethodDecl *Method =
9308 D ? dyn_cast_if_present<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9309 return (Method && Method->isDeleted()) ? 1 : 0;
9312 unsigned clang_CXXMethod_isStatic(CXCursor C) {
9313 if (!clang_isDeclaration(C.kind))
9314 return 0;
9316 const Decl *D = cxcursor::getCursorDecl(C);
9317 const CXXMethodDecl *Method =
9318 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9319 return (Method && Method->isStatic()) ? 1 : 0;
9322 unsigned clang_CXXMethod_isVirtual(CXCursor C) {
9323 if (!clang_isDeclaration(C.kind))
9324 return 0;
9326 const Decl *D = cxcursor::getCursorDecl(C);
9327 const CXXMethodDecl *Method =
9328 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9329 return (Method && Method->isVirtual()) ? 1 : 0;
9332 unsigned clang_CXXMethod_isCopyAssignmentOperator(CXCursor C) {
9333 if (!clang_isDeclaration(C.kind))
9334 return 0;
9336 const Decl *D = cxcursor::getCursorDecl(C);
9337 const CXXMethodDecl *Method =
9338 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9340 return (Method && Method->isCopyAssignmentOperator()) ? 1 : 0;
9343 unsigned clang_CXXMethod_isMoveAssignmentOperator(CXCursor C) {
9344 if (!clang_isDeclaration(C.kind))
9345 return 0;
9347 const Decl *D = cxcursor::getCursorDecl(C);
9348 const CXXMethodDecl *Method =
9349 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9351 return (Method && Method->isMoveAssignmentOperator()) ? 1 : 0;
9354 unsigned clang_CXXMethod_isExplicit(CXCursor C) {
9355 if (!clang_isDeclaration(C.kind))
9356 return 0;
9358 const Decl *D = cxcursor::getCursorDecl(C);
9359 const FunctionDecl *FD = D->getAsFunction();
9361 if (!FD)
9362 return 0;
9364 if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(FD))
9365 return Ctor->isExplicit();
9367 if (const auto *Conv = dyn_cast<CXXConversionDecl>(FD))
9368 return Conv->isExplicit();
9370 return 0;
9373 unsigned clang_CXXRecord_isAbstract(CXCursor C) {
9374 if (!clang_isDeclaration(C.kind))
9375 return 0;
9377 const auto *D = cxcursor::getCursorDecl(C);
9378 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
9379 if (RD)
9380 RD = RD->getDefinition();
9381 return (RD && RD->isAbstract()) ? 1 : 0;
9384 unsigned clang_EnumDecl_isScoped(CXCursor C) {
9385 if (!clang_isDeclaration(C.kind))
9386 return 0;
9388 const Decl *D = cxcursor::getCursorDecl(C);
9389 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
9390 return (Enum && Enum->isScoped()) ? 1 : 0;
9393 //===----------------------------------------------------------------------===//
9394 // Attribute introspection.
9395 //===----------------------------------------------------------------------===//
9397 CXType clang_getIBOutletCollectionType(CXCursor C) {
9398 if (C.kind != CXCursor_IBOutletCollectionAttr)
9399 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
9401 const IBOutletCollectionAttr *A =
9402 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
9404 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
9407 //===----------------------------------------------------------------------===//
9408 // Inspecting memory usage.
9409 //===----------------------------------------------------------------------===//
9411 typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
9413 static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
9414 enum CXTUResourceUsageKind k,
9415 unsigned long amount) {
9416 CXTUResourceUsageEntry entry = {k, amount};
9417 entries.push_back(entry);
9420 const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
9421 const char *str = "";
9422 switch (kind) {
9423 case CXTUResourceUsage_AST:
9424 str = "ASTContext: expressions, declarations, and types";
9425 break;
9426 case CXTUResourceUsage_Identifiers:
9427 str = "ASTContext: identifiers";
9428 break;
9429 case CXTUResourceUsage_Selectors:
9430 str = "ASTContext: selectors";
9431 break;
9432 case CXTUResourceUsage_GlobalCompletionResults:
9433 str = "Code completion: cached global results";
9434 break;
9435 case CXTUResourceUsage_SourceManagerContentCache:
9436 str = "SourceManager: content cache allocator";
9437 break;
9438 case CXTUResourceUsage_AST_SideTables:
9439 str = "ASTContext: side tables";
9440 break;
9441 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
9442 str = "SourceManager: malloc'ed memory buffers";
9443 break;
9444 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
9445 str = "SourceManager: mmap'ed memory buffers";
9446 break;
9447 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
9448 str = "ExternalASTSource: malloc'ed memory buffers";
9449 break;
9450 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
9451 str = "ExternalASTSource: mmap'ed memory buffers";
9452 break;
9453 case CXTUResourceUsage_Preprocessor:
9454 str = "Preprocessor: malloc'ed memory";
9455 break;
9456 case CXTUResourceUsage_PreprocessingRecord:
9457 str = "Preprocessor: PreprocessingRecord";
9458 break;
9459 case CXTUResourceUsage_SourceManager_DataStructures:
9460 str = "SourceManager: data structures and tables";
9461 break;
9462 case CXTUResourceUsage_Preprocessor_HeaderSearch:
9463 str = "Preprocessor: header search tables";
9464 break;
9466 return str;
9469 CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
9470 if (isNotUsableTU(TU)) {
9471 LOG_BAD_TU(TU);
9472 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
9473 return usage;
9476 ASTUnit *astUnit = cxtu::getASTUnit(TU);
9477 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
9478 ASTContext &astContext = astUnit->getASTContext();
9480 // How much memory is used by AST nodes and types?
9481 createCXTUResourceUsageEntry(
9482 *entries, CXTUResourceUsage_AST,
9483 (unsigned long)astContext.getASTAllocatedMemory());
9485 // How much memory is used by identifiers?
9486 createCXTUResourceUsageEntry(
9487 *entries, CXTUResourceUsage_Identifiers,
9488 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
9490 // How much memory is used for selectors?
9491 createCXTUResourceUsageEntry(
9492 *entries, CXTUResourceUsage_Selectors,
9493 (unsigned long)astContext.Selectors.getTotalMemory());
9495 // How much memory is used by ASTContext's side tables?
9496 createCXTUResourceUsageEntry(
9497 *entries, CXTUResourceUsage_AST_SideTables,
9498 (unsigned long)astContext.getSideTableAllocatedMemory());
9500 // How much memory is used for caching global code completion results?
9501 unsigned long completionBytes = 0;
9502 if (GlobalCodeCompletionAllocator *completionAllocator =
9503 astUnit->getCachedCompletionAllocator().get()) {
9504 completionBytes = completionAllocator->getTotalMemory();
9506 createCXTUResourceUsageEntry(
9507 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
9509 // How much memory is being used by SourceManager's content cache?
9510 createCXTUResourceUsageEntry(
9511 *entries, CXTUResourceUsage_SourceManagerContentCache,
9512 (unsigned long)astContext.getSourceManager().getContentCacheSize());
9514 // How much memory is being used by the MemoryBuffer's in SourceManager?
9515 const SourceManager::MemoryBufferSizes &srcBufs =
9516 astUnit->getSourceManager().getMemoryBufferSizes();
9518 createCXTUResourceUsageEntry(*entries,
9519 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
9520 (unsigned long)srcBufs.malloc_bytes);
9521 createCXTUResourceUsageEntry(*entries,
9522 CXTUResourceUsage_SourceManager_Membuffer_MMap,
9523 (unsigned long)srcBufs.mmap_bytes);
9524 createCXTUResourceUsageEntry(
9525 *entries, CXTUResourceUsage_SourceManager_DataStructures,
9526 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
9528 // How much memory is being used by the ExternalASTSource?
9529 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
9530 const ExternalASTSource::MemoryBufferSizes &sizes =
9531 esrc->getMemoryBufferSizes();
9533 createCXTUResourceUsageEntry(
9534 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
9535 (unsigned long)sizes.malloc_bytes);
9536 createCXTUResourceUsageEntry(
9537 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
9538 (unsigned long)sizes.mmap_bytes);
9541 // How much memory is being used by the Preprocessor?
9542 Preprocessor &pp = astUnit->getPreprocessor();
9543 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
9544 pp.getTotalMemory());
9546 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
9547 createCXTUResourceUsageEntry(*entries,
9548 CXTUResourceUsage_PreprocessingRecord,
9549 pRec->getTotalMemory());
9552 createCXTUResourceUsageEntry(*entries,
9553 CXTUResourceUsage_Preprocessor_HeaderSearch,
9554 pp.getHeaderSearchInfo().getTotalMemory());
9556 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
9557 !entries->empty() ? &(*entries)[0] : nullptr};
9558 (void)entries.release();
9559 return usage;
9562 void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
9563 if (usage.data)
9564 delete (MemUsageEntries *)usage.data;
9567 CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
9568 CXSourceRangeList *skipped = new CXSourceRangeList;
9569 skipped->count = 0;
9570 skipped->ranges = nullptr;
9572 if (isNotUsableTU(TU)) {
9573 LOG_BAD_TU(TU);
9574 return skipped;
9577 if (!file)
9578 return skipped;
9580 ASTUnit *astUnit = cxtu::getASTUnit(TU);
9581 PreprocessingRecord *ppRec =
9582 astUnit->getPreprocessor().getPreprocessingRecord();
9583 if (!ppRec)
9584 return skipped;
9586 ASTContext &Ctx = astUnit->getASTContext();
9587 SourceManager &sm = Ctx.getSourceManager();
9588 FileEntryRef fileEntry = *cxfile::getFileEntryRef(file);
9589 FileID wantedFileID = sm.translateFile(fileEntry);
9590 bool isMainFile = wantedFileID == sm.getMainFileID();
9592 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
9593 std::vector<SourceRange> wantedRanges;
9594 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
9595 ei = SkippedRanges.end();
9596 i != ei; ++i) {
9597 if (sm.getFileID(i->getBegin()) == wantedFileID ||
9598 sm.getFileID(i->getEnd()) == wantedFileID)
9599 wantedRanges.push_back(*i);
9600 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
9601 astUnit->isInPreambleFileID(i->getEnd())))
9602 wantedRanges.push_back(*i);
9605 skipped->count = wantedRanges.size();
9606 skipped->ranges = new CXSourceRange[skipped->count];
9607 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
9608 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
9610 return skipped;
9613 CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
9614 CXSourceRangeList *skipped = new CXSourceRangeList;
9615 skipped->count = 0;
9616 skipped->ranges = nullptr;
9618 if (isNotUsableTU(TU)) {
9619 LOG_BAD_TU(TU);
9620 return skipped;
9623 ASTUnit *astUnit = cxtu::getASTUnit(TU);
9624 PreprocessingRecord *ppRec =
9625 astUnit->getPreprocessor().getPreprocessingRecord();
9626 if (!ppRec)
9627 return skipped;
9629 ASTContext &Ctx = astUnit->getASTContext();
9631 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
9633 skipped->count = SkippedRanges.size();
9634 skipped->ranges = new CXSourceRange[skipped->count];
9635 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
9636 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
9638 return skipped;
9641 void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
9642 if (ranges) {
9643 delete[] ranges->ranges;
9644 delete ranges;
9648 void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
9649 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
9650 for (unsigned I = 0; I != Usage.numEntries; ++I)
9651 fprintf(stderr, " %s: %lu\n",
9652 clang_getTUResourceUsageName(Usage.entries[I].kind),
9653 Usage.entries[I].amount);
9655 clang_disposeCXTUResourceUsage(Usage);
9658 CXCursor clang_Cursor_getVarDeclInitializer(CXCursor cursor) {
9659 const Decl *const D = getCursorDecl(cursor);
9660 if (!D)
9661 return clang_getNullCursor();
9662 const auto *const VD = dyn_cast<VarDecl>(D);
9663 if (!VD)
9664 return clang_getNullCursor();
9665 const Expr *const Init = VD->getInit();
9666 if (!Init)
9667 return clang_getNullCursor();
9669 return cxcursor::MakeCXCursor(Init, VD, cxcursor::getCursorTU(cursor));
9672 int clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor) {
9673 const Decl *const D = getCursorDecl(cursor);
9674 if (!D)
9675 return -1;
9676 const auto *const VD = dyn_cast<VarDecl>(D);
9677 if (!VD)
9678 return -1;
9680 return VD->hasGlobalStorage();
9683 int clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor) {
9684 const Decl *const D = getCursorDecl(cursor);
9685 if (!D)
9686 return -1;
9687 const auto *const VD = dyn_cast<VarDecl>(D);
9688 if (!VD)
9689 return -1;
9691 return VD->hasExternalStorage();
9694 //===----------------------------------------------------------------------===//
9695 // Misc. utility functions.
9696 //===----------------------------------------------------------------------===//
9698 /// Default to using our desired 8 MB stack size on "safety" threads.
9699 static unsigned SafetyStackThreadSize = DesiredStackSize;
9701 namespace clang {
9703 bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
9704 unsigned Size) {
9705 if (!Size)
9706 Size = GetSafetyThreadStackSize();
9707 if (Size && !getenv("LIBCLANG_NOTHREADS"))
9708 return CRC.RunSafelyOnThread(Fn, Size);
9709 return CRC.RunSafely(Fn);
9712 unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
9714 void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
9716 } // namespace clang
9718 void clang::setThreadBackgroundPriority() {
9719 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
9720 return;
9722 #if LLVM_ENABLE_THREADS
9723 // The function name setThreadBackgroundPriority is for historical reasons;
9724 // Low is more appropriate.
9725 llvm::set_thread_priority(llvm::ThreadPriority::Low);
9726 #endif
9729 void cxindex::printDiagsToStderr(ASTUnit *Unit) {
9730 if (!Unit)
9731 return;
9733 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
9734 DEnd = Unit->stored_diag_end();
9735 D != DEnd; ++D) {
9736 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
9737 CXString Msg =
9738 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
9739 fprintf(stderr, "%s\n", clang_getCString(Msg));
9740 clang_disposeString(Msg);
9742 #ifdef _WIN32
9743 // On Windows, force a flush, since there may be multiple copies of
9744 // stderr and stdout in the file system, all with different buffers
9745 // but writing to the same device.
9746 fflush(stderr);
9747 #endif
9750 MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
9751 SourceLocation MacroDefLoc,
9752 CXTranslationUnit TU) {
9753 if (MacroDefLoc.isInvalid() || !TU)
9754 return nullptr;
9755 if (!II.hadMacroDefinition())
9756 return nullptr;
9758 ASTUnit *Unit = cxtu::getASTUnit(TU);
9759 Preprocessor &PP = Unit->getPreprocessor();
9760 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
9761 if (MD) {
9762 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
9763 Def = Def.getPreviousDefinition()) {
9764 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
9765 return Def.getMacroInfo();
9769 return nullptr;
9772 const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
9773 CXTranslationUnit TU) {
9774 if (!MacroDef || !TU)
9775 return nullptr;
9776 const IdentifierInfo *II = MacroDef->getName();
9777 if (!II)
9778 return nullptr;
9780 return getMacroInfo(*II, MacroDef->getLocation(), TU);
9783 MacroDefinitionRecord *
9784 cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
9785 CXTranslationUnit TU) {
9786 if (!MI || !TU)
9787 return nullptr;
9788 if (Tok.isNot(tok::raw_identifier))
9789 return nullptr;
9791 if (MI->getNumTokens() == 0)
9792 return nullptr;
9793 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
9794 MI->getDefinitionEndLoc());
9795 ASTUnit *Unit = cxtu::getASTUnit(TU);
9797 // Check that the token is inside the definition and not its argument list.
9798 SourceManager &SM = Unit->getSourceManager();
9799 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
9800 return nullptr;
9801 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
9802 return nullptr;
9804 Preprocessor &PP = Unit->getPreprocessor();
9805 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
9806 if (!PPRec)
9807 return nullptr;
9809 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
9810 if (!II.hadMacroDefinition())
9811 return nullptr;
9813 // Check that the identifier is not one of the macro arguments.
9814 if (llvm::is_contained(MI->params(), &II))
9815 return nullptr;
9817 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
9818 if (!InnerMD)
9819 return nullptr;
9821 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
9824 MacroDefinitionRecord *
9825 cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
9826 CXTranslationUnit TU) {
9827 if (Loc.isInvalid() || !MI || !TU)
9828 return nullptr;
9830 if (MI->getNumTokens() == 0)
9831 return nullptr;
9832 ASTUnit *Unit = cxtu::getASTUnit(TU);
9833 Preprocessor &PP = Unit->getPreprocessor();
9834 if (!PP.getPreprocessingRecord())
9835 return nullptr;
9836 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
9837 Token Tok;
9838 if (PP.getRawToken(Loc, Tok))
9839 return nullptr;
9841 return checkForMacroInMacroDefinition(MI, Tok, TU);
9844 CXString clang_getClangVersion() {
9845 return cxstring::createDup(getClangFullVersion());
9848 Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
9849 if (TU) {
9850 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
9851 LogOS << '<' << Unit->getMainFileName() << '>';
9852 if (Unit->isMainFileAST())
9853 LogOS << " (" << Unit->getASTFileName() << ')';
9854 return *this;
9856 } else {
9857 LogOS << "<NULL TU>";
9859 return *this;
9862 Logger &cxindex::Logger::operator<<(FileEntryRef FE) {
9863 *this << FE.getName();
9864 return *this;
9867 Logger &cxindex::Logger::operator<<(CXCursor cursor) {
9868 CXString cursorName = clang_getCursorDisplayName(cursor);
9869 *this << cursorName << "@" << clang_getCursorLocation(cursor);
9870 clang_disposeString(cursorName);
9871 return *this;
9874 Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
9875 CXFile File;
9876 unsigned Line, Column;
9877 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
9878 CXString FileName = clang_getFileName(File);
9879 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
9880 clang_disposeString(FileName);
9881 return *this;
9884 Logger &cxindex::Logger::operator<<(CXSourceRange range) {
9885 CXSourceLocation BLoc = clang_getRangeStart(range);
9886 CXSourceLocation ELoc = clang_getRangeEnd(range);
9888 CXFile BFile;
9889 unsigned BLine, BColumn;
9890 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
9892 CXFile EFile;
9893 unsigned ELine, EColumn;
9894 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
9896 CXString BFileName = clang_getFileName(BFile);
9897 if (BFile == EFile) {
9898 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
9899 BLine, BColumn, ELine, EColumn);
9900 } else {
9901 CXString EFileName = clang_getFileName(EFile);
9902 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9903 BColumn)
9904 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9905 EColumn);
9906 clang_disposeString(EFileName);
9908 clang_disposeString(BFileName);
9909 return *this;
9912 Logger &cxindex::Logger::operator<<(CXString Str) {
9913 *this << clang_getCString(Str);
9914 return *this;
9917 Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9918 LogOS << Fmt;
9919 return *this;
9922 static llvm::ManagedStatic<std::mutex> LoggingMutex;
9924 cxindex::Logger::~Logger() {
9925 std::lock_guard<std::mutex> L(*LoggingMutex);
9927 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9929 raw_ostream &OS = llvm::errs();
9930 OS << "[libclang:" << Name << ':';
9932 #ifdef USE_DARWIN_THREADS
9933 // TODO: Portability.
9934 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9935 OS << tid << ':';
9936 #endif
9938 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9939 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
9940 OS << Msg << '\n';
9942 if (Trace) {
9943 llvm::sys::PrintStackTrace(OS);
9944 OS << "--------------------------------------------------\n";
9948 CXString clang_getBinaryOperatorKindSpelling(enum CXBinaryOperatorKind kind) {
9949 return cxstring::createRef(
9950 BinaryOperator::getOpcodeStr(static_cast<BinaryOperatorKind>(kind - 1)));
9953 enum CXBinaryOperatorKind clang_getCursorBinaryOperatorKind(CXCursor cursor) {
9954 if (clang_isExpression(cursor.kind)) {
9955 const Expr *expr = getCursorExpr(cursor);
9957 if (const auto *op = dyn_cast<BinaryOperator>(expr))
9958 return static_cast<CXBinaryOperatorKind>(op->getOpcode() + 1);
9960 if (const auto *op = dyn_cast<CXXRewrittenBinaryOperator>(expr))
9961 return static_cast<CXBinaryOperatorKind>(op->getOpcode() + 1);
9964 return CXBinaryOperator_Invalid;
9967 CXString clang_getUnaryOperatorKindSpelling(enum CXUnaryOperatorKind kind) {
9968 return cxstring::createRef(
9969 UnaryOperator::getOpcodeStr(static_cast<UnaryOperatorKind>(kind - 1)));
9972 enum CXUnaryOperatorKind clang_getCursorUnaryOperatorKind(CXCursor cursor) {
9973 if (clang_isExpression(cursor.kind)) {
9974 const Expr *expr = getCursorExpr(cursor);
9976 if (const auto *op = dyn_cast<UnaryOperator>(expr))
9977 return static_cast<CXUnaryOperatorKind>(op->getOpcode() + 1);
9980 return CXUnaryOperator_Invalid;