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