Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / tools / libclang / CIndex.cpp
blob169ce4f9b7c6a4d2eac1d6e17aaff9035f1f3ca4
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 NoLinkage:
8250 case VisibleNoLinkage:
8251 return CXLinkage_NoLinkage;
8252 case InternalLinkage:
8253 return CXLinkage_Internal;
8254 case UniqueExternalLinkage:
8255 return CXLinkage_UniqueExternal;
8256 case ModuleLinkage:
8257 case ExternalLinkage:
8258 return CXLinkage_External;
8261 return CXLinkage_Invalid;
8264 //===----------------------------------------------------------------------===//
8265 // Operations for querying visibility of a cursor.
8266 //===----------------------------------------------------------------------===//
8268 CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
8269 if (!clang_isDeclaration(cursor.kind))
8270 return CXVisibility_Invalid;
8272 const Decl *D = cxcursor::getCursorDecl(cursor);
8273 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
8274 switch (ND->getVisibility()) {
8275 case HiddenVisibility:
8276 return CXVisibility_Hidden;
8277 case ProtectedVisibility:
8278 return CXVisibility_Protected;
8279 case DefaultVisibility:
8280 return CXVisibility_Default;
8283 return CXVisibility_Invalid;
8286 //===----------------------------------------------------------------------===//
8287 // Operations for querying language of a cursor.
8288 //===----------------------------------------------------------------------===//
8290 static CXLanguageKind getDeclLanguage(const Decl *D) {
8291 if (!D)
8292 return CXLanguage_C;
8294 switch (D->getKind()) {
8295 default:
8296 break;
8297 case Decl::ImplicitParam:
8298 case Decl::ObjCAtDefsField:
8299 case Decl::ObjCCategory:
8300 case Decl::ObjCCategoryImpl:
8301 case Decl::ObjCCompatibleAlias:
8302 case Decl::ObjCImplementation:
8303 case Decl::ObjCInterface:
8304 case Decl::ObjCIvar:
8305 case Decl::ObjCMethod:
8306 case Decl::ObjCProperty:
8307 case Decl::ObjCPropertyImpl:
8308 case Decl::ObjCProtocol:
8309 case Decl::ObjCTypeParam:
8310 return CXLanguage_ObjC;
8311 case Decl::CXXConstructor:
8312 case Decl::CXXConversion:
8313 case Decl::CXXDestructor:
8314 case Decl::CXXMethod:
8315 case Decl::CXXRecord:
8316 case Decl::ClassTemplate:
8317 case Decl::ClassTemplatePartialSpecialization:
8318 case Decl::ClassTemplateSpecialization:
8319 case Decl::Friend:
8320 case Decl::FriendTemplate:
8321 case Decl::FunctionTemplate:
8322 case Decl::LinkageSpec:
8323 case Decl::Namespace:
8324 case Decl::NamespaceAlias:
8325 case Decl::NonTypeTemplateParm:
8326 case Decl::StaticAssert:
8327 case Decl::TemplateTemplateParm:
8328 case Decl::TemplateTypeParm:
8329 case Decl::UnresolvedUsingTypename:
8330 case Decl::UnresolvedUsingValue:
8331 case Decl::Using:
8332 case Decl::UsingDirective:
8333 case Decl::UsingShadow:
8334 return CXLanguage_CPlusPlus;
8337 return CXLanguage_C;
8340 static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
8341 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
8342 return CXAvailability_NotAvailable;
8344 switch (D->getAvailability()) {
8345 case AR_Available:
8346 case AR_NotYetIntroduced:
8347 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
8348 return getCursorAvailabilityForDecl(
8349 cast<Decl>(EnumConst->getDeclContext()));
8350 return CXAvailability_Available;
8352 case AR_Deprecated:
8353 return CXAvailability_Deprecated;
8355 case AR_Unavailable:
8356 return CXAvailability_NotAvailable;
8359 llvm_unreachable("Unknown availability kind!");
8362 enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
8363 if (clang_isDeclaration(cursor.kind))
8364 if (const Decl *D = cxcursor::getCursorDecl(cursor))
8365 return getCursorAvailabilityForDecl(D);
8367 return CXAvailability_Available;
8370 static CXVersion convertVersion(VersionTuple In) {
8371 CXVersion Out = {-1, -1, -1};
8372 if (In.empty())
8373 return Out;
8375 Out.Major = In.getMajor();
8377 std::optional<unsigned> Minor = In.getMinor();
8378 if (Minor)
8379 Out.Minor = *Minor;
8380 else
8381 return Out;
8383 std::optional<unsigned> Subminor = In.getSubminor();
8384 if (Subminor)
8385 Out.Subminor = *Subminor;
8387 return Out;
8390 static void getCursorPlatformAvailabilityForDecl(
8391 const Decl *D, int *always_deprecated, CXString *deprecated_message,
8392 int *always_unavailable, CXString *unavailable_message,
8393 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
8394 bool HadAvailAttr = false;
8395 for (auto A : D->attrs()) {
8396 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
8397 HadAvailAttr = true;
8398 if (always_deprecated)
8399 *always_deprecated = 1;
8400 if (deprecated_message) {
8401 clang_disposeString(*deprecated_message);
8402 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
8404 continue;
8407 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
8408 HadAvailAttr = true;
8409 if (always_unavailable)
8410 *always_unavailable = 1;
8411 if (unavailable_message) {
8412 clang_disposeString(*unavailable_message);
8413 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
8415 continue;
8418 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
8419 AvailabilityAttrs.push_back(Avail);
8420 HadAvailAttr = true;
8424 if (!HadAvailAttr)
8425 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
8426 return getCursorPlatformAvailabilityForDecl(
8427 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
8428 deprecated_message, always_unavailable, unavailable_message,
8429 AvailabilityAttrs);
8431 // If no availability attributes are found, inherit the attribute from the
8432 // containing decl or the class or category interface decl.
8433 if (AvailabilityAttrs.empty()) {
8434 const ObjCContainerDecl *CD = nullptr;
8435 const DeclContext *DC = D->getDeclContext();
8437 if (auto *IMD = dyn_cast<ObjCImplementationDecl>(D))
8438 CD = IMD->getClassInterface();
8439 else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D))
8440 CD = CatD->getClassInterface();
8441 else if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(D))
8442 CD = IMD->getCategoryDecl();
8443 else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(DC))
8444 CD = ID;
8445 else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(DC))
8446 CD = CatD;
8447 else if (auto *IMD = dyn_cast<ObjCImplementationDecl>(DC))
8448 CD = IMD->getClassInterface();
8449 else if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(DC))
8450 CD = IMD->getCategoryDecl();
8451 else if (auto *PD = dyn_cast<ObjCProtocolDecl>(DC))
8452 CD = PD;
8454 if (CD)
8455 getCursorPlatformAvailabilityForDecl(
8456 CD, always_deprecated, deprecated_message, always_unavailable,
8457 unavailable_message, AvailabilityAttrs);
8458 return;
8461 llvm::sort(
8462 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
8463 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
8465 ASTContext &Ctx = D->getASTContext();
8466 auto It = std::unique(
8467 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
8468 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
8469 if (LHS->getPlatform() != RHS->getPlatform())
8470 return false;
8472 if (LHS->getIntroduced() == RHS->getIntroduced() &&
8473 LHS->getDeprecated() == RHS->getDeprecated() &&
8474 LHS->getObsoleted() == RHS->getObsoleted() &&
8475 LHS->getMessage() == RHS->getMessage() &&
8476 LHS->getReplacement() == RHS->getReplacement())
8477 return true;
8479 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
8480 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
8481 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
8482 return false;
8484 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
8485 LHS->setIntroduced(Ctx, RHS->getIntroduced());
8487 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
8488 LHS->setDeprecated(Ctx, RHS->getDeprecated());
8489 if (LHS->getMessage().empty())
8490 LHS->setMessage(Ctx, RHS->getMessage());
8491 if (LHS->getReplacement().empty())
8492 LHS->setReplacement(Ctx, RHS->getReplacement());
8495 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
8496 LHS->setObsoleted(Ctx, RHS->getObsoleted());
8497 if (LHS->getMessage().empty())
8498 LHS->setMessage(Ctx, RHS->getMessage());
8499 if (LHS->getReplacement().empty())
8500 LHS->setReplacement(Ctx, RHS->getReplacement());
8503 return true;
8505 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
8508 int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
8509 CXString *deprecated_message,
8510 int *always_unavailable,
8511 CXString *unavailable_message,
8512 CXPlatformAvailability *availability,
8513 int availability_size) {
8514 if (always_deprecated)
8515 *always_deprecated = 0;
8516 if (deprecated_message)
8517 *deprecated_message = cxstring::createEmpty();
8518 if (always_unavailable)
8519 *always_unavailable = 0;
8520 if (unavailable_message)
8521 *unavailable_message = cxstring::createEmpty();
8523 if (!clang_isDeclaration(cursor.kind))
8524 return 0;
8526 const Decl *D = cxcursor::getCursorDecl(cursor);
8527 if (!D)
8528 return 0;
8530 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
8531 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8532 always_unavailable, unavailable_message,
8533 AvailabilityAttrs);
8534 for (const auto &Avail : llvm::enumerate(
8535 llvm::ArrayRef(AvailabilityAttrs).take_front(availability_size))) {
8536 availability[Avail.index()].Platform =
8537 cxstring::createDup(Avail.value()->getPlatform()->getName());
8538 availability[Avail.index()].Introduced =
8539 convertVersion(Avail.value()->getIntroduced());
8540 availability[Avail.index()].Deprecated =
8541 convertVersion(Avail.value()->getDeprecated());
8542 availability[Avail.index()].Obsoleted =
8543 convertVersion(Avail.value()->getObsoleted());
8544 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8545 availability[Avail.index()].Message =
8546 cxstring::createDup(Avail.value()->getMessage());
8549 return AvailabilityAttrs.size();
8552 void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8553 clang_disposeString(availability->Platform);
8554 clang_disposeString(availability->Message);
8557 CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8558 if (clang_isDeclaration(cursor.kind))
8559 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8561 return CXLanguage_Invalid;
8564 CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8565 const Decl *D = cxcursor::getCursorDecl(cursor);
8566 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8567 switch (VD->getTLSKind()) {
8568 case VarDecl::TLS_None:
8569 return CXTLS_None;
8570 case VarDecl::TLS_Dynamic:
8571 return CXTLS_Dynamic;
8572 case VarDecl::TLS_Static:
8573 return CXTLS_Static;
8577 return CXTLS_None;
8580 /// If the given cursor is the "templated" declaration
8581 /// describing a class or function template, return the class or
8582 /// function template.
8583 static const Decl *maybeGetTemplateCursor(const Decl *D) {
8584 if (!D)
8585 return nullptr;
8587 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8588 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8589 return FunTmpl;
8591 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
8592 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8593 return ClassTmpl;
8595 return D;
8598 enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8599 StorageClass sc = SC_None;
8600 const Decl *D = getCursorDecl(C);
8601 if (D) {
8602 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8603 sc = FD->getStorageClass();
8604 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8605 sc = VD->getStorageClass();
8606 } else {
8607 return CX_SC_Invalid;
8609 } else {
8610 return CX_SC_Invalid;
8612 switch (sc) {
8613 case SC_None:
8614 return CX_SC_None;
8615 case SC_Extern:
8616 return CX_SC_Extern;
8617 case SC_Static:
8618 return CX_SC_Static;
8619 case SC_PrivateExtern:
8620 return CX_SC_PrivateExtern;
8621 case SC_Auto:
8622 return CX_SC_Auto;
8623 case SC_Register:
8624 return CX_SC_Register;
8626 llvm_unreachable("Unhandled storage class!");
8629 CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8630 if (clang_isDeclaration(cursor.kind)) {
8631 if (const Decl *D = getCursorDecl(cursor)) {
8632 const DeclContext *DC = D->getDeclContext();
8633 if (!DC)
8634 return clang_getNullCursor();
8636 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
8637 getCursorTU(cursor));
8641 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
8642 if (const Decl *D = getCursorDecl(cursor))
8643 return MakeCXCursor(D, getCursorTU(cursor));
8646 return clang_getNullCursor();
8649 CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8650 if (clang_isDeclaration(cursor.kind)) {
8651 if (const Decl *D = getCursorDecl(cursor)) {
8652 const DeclContext *DC = D->getLexicalDeclContext();
8653 if (!DC)
8654 return clang_getNullCursor();
8656 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
8657 getCursorTU(cursor));
8661 // FIXME: Note that we can't easily compute the lexical context of a
8662 // statement or expression, so we return nothing.
8663 return clang_getNullCursor();
8666 CXFile clang_getIncludedFile(CXCursor cursor) {
8667 if (cursor.kind != CXCursor_InclusionDirective)
8668 return nullptr;
8670 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
8671 return cxfile::makeCXFile(ID->getFile());
8674 unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8675 if (C.kind != CXCursor_ObjCPropertyDecl)
8676 return CXObjCPropertyAttr_noattr;
8678 unsigned Result = CXObjCPropertyAttr_noattr;
8679 const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));
8680 ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
8682 #define SET_CXOBJCPROP_ATTR(A) \
8683 if (Attr & ObjCPropertyAttribute::kind_##A) \
8684 Result |= CXObjCPropertyAttr_##A
8685 SET_CXOBJCPROP_ATTR(readonly);
8686 SET_CXOBJCPROP_ATTR(getter);
8687 SET_CXOBJCPROP_ATTR(assign);
8688 SET_CXOBJCPROP_ATTR(readwrite);
8689 SET_CXOBJCPROP_ATTR(retain);
8690 SET_CXOBJCPROP_ATTR(copy);
8691 SET_CXOBJCPROP_ATTR(nonatomic);
8692 SET_CXOBJCPROP_ATTR(setter);
8693 SET_CXOBJCPROP_ATTR(atomic);
8694 SET_CXOBJCPROP_ATTR(weak);
8695 SET_CXOBJCPROP_ATTR(strong);
8696 SET_CXOBJCPROP_ATTR(unsafe_unretained);
8697 SET_CXOBJCPROP_ATTR(class);
8698 #undef SET_CXOBJCPROP_ATTR
8700 return Result;
8703 CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8704 if (C.kind != CXCursor_ObjCPropertyDecl)
8705 return cxstring::createNull();
8707 const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));
8708 Selector sel = PD->getGetterName();
8709 if (sel.isNull())
8710 return cxstring::createNull();
8712 return cxstring::createDup(sel.getAsString());
8715 CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8716 if (C.kind != CXCursor_ObjCPropertyDecl)
8717 return cxstring::createNull();
8719 const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));
8720 Selector sel = PD->getSetterName();
8721 if (sel.isNull())
8722 return cxstring::createNull();
8724 return cxstring::createDup(sel.getAsString());
8727 unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8728 if (!clang_isDeclaration(C.kind))
8729 return CXObjCDeclQualifier_None;
8731 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8732 const Decl *D = getCursorDecl(C);
8733 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8734 QT = MD->getObjCDeclQualifier();
8735 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8736 QT = PD->getObjCDeclQualifier();
8737 if (QT == Decl::OBJC_TQ_None)
8738 return CXObjCDeclQualifier_None;
8740 unsigned Result = CXObjCDeclQualifier_None;
8741 if (QT & Decl::OBJC_TQ_In)
8742 Result |= CXObjCDeclQualifier_In;
8743 if (QT & Decl::OBJC_TQ_Inout)
8744 Result |= CXObjCDeclQualifier_Inout;
8745 if (QT & Decl::OBJC_TQ_Out)
8746 Result |= CXObjCDeclQualifier_Out;
8747 if (QT & Decl::OBJC_TQ_Bycopy)
8748 Result |= CXObjCDeclQualifier_Bycopy;
8749 if (QT & Decl::OBJC_TQ_Byref)
8750 Result |= CXObjCDeclQualifier_Byref;
8751 if (QT & Decl::OBJC_TQ_Oneway)
8752 Result |= CXObjCDeclQualifier_Oneway;
8754 return Result;
8757 unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8758 if (!clang_isDeclaration(C.kind))
8759 return 0;
8761 const Decl *D = getCursorDecl(C);
8762 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8763 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8764 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8765 return MD->getImplementationControl() ==
8766 ObjCImplementationControl::Optional;
8768 return 0;
8771 unsigned clang_Cursor_isVariadic(CXCursor C) {
8772 if (!clang_isDeclaration(C.kind))
8773 return 0;
8775 const Decl *D = getCursorDecl(C);
8776 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8777 return FD->isVariadic();
8778 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8779 return MD->isVariadic();
8781 return 0;
8784 unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8785 CXString *definedIn,
8786 unsigned *isGenerated) {
8787 if (!clang_isDeclaration(C.kind))
8788 return 0;
8790 const Decl *D = getCursorDecl(C);
8792 if (auto *attr = D->getExternalSourceSymbolAttr()) {
8793 if (language)
8794 *language = cxstring::createDup(attr->getLanguage());
8795 if (definedIn)
8796 *definedIn = cxstring::createDup(attr->getDefinedIn());
8797 if (isGenerated)
8798 *isGenerated = attr->getGeneratedDeclaration();
8799 return 1;
8801 return 0;
8804 CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8805 if (!clang_isDeclaration(C.kind))
8806 return clang_getNullRange();
8808 const Decl *D = getCursorDecl(C);
8809 ASTContext &Context = getCursorContext(C);
8810 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8811 if (!RC)
8812 return clang_getNullRange();
8814 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8817 CXString clang_Cursor_getRawCommentText(CXCursor C) {
8818 if (!clang_isDeclaration(C.kind))
8819 return cxstring::createNull();
8821 const Decl *D = getCursorDecl(C);
8822 ASTContext &Context = getCursorContext(C);
8823 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8824 StringRef RawText =
8825 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
8827 // Don't duplicate the string because RawText points directly into source
8828 // code.
8829 return cxstring::createRef(RawText);
8832 CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8833 if (!clang_isDeclaration(C.kind))
8834 return cxstring::createNull();
8836 const Decl *D = getCursorDecl(C);
8837 const ASTContext &Context = getCursorContext(C);
8838 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8840 if (RC) {
8841 StringRef BriefText = RC->getBriefText(Context);
8843 // Don't duplicate the string because RawComment ensures that this memory
8844 // will not go away.
8845 return cxstring::createRef(BriefText);
8848 return cxstring::createNull();
8851 CXModule clang_Cursor_getModule(CXCursor C) {
8852 if (C.kind == CXCursor_ModuleImportDecl) {
8853 if (const ImportDecl *ImportD =
8854 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
8855 return ImportD->getImportedModule();
8858 return nullptr;
8861 CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8862 if (isNotUsableTU(TU)) {
8863 LOG_BAD_TU(TU);
8864 return nullptr;
8866 if (!File)
8867 return nullptr;
8868 FileEntryRef FE = *cxfile::getFileEntryRef(File);
8870 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8871 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8872 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
8874 return Header.getModule();
8877 CXFile clang_Module_getASTFile(CXModule CXMod) {
8878 if (!CXMod)
8879 return nullptr;
8880 Module *Mod = static_cast<Module *>(CXMod);
8881 return cxfile::makeCXFile(Mod->getASTFile());
8884 CXModule clang_Module_getParent(CXModule CXMod) {
8885 if (!CXMod)
8886 return nullptr;
8887 Module *Mod = static_cast<Module *>(CXMod);
8888 return Mod->Parent;
8891 CXString clang_Module_getName(CXModule CXMod) {
8892 if (!CXMod)
8893 return cxstring::createEmpty();
8894 Module *Mod = static_cast<Module *>(CXMod);
8895 return cxstring::createDup(Mod->Name);
8898 CXString clang_Module_getFullName(CXModule CXMod) {
8899 if (!CXMod)
8900 return cxstring::createEmpty();
8901 Module *Mod = static_cast<Module *>(CXMod);
8902 return cxstring::createDup(Mod->getFullModuleName());
8905 int clang_Module_isSystem(CXModule CXMod) {
8906 if (!CXMod)
8907 return 0;
8908 Module *Mod = static_cast<Module *>(CXMod);
8909 return Mod->IsSystem;
8912 unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8913 CXModule CXMod) {
8914 if (isNotUsableTU(TU)) {
8915 LOG_BAD_TU(TU);
8916 return 0;
8918 if (!CXMod)
8919 return 0;
8920 Module *Mod = static_cast<Module *>(CXMod);
8921 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8922 ArrayRef<FileEntryRef> TopHeaders = Mod->getTopHeaders(FileMgr);
8923 return TopHeaders.size();
8926 CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8927 unsigned Index) {
8928 if (isNotUsableTU(TU)) {
8929 LOG_BAD_TU(TU);
8930 return nullptr;
8932 if (!CXMod)
8933 return nullptr;
8934 Module *Mod = static_cast<Module *>(CXMod);
8935 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8937 ArrayRef<FileEntryRef> TopHeaders = Mod->getTopHeaders(FileMgr);
8938 if (Index < TopHeaders.size())
8939 return cxfile::makeCXFile(TopHeaders[Index]);
8941 return nullptr;
8944 //===----------------------------------------------------------------------===//
8945 // C++ AST instrospection.
8946 //===----------------------------------------------------------------------===//
8948 unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8949 if (!clang_isDeclaration(C.kind))
8950 return 0;
8952 const Decl *D = cxcursor::getCursorDecl(C);
8953 const CXXConstructorDecl *Constructor =
8954 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8955 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8958 unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8959 if (!clang_isDeclaration(C.kind))
8960 return 0;
8962 const Decl *D = cxcursor::getCursorDecl(C);
8963 const CXXConstructorDecl *Constructor =
8964 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8965 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8968 unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8969 if (!clang_isDeclaration(C.kind))
8970 return 0;
8972 const Decl *D = cxcursor::getCursorDecl(C);
8973 const CXXConstructorDecl *Constructor =
8974 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8975 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8978 unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8979 if (!clang_isDeclaration(C.kind))
8980 return 0;
8982 const Decl *D = cxcursor::getCursorDecl(C);
8983 const CXXConstructorDecl *Constructor =
8984 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8985 // Passing 'false' excludes constructors marked 'explicit'.
8986 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8989 unsigned clang_CXXField_isMutable(CXCursor C) {
8990 if (!clang_isDeclaration(C.kind))
8991 return 0;
8993 if (const auto D = cxcursor::getCursorDecl(C))
8994 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8995 return FD->isMutable() ? 1 : 0;
8996 return 0;
8999 unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
9000 if (!clang_isDeclaration(C.kind))
9001 return 0;
9003 const Decl *D = cxcursor::getCursorDecl(C);
9004 const CXXMethodDecl *Method =
9005 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9006 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
9009 unsigned clang_CXXMethod_isConst(CXCursor C) {
9010 if (!clang_isDeclaration(C.kind))
9011 return 0;
9013 const Decl *D = cxcursor::getCursorDecl(C);
9014 const CXXMethodDecl *Method =
9015 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9016 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
9019 unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
9020 if (!clang_isDeclaration(C.kind))
9021 return 0;
9023 const Decl *D = cxcursor::getCursorDecl(C);
9024 const CXXMethodDecl *Method =
9025 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9026 return (Method && Method->isDefaulted()) ? 1 : 0;
9029 unsigned clang_CXXMethod_isDeleted(CXCursor C) {
9030 if (!clang_isDeclaration(C.kind))
9031 return 0;
9033 const Decl *D = cxcursor::getCursorDecl(C);
9034 const CXXMethodDecl *Method =
9035 D ? dyn_cast_if_present<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9036 return (Method && Method->isDeleted()) ? 1 : 0;
9039 unsigned clang_CXXMethod_isStatic(CXCursor C) {
9040 if (!clang_isDeclaration(C.kind))
9041 return 0;
9043 const Decl *D = cxcursor::getCursorDecl(C);
9044 const CXXMethodDecl *Method =
9045 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9046 return (Method && Method->isStatic()) ? 1 : 0;
9049 unsigned clang_CXXMethod_isVirtual(CXCursor C) {
9050 if (!clang_isDeclaration(C.kind))
9051 return 0;
9053 const Decl *D = cxcursor::getCursorDecl(C);
9054 const CXXMethodDecl *Method =
9055 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9056 return (Method && Method->isVirtual()) ? 1 : 0;
9059 unsigned clang_CXXMethod_isCopyAssignmentOperator(CXCursor C) {
9060 if (!clang_isDeclaration(C.kind))
9061 return 0;
9063 const Decl *D = cxcursor::getCursorDecl(C);
9064 const CXXMethodDecl *Method =
9065 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9067 return (Method && Method->isCopyAssignmentOperator()) ? 1 : 0;
9070 unsigned clang_CXXMethod_isMoveAssignmentOperator(CXCursor C) {
9071 if (!clang_isDeclaration(C.kind))
9072 return 0;
9074 const Decl *D = cxcursor::getCursorDecl(C);
9075 const CXXMethodDecl *Method =
9076 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
9078 return (Method && Method->isMoveAssignmentOperator()) ? 1 : 0;
9081 unsigned clang_CXXMethod_isExplicit(CXCursor C) {
9082 if (!clang_isDeclaration(C.kind))
9083 return 0;
9085 const Decl *D = cxcursor::getCursorDecl(C);
9086 const FunctionDecl *FD = D->getAsFunction();
9088 if (!FD)
9089 return 0;
9091 if (const auto *Ctor = dyn_cast<CXXConstructorDecl>(FD))
9092 return Ctor->isExplicit();
9094 if (const auto *Conv = dyn_cast<CXXConversionDecl>(FD))
9095 return Conv->isExplicit();
9097 return 0;
9100 unsigned clang_CXXRecord_isAbstract(CXCursor C) {
9101 if (!clang_isDeclaration(C.kind))
9102 return 0;
9104 const auto *D = cxcursor::getCursorDecl(C);
9105 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
9106 if (RD)
9107 RD = RD->getDefinition();
9108 return (RD && RD->isAbstract()) ? 1 : 0;
9111 unsigned clang_EnumDecl_isScoped(CXCursor C) {
9112 if (!clang_isDeclaration(C.kind))
9113 return 0;
9115 const Decl *D = cxcursor::getCursorDecl(C);
9116 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
9117 return (Enum && Enum->isScoped()) ? 1 : 0;
9120 //===----------------------------------------------------------------------===//
9121 // Attribute introspection.
9122 //===----------------------------------------------------------------------===//
9124 CXType clang_getIBOutletCollectionType(CXCursor C) {
9125 if (C.kind != CXCursor_IBOutletCollectionAttr)
9126 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
9128 const IBOutletCollectionAttr *A =
9129 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
9131 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
9134 //===----------------------------------------------------------------------===//
9135 // Inspecting memory usage.
9136 //===----------------------------------------------------------------------===//
9138 typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
9140 static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
9141 enum CXTUResourceUsageKind k,
9142 unsigned long amount) {
9143 CXTUResourceUsageEntry entry = {k, amount};
9144 entries.push_back(entry);
9147 const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
9148 const char *str = "";
9149 switch (kind) {
9150 case CXTUResourceUsage_AST:
9151 str = "ASTContext: expressions, declarations, and types";
9152 break;
9153 case CXTUResourceUsage_Identifiers:
9154 str = "ASTContext: identifiers";
9155 break;
9156 case CXTUResourceUsage_Selectors:
9157 str = "ASTContext: selectors";
9158 break;
9159 case CXTUResourceUsage_GlobalCompletionResults:
9160 str = "Code completion: cached global results";
9161 break;
9162 case CXTUResourceUsage_SourceManagerContentCache:
9163 str = "SourceManager: content cache allocator";
9164 break;
9165 case CXTUResourceUsage_AST_SideTables:
9166 str = "ASTContext: side tables";
9167 break;
9168 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
9169 str = "SourceManager: malloc'ed memory buffers";
9170 break;
9171 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
9172 str = "SourceManager: mmap'ed memory buffers";
9173 break;
9174 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
9175 str = "ExternalASTSource: malloc'ed memory buffers";
9176 break;
9177 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
9178 str = "ExternalASTSource: mmap'ed memory buffers";
9179 break;
9180 case CXTUResourceUsage_Preprocessor:
9181 str = "Preprocessor: malloc'ed memory";
9182 break;
9183 case CXTUResourceUsage_PreprocessingRecord:
9184 str = "Preprocessor: PreprocessingRecord";
9185 break;
9186 case CXTUResourceUsage_SourceManager_DataStructures:
9187 str = "SourceManager: data structures and tables";
9188 break;
9189 case CXTUResourceUsage_Preprocessor_HeaderSearch:
9190 str = "Preprocessor: header search tables";
9191 break;
9193 return str;
9196 CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
9197 if (isNotUsableTU(TU)) {
9198 LOG_BAD_TU(TU);
9199 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
9200 return usage;
9203 ASTUnit *astUnit = cxtu::getASTUnit(TU);
9204 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
9205 ASTContext &astContext = astUnit->getASTContext();
9207 // How much memory is used by AST nodes and types?
9208 createCXTUResourceUsageEntry(
9209 *entries, CXTUResourceUsage_AST,
9210 (unsigned long)astContext.getASTAllocatedMemory());
9212 // How much memory is used by identifiers?
9213 createCXTUResourceUsageEntry(
9214 *entries, CXTUResourceUsage_Identifiers,
9215 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
9217 // How much memory is used for selectors?
9218 createCXTUResourceUsageEntry(
9219 *entries, CXTUResourceUsage_Selectors,
9220 (unsigned long)astContext.Selectors.getTotalMemory());
9222 // How much memory is used by ASTContext's side tables?
9223 createCXTUResourceUsageEntry(
9224 *entries, CXTUResourceUsage_AST_SideTables,
9225 (unsigned long)astContext.getSideTableAllocatedMemory());
9227 // How much memory is used for caching global code completion results?
9228 unsigned long completionBytes = 0;
9229 if (GlobalCodeCompletionAllocator *completionAllocator =
9230 astUnit->getCachedCompletionAllocator().get()) {
9231 completionBytes = completionAllocator->getTotalMemory();
9233 createCXTUResourceUsageEntry(
9234 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
9236 // How much memory is being used by SourceManager's content cache?
9237 createCXTUResourceUsageEntry(
9238 *entries, CXTUResourceUsage_SourceManagerContentCache,
9239 (unsigned long)astContext.getSourceManager().getContentCacheSize());
9241 // How much memory is being used by the MemoryBuffer's in SourceManager?
9242 const SourceManager::MemoryBufferSizes &srcBufs =
9243 astUnit->getSourceManager().getMemoryBufferSizes();
9245 createCXTUResourceUsageEntry(*entries,
9246 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
9247 (unsigned long)srcBufs.malloc_bytes);
9248 createCXTUResourceUsageEntry(*entries,
9249 CXTUResourceUsage_SourceManager_Membuffer_MMap,
9250 (unsigned long)srcBufs.mmap_bytes);
9251 createCXTUResourceUsageEntry(
9252 *entries, CXTUResourceUsage_SourceManager_DataStructures,
9253 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
9255 // How much memory is being used by the ExternalASTSource?
9256 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
9257 const ExternalASTSource::MemoryBufferSizes &sizes =
9258 esrc->getMemoryBufferSizes();
9260 createCXTUResourceUsageEntry(
9261 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
9262 (unsigned long)sizes.malloc_bytes);
9263 createCXTUResourceUsageEntry(
9264 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
9265 (unsigned long)sizes.mmap_bytes);
9268 // How much memory is being used by the Preprocessor?
9269 Preprocessor &pp = astUnit->getPreprocessor();
9270 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
9271 pp.getTotalMemory());
9273 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
9274 createCXTUResourceUsageEntry(*entries,
9275 CXTUResourceUsage_PreprocessingRecord,
9276 pRec->getTotalMemory());
9279 createCXTUResourceUsageEntry(*entries,
9280 CXTUResourceUsage_Preprocessor_HeaderSearch,
9281 pp.getHeaderSearchInfo().getTotalMemory());
9283 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
9284 !entries->empty() ? &(*entries)[0] : nullptr};
9285 (void)entries.release();
9286 return usage;
9289 void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
9290 if (usage.data)
9291 delete (MemUsageEntries *)usage.data;
9294 CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
9295 CXSourceRangeList *skipped = new CXSourceRangeList;
9296 skipped->count = 0;
9297 skipped->ranges = nullptr;
9299 if (isNotUsableTU(TU)) {
9300 LOG_BAD_TU(TU);
9301 return skipped;
9304 if (!file)
9305 return skipped;
9307 ASTUnit *astUnit = cxtu::getASTUnit(TU);
9308 PreprocessingRecord *ppRec =
9309 astUnit->getPreprocessor().getPreprocessingRecord();
9310 if (!ppRec)
9311 return skipped;
9313 ASTContext &Ctx = astUnit->getASTContext();
9314 SourceManager &sm = Ctx.getSourceManager();
9315 FileEntryRef fileEntry = *cxfile::getFileEntryRef(file);
9316 FileID wantedFileID = sm.translateFile(fileEntry);
9317 bool isMainFile = wantedFileID == sm.getMainFileID();
9319 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
9320 std::vector<SourceRange> wantedRanges;
9321 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
9322 ei = SkippedRanges.end();
9323 i != ei; ++i) {
9324 if (sm.getFileID(i->getBegin()) == wantedFileID ||
9325 sm.getFileID(i->getEnd()) == wantedFileID)
9326 wantedRanges.push_back(*i);
9327 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
9328 astUnit->isInPreambleFileID(i->getEnd())))
9329 wantedRanges.push_back(*i);
9332 skipped->count = wantedRanges.size();
9333 skipped->ranges = new CXSourceRange[skipped->count];
9334 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
9335 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
9337 return skipped;
9340 CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
9341 CXSourceRangeList *skipped = new CXSourceRangeList;
9342 skipped->count = 0;
9343 skipped->ranges = nullptr;
9345 if (isNotUsableTU(TU)) {
9346 LOG_BAD_TU(TU);
9347 return skipped;
9350 ASTUnit *astUnit = cxtu::getASTUnit(TU);
9351 PreprocessingRecord *ppRec =
9352 astUnit->getPreprocessor().getPreprocessingRecord();
9353 if (!ppRec)
9354 return skipped;
9356 ASTContext &Ctx = astUnit->getASTContext();
9358 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
9360 skipped->count = SkippedRanges.size();
9361 skipped->ranges = new CXSourceRange[skipped->count];
9362 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
9363 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
9365 return skipped;
9368 void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
9369 if (ranges) {
9370 delete[] ranges->ranges;
9371 delete ranges;
9375 void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
9376 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
9377 for (unsigned I = 0; I != Usage.numEntries; ++I)
9378 fprintf(stderr, " %s: %lu\n",
9379 clang_getTUResourceUsageName(Usage.entries[I].kind),
9380 Usage.entries[I].amount);
9382 clang_disposeCXTUResourceUsage(Usage);
9385 CXCursor clang_Cursor_getVarDeclInitializer(CXCursor cursor) {
9386 const Decl *const D = getCursorDecl(cursor);
9387 if (!D)
9388 return clang_getNullCursor();
9389 const auto *const VD = dyn_cast<VarDecl>(D);
9390 if (!VD)
9391 return clang_getNullCursor();
9392 const Expr *const Init = VD->getInit();
9393 if (!Init)
9394 return clang_getNullCursor();
9396 return cxcursor::MakeCXCursor(Init, VD, cxcursor::getCursorTU(cursor));
9399 int clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor) {
9400 const Decl *const D = getCursorDecl(cursor);
9401 if (!D)
9402 return -1;
9403 const auto *const VD = dyn_cast<VarDecl>(D);
9404 if (!VD)
9405 return -1;
9407 return VD->hasGlobalStorage();
9410 int clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor) {
9411 const Decl *const D = getCursorDecl(cursor);
9412 if (!D)
9413 return -1;
9414 const auto *const VD = dyn_cast<VarDecl>(D);
9415 if (!VD)
9416 return -1;
9418 return VD->hasExternalStorage();
9421 //===----------------------------------------------------------------------===//
9422 // Misc. utility functions.
9423 //===----------------------------------------------------------------------===//
9425 /// Default to using our desired 8 MB stack size on "safety" threads.
9426 static unsigned SafetyStackThreadSize = DesiredStackSize;
9428 namespace clang {
9430 bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
9431 unsigned Size) {
9432 if (!Size)
9433 Size = GetSafetyThreadStackSize();
9434 if (Size && !getenv("LIBCLANG_NOTHREADS"))
9435 return CRC.RunSafelyOnThread(Fn, Size);
9436 return CRC.RunSafely(Fn);
9439 unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
9441 void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
9443 } // namespace clang
9445 void clang::setThreadBackgroundPriority() {
9446 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
9447 return;
9449 #if LLVM_ENABLE_THREADS
9450 // The function name setThreadBackgroundPriority is for historical reasons;
9451 // Low is more appropriate.
9452 llvm::set_thread_priority(llvm::ThreadPriority::Low);
9453 #endif
9456 void cxindex::printDiagsToStderr(ASTUnit *Unit) {
9457 if (!Unit)
9458 return;
9460 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
9461 DEnd = Unit->stored_diag_end();
9462 D != DEnd; ++D) {
9463 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
9464 CXString Msg =
9465 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
9466 fprintf(stderr, "%s\n", clang_getCString(Msg));
9467 clang_disposeString(Msg);
9469 #ifdef _WIN32
9470 // On Windows, force a flush, since there may be multiple copies of
9471 // stderr and stdout in the file system, all with different buffers
9472 // but writing to the same device.
9473 fflush(stderr);
9474 #endif
9477 MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
9478 SourceLocation MacroDefLoc,
9479 CXTranslationUnit TU) {
9480 if (MacroDefLoc.isInvalid() || !TU)
9481 return nullptr;
9482 if (!II.hadMacroDefinition())
9483 return nullptr;
9485 ASTUnit *Unit = cxtu::getASTUnit(TU);
9486 Preprocessor &PP = Unit->getPreprocessor();
9487 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
9488 if (MD) {
9489 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
9490 Def = Def.getPreviousDefinition()) {
9491 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
9492 return Def.getMacroInfo();
9496 return nullptr;
9499 const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
9500 CXTranslationUnit TU) {
9501 if (!MacroDef || !TU)
9502 return nullptr;
9503 const IdentifierInfo *II = MacroDef->getName();
9504 if (!II)
9505 return nullptr;
9507 return getMacroInfo(*II, MacroDef->getLocation(), TU);
9510 MacroDefinitionRecord *
9511 cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
9512 CXTranslationUnit TU) {
9513 if (!MI || !TU)
9514 return nullptr;
9515 if (Tok.isNot(tok::raw_identifier))
9516 return nullptr;
9518 if (MI->getNumTokens() == 0)
9519 return nullptr;
9520 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
9521 MI->getDefinitionEndLoc());
9522 ASTUnit *Unit = cxtu::getASTUnit(TU);
9524 // Check that the token is inside the definition and not its argument list.
9525 SourceManager &SM = Unit->getSourceManager();
9526 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
9527 return nullptr;
9528 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
9529 return nullptr;
9531 Preprocessor &PP = Unit->getPreprocessor();
9532 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
9533 if (!PPRec)
9534 return nullptr;
9536 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
9537 if (!II.hadMacroDefinition())
9538 return nullptr;
9540 // Check that the identifier is not one of the macro arguments.
9541 if (llvm::is_contained(MI->params(), &II))
9542 return nullptr;
9544 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
9545 if (!InnerMD)
9546 return nullptr;
9548 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
9551 MacroDefinitionRecord *
9552 cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
9553 CXTranslationUnit TU) {
9554 if (Loc.isInvalid() || !MI || !TU)
9555 return nullptr;
9557 if (MI->getNumTokens() == 0)
9558 return nullptr;
9559 ASTUnit *Unit = cxtu::getASTUnit(TU);
9560 Preprocessor &PP = Unit->getPreprocessor();
9561 if (!PP.getPreprocessingRecord())
9562 return nullptr;
9563 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
9564 Token Tok;
9565 if (PP.getRawToken(Loc, Tok))
9566 return nullptr;
9568 return checkForMacroInMacroDefinition(MI, Tok, TU);
9571 CXString clang_getClangVersion() {
9572 return cxstring::createDup(getClangFullVersion());
9575 Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
9576 if (TU) {
9577 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
9578 LogOS << '<' << Unit->getMainFileName() << '>';
9579 if (Unit->isMainFileAST())
9580 LogOS << " (" << Unit->getASTFileName() << ')';
9581 return *this;
9583 } else {
9584 LogOS << "<NULL TU>";
9586 return *this;
9589 Logger &cxindex::Logger::operator<<(FileEntryRef FE) {
9590 *this << FE.getName();
9591 return *this;
9594 Logger &cxindex::Logger::operator<<(CXCursor cursor) {
9595 CXString cursorName = clang_getCursorDisplayName(cursor);
9596 *this << cursorName << "@" << clang_getCursorLocation(cursor);
9597 clang_disposeString(cursorName);
9598 return *this;
9601 Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
9602 CXFile File;
9603 unsigned Line, Column;
9604 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
9605 CXString FileName = clang_getFileName(File);
9606 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
9607 clang_disposeString(FileName);
9608 return *this;
9611 Logger &cxindex::Logger::operator<<(CXSourceRange range) {
9612 CXSourceLocation BLoc = clang_getRangeStart(range);
9613 CXSourceLocation ELoc = clang_getRangeEnd(range);
9615 CXFile BFile;
9616 unsigned BLine, BColumn;
9617 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
9619 CXFile EFile;
9620 unsigned ELine, EColumn;
9621 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
9623 CXString BFileName = clang_getFileName(BFile);
9624 if (BFile == EFile) {
9625 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
9626 BLine, BColumn, ELine, EColumn);
9627 } else {
9628 CXString EFileName = clang_getFileName(EFile);
9629 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9630 BColumn)
9631 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9632 EColumn);
9633 clang_disposeString(EFileName);
9635 clang_disposeString(BFileName);
9636 return *this;
9639 Logger &cxindex::Logger::operator<<(CXString Str) {
9640 *this << clang_getCString(Str);
9641 return *this;
9644 Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9645 LogOS << Fmt;
9646 return *this;
9649 static llvm::ManagedStatic<std::mutex> LoggingMutex;
9651 cxindex::Logger::~Logger() {
9652 std::lock_guard<std::mutex> L(*LoggingMutex);
9654 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9656 raw_ostream &OS = llvm::errs();
9657 OS << "[libclang:" << Name << ':';
9659 #ifdef USE_DARWIN_THREADS
9660 // TODO: Portability.
9661 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9662 OS << tid << ':';
9663 #endif
9665 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9666 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
9667 OS << Msg << '\n';
9669 if (Trace) {
9670 llvm::sys::PrintStackTrace(OS);
9671 OS << "--------------------------------------------------\n";
9675 CXString clang_getBinaryOperatorKindSpelling(enum CXBinaryOperatorKind kind) {
9676 return cxstring::createRef(
9677 BinaryOperator::getOpcodeStr(static_cast<BinaryOperatorKind>(kind - 1)));
9680 enum CXBinaryOperatorKind clang_getCursorBinaryOperatorKind(CXCursor cursor) {
9681 if (clang_isExpression(cursor.kind)) {
9682 const Expr *expr = getCursorExpr(cursor);
9684 if (const auto *op = dyn_cast<BinaryOperator>(expr))
9685 return static_cast<CXBinaryOperatorKind>(op->getOpcode() + 1);
9687 if (const auto *op = dyn_cast<CXXRewrittenBinaryOperator>(expr))
9688 return static_cast<CXBinaryOperatorKind>(op->getOpcode() + 1);
9691 return CXBinaryOperator_Invalid;
9694 CXString clang_getUnaryOperatorKindSpelling(enum CXUnaryOperatorKind kind) {
9695 return cxstring::createRef(
9696 UnaryOperator::getOpcodeStr(static_cast<UnaryOperatorKind>(kind - 1)));
9699 enum CXUnaryOperatorKind clang_getCursorUnaryOperatorKind(CXCursor cursor) {
9700 if (clang_isExpression(cursor.kind)) {
9701 const Expr *expr = getCursorExpr(cursor);
9703 if (const auto *op = dyn_cast<UnaryOperator>(expr))
9704 return static_cast<CXUnaryOperatorKind>(op->getOpcode() + 1);
9707 return CXUnaryOperator_Invalid;