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