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