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