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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of clang/tools/libclang/CIndex.cpp