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