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

source code of clang/tools/libclang/CIndex.cpp