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