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