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