[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / tools / libclang / CIndex.cpp
blobb3f91ef794ba22615fce08379b102ec1825a49a8
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 "CXSourceLocation.h"
19 #include "CXString.h"
20 #include "CXTranslationUnit.h"
21 #include "CXType.h"
22 #include "CursorVisitor.h"
23 #include "clang-c/FatalErrorHandler.h"
24 #include "clang/AST/Attr.h"
25 #include "clang/AST/DeclObjCCommon.h"
26 #include "clang/AST/Mangle.h"
27 #include "clang/AST/OpenMPClause.h"
28 #include "clang/AST/StmtVisitor.h"
29 #include "clang/Basic/Diagnostic.h"
30 #include "clang/Basic/DiagnosticCategories.h"
31 #include "clang/Basic/DiagnosticIDs.h"
32 #include "clang/Basic/Stack.h"
33 #include "clang/Basic/TargetInfo.h"
34 #include "clang/Basic/Version.h"
35 #include "clang/Frontend/ASTUnit.h"
36 #include "clang/Frontend/CompilerInstance.h"
37 #include "clang/Index/CommentToXML.h"
38 #include "clang/Lex/HeaderSearch.h"
39 #include "clang/Lex/Lexer.h"
40 #include "clang/Lex/PreprocessingRecord.h"
41 #include "clang/Lex/Preprocessor.h"
42 #include "llvm/ADT/Optional.h"
43 #include "llvm/ADT/STLExtras.h"
44 #include "llvm/ADT/StringSwitch.h"
45 #include "llvm/Config/llvm-config.h"
46 #include "llvm/Support/Compiler.h"
47 #include "llvm/Support/CrashRecoveryContext.h"
48 #include "llvm/Support/Format.h"
49 #include "llvm/Support/ManagedStatic.h"
50 #include "llvm/Support/MemoryBuffer.h"
51 #include "llvm/Support/Program.h"
52 #include "llvm/Support/SaveAndRestore.h"
53 #include "llvm/Support/Signals.h"
54 #include "llvm/Support/TargetSelect.h"
55 #include "llvm/Support/Threading.h"
56 #include "llvm/Support/Timer.h"
57 #include "llvm/Support/raw_ostream.h"
58 #include "llvm/Support/thread.h"
59 #include <mutex>
61 #if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62 #define USE_DARWIN_THREADS
63 #endif
65 #ifdef USE_DARWIN_THREADS
66 #include <pthread.h>
67 #endif
69 using namespace clang;
70 using namespace clang::cxcursor;
71 using namespace clang::cxtu;
72 using namespace clang::cxindex;
74 CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,
75 std::unique_ptr<ASTUnit> AU) {
76 if (!AU)
77 return nullptr;
78 assert(CIdx);
79 CXTranslationUnit D = new CXTranslationUnitImpl();
80 D->CIdx = CIdx;
81 D->TheASTUnit = AU.release();
82 D->StringPool = new cxstring::CXStringPool();
83 D->Diagnostics = nullptr;
84 D->OverridenCursorsPool = createOverridenCXCursorsPool();
85 D->CommentToXML = nullptr;
86 D->ParsingOptions = 0;
87 D->Arguments = {};
88 return D;
91 bool cxtu::isASTReadError(ASTUnit *AU) {
92 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
93 DEnd = AU->stored_diag_end();
94 D != DEnd; ++D) {
95 if (D->getLevel() >= DiagnosticsEngine::Error &&
96 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
97 diag::DiagCat_AST_Deserialization_Issue)
98 return true;
100 return false;
103 cxtu::CXTUOwner::~CXTUOwner() {
104 if (TU)
105 clang_disposeTranslationUnit(TU);
108 /// Compare two source ranges to determine their relative position in
109 /// the translation unit.
110 static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1,
111 SourceRange R2) {
112 assert(R1.isValid() && "First range is invalid?");
113 assert(R2.isValid() && "Second range is invalid?");
114 if (R1.getEnd() != R2.getBegin() &&
115 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
116 return RangeBefore;
117 if (R2.getEnd() != R1.getBegin() &&
118 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
119 return RangeAfter;
120 return RangeOverlap;
123 /// Determine if a source location falls within, before, or after a
124 /// a given source range.
125 static RangeComparisonResult LocationCompare(SourceManager &SM,
126 SourceLocation L, SourceRange R) {
127 assert(R.isValid() && "First range is invalid?");
128 assert(L.isValid() && "Second range is invalid?");
129 if (L == R.getBegin() || L == R.getEnd())
130 return RangeOverlap;
131 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
132 return RangeBefore;
133 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
134 return RangeAfter;
135 return RangeOverlap;
138 /// Translate a Clang source range into a CIndex source range.
140 /// Clang internally represents ranges where the end location points to the
141 /// start of the token at the end. However, for external clients it is more
142 /// useful to have a CXSourceRange be a proper half-open interval. This routine
143 /// does the appropriate translation.
144 CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
145 const LangOptions &LangOpts,
146 const CharSourceRange &R) {
147 // We want the last character in this location, so we will adjust the
148 // location accordingly.
149 SourceLocation EndLoc = R.getEnd();
150 bool IsTokenRange = R.isTokenRange();
151 if (EndLoc.isValid() && EndLoc.isMacroID() &&
152 !SM.isMacroArgExpansion(EndLoc)) {
153 CharSourceRange Expansion = SM.getExpansionRange(EndLoc);
154 EndLoc = Expansion.getEnd();
155 IsTokenRange = Expansion.isTokenRange();
157 if (IsTokenRange && EndLoc.isValid()) {
158 unsigned Length =
159 Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);
160 EndLoc = EndLoc.getLocWithOffset(Length);
163 CXSourceRange Result = {
164 {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};
165 return Result;
168 CharSourceRange cxloc::translateCXRangeToCharRange(CXSourceRange R) {
169 return CharSourceRange::getCharRange(
170 SourceLocation::getFromRawEncoding(R.begin_int_data),
171 SourceLocation::getFromRawEncoding(R.end_int_data));
174 //===----------------------------------------------------------------------===//
175 // Cursor visitor.
176 //===----------------------------------------------------------------------===//
178 static SourceRange getRawCursorExtent(CXCursor C);
179 static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
181 RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
182 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
185 /// Visit the given cursor and, if requested by the visitor,
186 /// its children.
188 /// \param Cursor the cursor to visit.
190 /// \param CheckedRegionOfInterest if true, then the caller already checked
191 /// that this cursor is within the region of interest.
193 /// \returns true if the visitation should be aborted, false if it
194 /// should continue.
195 bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
196 if (clang_isInvalid(Cursor.kind))
197 return false;
199 if (clang_isDeclaration(Cursor.kind)) {
200 const Decl *D = getCursorDecl(Cursor);
201 if (!D) {
202 assert(0 && "Invalid declaration cursor");
203 return true; // abort.
206 // Ignore implicit declarations, unless it's an objc method because
207 // currently we should report implicit methods for properties when indexing.
208 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
209 return false;
212 // If we have a range of interest, and this cursor doesn't intersect with it,
213 // we're done.
214 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
215 SourceRange Range = getRawCursorExtent(Cursor);
216 if (Range.isInvalid() || CompareRegionOfInterest(Range))
217 return false;
220 switch (Visitor(Cursor, Parent, ClientData)) {
221 case CXChildVisit_Break:
222 return true;
224 case CXChildVisit_Continue:
225 return false;
227 case CXChildVisit_Recurse: {
228 bool ret = VisitChildren(Cursor);
229 if (PostChildrenVisitor)
230 if (PostChildrenVisitor(Cursor, ClientData))
231 return true;
232 return ret;
236 llvm_unreachable("Invalid CXChildVisitResult!");
239 static bool visitPreprocessedEntitiesInRange(SourceRange R,
240 PreprocessingRecord &PPRec,
241 CursorVisitor &Visitor) {
242 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
243 FileID FID;
245 if (!Visitor.shouldVisitIncludedEntities()) {
246 // If the begin/end of the range lie in the same FileID, do the optimization
247 // where we skip preprocessed entities that do not come from the same
248 // FileID.
249 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
250 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
251 FID = FileID();
254 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
255 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
256 PPRec, FID);
259 bool CursorVisitor::visitFileRegion() {
260 if (RegionOfInterest.isInvalid())
261 return false;
263 ASTUnit *Unit = cxtu::getASTUnit(TU);
264 SourceManager &SM = Unit->getSourceManager();
266 std::pair<FileID, unsigned> Begin = SM.getDecomposedLoc(
267 SM.getFileLoc(RegionOfInterest.getBegin())),
268 End = SM.getDecomposedLoc(
269 SM.getFileLoc(RegionOfInterest.getEnd()));
271 if (End.first != Begin.first) {
272 // If the end does not reside in the same file, try to recover by
273 // picking the end of the file of begin location.
274 End.first = Begin.first;
275 End.second = SM.getFileIDSize(Begin.first);
278 assert(Begin.first == End.first);
279 if (Begin.second > End.second)
280 return false;
282 FileID File = Begin.first;
283 unsigned Offset = Begin.second;
284 unsigned Length = End.second - Begin.second;
286 if (!VisitDeclsOnly && !VisitPreprocessorLast)
287 if (visitPreprocessedEntitiesInRegion())
288 return true; // visitation break.
290 if (visitDeclsFromFileRegion(File, Offset, Length))
291 return true; // visitation break.
293 if (!VisitDeclsOnly && VisitPreprocessorLast)
294 return visitPreprocessedEntitiesInRegion();
296 return false;
299 static bool isInLexicalContext(Decl *D, DeclContext *DC) {
300 if (!DC)
301 return false;
303 for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;
304 DeclDC = DeclDC->getLexicalParent()) {
305 if (DeclDC == DC)
306 return true;
308 return false;
311 bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,
312 unsigned Length) {
313 ASTUnit *Unit = cxtu::getASTUnit(TU);
314 SourceManager &SM = Unit->getSourceManager();
315 SourceRange Range = RegionOfInterest;
317 SmallVector<Decl *, 16> Decls;
318 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 // If we didn't find any file level decls for the file, try looking at the
321 // file that it was included from.
322 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
323 bool Invalid = false;
324 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
325 if (Invalid)
326 return false;
328 SourceLocation Outer;
329 if (SLEntry.isFile())
330 Outer = SLEntry.getFile().getIncludeLoc();
331 else
332 Outer = SLEntry.getExpansion().getExpansionLocStart();
333 if (Outer.isInvalid())
334 return false;
336 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
337 Length = 0;
338 Unit->findFileRegionDecls(File, Offset, Length, Decls);
341 assert(!Decls.empty());
343 bool VisitedAtLeastOnce = false;
344 DeclContext *CurDC = nullptr;
345 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
346 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
347 Decl *D = *DIt;
348 if (D->getSourceRange().isInvalid())
349 continue;
351 if (isInLexicalContext(D, CurDC))
352 continue;
354 CurDC = dyn_cast<DeclContext>(D);
356 if (TagDecl *TD = dyn_cast<TagDecl>(D))
357 if (!TD->isFreeStanding())
358 continue;
360 RangeComparisonResult CompRes =
361 RangeCompare(SM, D->getSourceRange(), Range);
362 if (CompRes == RangeBefore)
363 continue;
364 if (CompRes == RangeAfter)
365 break;
367 assert(CompRes == RangeOverlap);
368 VisitedAtLeastOnce = true;
370 if (isa<ObjCContainerDecl>(D)) {
371 FileDI_current = &DIt;
372 FileDE_current = DE;
373 } else {
374 FileDI_current = nullptr;
377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
381 if (VisitedAtLeastOnce)
382 return false;
384 // No Decls overlapped with the range. Move up the lexical context until there
385 // is a context that contains the range or we reach the translation unit
386 // level.
387 DeclContext *DC = DIt == Decls.begin()
388 ? (*DIt)->getLexicalDeclContext()
389 : (*(DIt - 1))->getLexicalDeclContext();
391 while (DC && !DC->isTranslationUnit()) {
392 Decl *D = cast<Decl>(DC);
393 SourceRange CurDeclRange = D->getSourceRange();
394 if (CurDeclRange.isInvalid())
395 break;
397 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
398 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
399 return true; // visitation break.
402 DC = D->getLexicalDeclContext();
405 return false;
408 bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
409 if (!AU->getPreprocessor().getPreprocessingRecord())
410 return false;
412 PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();
413 SourceManager &SM = AU->getSourceManager();
415 if (RegionOfInterest.isValid()) {
416 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
417 SourceLocation B = MappedRange.getBegin();
418 SourceLocation E = MappedRange.getEnd();
420 if (AU->isInPreambleFileID(B)) {
421 if (SM.isLoadedSourceLocation(E))
422 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,
423 *this);
425 // Beginning of range lies in the preamble but it also extends beyond
426 // it into the main file. Split the range into 2 parts, one covering
427 // the preamble and another covering the main file. This allows subsequent
428 // calls to visitPreprocessedEntitiesInRange to accept a source range that
429 // lies in the same FileID, allowing it to skip preprocessed entities that
430 // do not come from the same FileID.
431 bool breaked = visitPreprocessedEntitiesInRange(
432 SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);
433 if (breaked)
434 return true;
435 return visitPreprocessedEntitiesInRange(
436 SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);
439 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
442 bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
444 if (OnlyLocalDecls)
445 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
446 PPRec);
448 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
451 template <typename InputIterator>
452 bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
453 InputIterator Last,
454 PreprocessingRecord &PPRec,
455 FileID FID) {
456 for (; First != Last; ++First) {
457 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
458 continue;
460 PreprocessedEntity *PPE = *First;
461 if (!PPE)
462 continue;
464 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
465 if (Visit(MakeMacroExpansionCursor(ME, TU)))
466 return true;
468 continue;
471 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
472 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
473 return true;
475 continue;
478 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
479 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
480 return true;
482 continue;
486 return false;
489 /// Visit the children of the given cursor.
491 /// \returns true if the visitation should be aborted, false if it
492 /// should continue.
493 bool CursorVisitor::VisitChildren(CXCursor Cursor) {
494 if (clang_isReference(Cursor.kind) &&
495 Cursor.kind != CXCursor_CXXBaseSpecifier) {
496 // By definition, references have no children.
497 return false;
500 // Set the Parent field to Cursor, then back to its old value once we're
501 // done.
502 SetParentRAII SetParent(Parent, StmtParent, Cursor);
504 if (clang_isDeclaration(Cursor.kind)) {
505 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
506 if (!D)
507 return false;
509 return VisitAttributes(D) || Visit(D);
512 if (clang_isStatement(Cursor.kind)) {
513 if (const Stmt *S = getCursorStmt(Cursor))
514 return Visit(S);
516 return false;
519 if (clang_isExpression(Cursor.kind)) {
520 if (const Expr *E = getCursorExpr(Cursor))
521 return Visit(E);
523 return false;
526 if (clang_isTranslationUnit(Cursor.kind)) {
527 CXTranslationUnit TU = getCursorTU(Cursor);
528 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
530 int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
531 for (unsigned I = 0; I != 2; ++I) {
532 if (VisitOrder[I]) {
533 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
534 RegionOfInterest.isInvalid()) {
535 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
536 TLEnd = CXXUnit->top_level_end();
537 TL != TLEnd; ++TL) {
538 const Optional<bool> V = handleDeclForVisitation(*TL);
539 if (!V)
540 continue;
541 return V.value();
543 } else if (VisitDeclContext(
544 CXXUnit->getASTContext().getTranslationUnitDecl()))
545 return true;
546 continue;
549 // Walk the preprocessing record.
550 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
551 visitPreprocessedEntitiesInRegion();
554 return false;
557 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
558 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
559 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
560 return Visit(BaseTSInfo->getTypeLoc());
565 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
566 const IBOutletCollectionAttr *A =
567 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
568 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
569 return Visit(cxcursor::MakeCursorObjCClassRef(
570 ObjT->getInterface(),
571 A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));
574 // If pointing inside a macro definition, check if the token is an identifier
575 // that was ever defined as a macro. In such a case, create a "pseudo" macro
576 // expansion cursor for that token.
577 SourceLocation BeginLoc = RegionOfInterest.getBegin();
578 if (Cursor.kind == CXCursor_MacroDefinition &&
579 BeginLoc == RegionOfInterest.getEnd()) {
580 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
581 const MacroInfo *MI =
582 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
583 if (MacroDefinitionRecord *MacroDef =
584 checkForMacroInMacroDefinition(MI, Loc, TU))
585 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
588 // Nothing to visit at the moment.
589 return false;
592 bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
593 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
594 if (Visit(TSInfo->getTypeLoc()))
595 return true;
597 if (Stmt *Body = B->getBody())
598 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
600 return false;
603 Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
604 if (RegionOfInterest.isValid()) {
605 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
606 if (Range.isInvalid())
607 return None;
609 switch (CompareRegionOfInterest(Range)) {
610 case RangeBefore:
611 // This declaration comes before the region of interest; skip it.
612 return None;
614 case RangeAfter:
615 // This declaration comes after the region of interest; we're done.
616 return false;
618 case RangeOverlap:
619 // This declaration overlaps the region of interest; visit it.
620 break;
623 return true;
626 bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
627 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
629 // FIXME: Eventually remove. This part of a hack to support proper
630 // iteration over all Decls contained lexically within an ObjC container.
631 SaveAndRestore<DeclContext::decl_iterator *> DI_saved(DI_current, &I);
632 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
634 for (; I != E; ++I) {
635 Decl *D = *I;
636 if (D->getLexicalDeclContext() != DC)
637 continue;
638 // Filter out synthesized property accessor redeclarations.
639 if (isa<ObjCImplDecl>(DC))
640 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
641 if (OMD->isSynthesizedAccessorStub())
642 continue;
643 const Optional<bool> V = handleDeclForVisitation(D);
644 if (!V)
645 continue;
646 return V.value();
648 return false;
651 Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
652 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
654 // Ignore synthesized ivars here, otherwise if we have something like:
655 // @synthesize prop = _prop;
656 // and '_prop' is not declared, we will encounter a '_prop' ivar before
657 // encountering the 'prop' synthesize declaration and we will think that
658 // we passed the region-of-interest.
659 if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
660 if (ivarD->getSynthesize())
661 return None;
664 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
665 // declarations is a mismatch with the compiler semantics.
666 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
667 auto *ID = cast<ObjCInterfaceDecl>(D);
668 if (!ID->isThisDeclarationADefinition())
669 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
671 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
672 auto *PD = cast<ObjCProtocolDecl>(D);
673 if (!PD->isThisDeclarationADefinition())
674 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
677 const Optional<bool> V = shouldVisitCursor(Cursor);
678 if (!V)
679 return None;
680 if (!V.value())
681 return false;
682 if (Visit(Cursor, true))
683 return true;
684 return None;
687 bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
688 llvm_unreachable("Translation units are visited directly by Visit()");
691 bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
692 if (VisitTemplateParameters(D->getTemplateParameters()))
693 return true;
695 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
698 bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
699 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
700 return Visit(TSInfo->getTypeLoc());
702 return false;
705 bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
706 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
707 return Visit(TSInfo->getTypeLoc());
709 return false;
712 bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }
714 bool CursorVisitor::VisitClassTemplateSpecializationDecl(
715 ClassTemplateSpecializationDecl *D) {
716 bool ShouldVisitBody = false;
717 switch (D->getSpecializationKind()) {
718 case TSK_Undeclared:
719 case TSK_ImplicitInstantiation:
720 // Nothing to visit
721 return false;
723 case TSK_ExplicitInstantiationDeclaration:
724 case TSK_ExplicitInstantiationDefinition:
725 break;
727 case TSK_ExplicitSpecialization:
728 ShouldVisitBody = true;
729 break;
732 // Visit the template arguments used in the specialization.
733 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
734 TypeLoc TL = SpecType->getTypeLoc();
735 if (TemplateSpecializationTypeLoc TSTLoc =
736 TL.getAs<TemplateSpecializationTypeLoc>()) {
737 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
738 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
739 return true;
743 return ShouldVisitBody && VisitCXXRecordDecl(D);
746 bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
747 ClassTemplatePartialSpecializationDecl *D) {
748 // FIXME: Visit the "outer" template parameter lists on the TagDecl
749 // before visiting these template parameters.
750 if (VisitTemplateParameters(D->getTemplateParameters()))
751 return true;
753 // Visit the partial specialization arguments.
754 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
755 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
756 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
757 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
758 return true;
760 return VisitCXXRecordDecl(D);
763 bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
764 if (const auto *TC = D->getTypeConstraint()) {
765 if (VisitTypeConstraint(*TC))
766 return true;
769 // Visit the default argument.
770 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
771 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
772 if (Visit(DefArg->getTypeLoc()))
773 return true;
775 return false;
778 bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
779 if (Expr *Init = D->getInitExpr())
780 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
781 return false;
784 bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
785 unsigned NumParamList = DD->getNumTemplateParameterLists();
786 for (unsigned i = 0; i < NumParamList; i++) {
787 TemplateParameterList *Params = DD->getTemplateParameterList(i);
788 if (VisitTemplateParameters(Params))
789 return true;
792 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
793 if (Visit(TSInfo->getTypeLoc()))
794 return true;
796 // Visit the nested-name-specifier, if present.
797 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
798 if (VisitNestedNameSpecifierLoc(QualifierLoc))
799 return true;
801 return false;
804 static bool HasTrailingReturnType(FunctionDecl *ND) {
805 const QualType Ty = ND->getType();
806 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
807 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
808 return FT->hasTrailingReturn();
811 return false;
814 /// Compare two base or member initializers based on their source order.
815 static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
816 CXXCtorInitializer *const *Y) {
817 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
820 bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
821 unsigned NumParamList = ND->getNumTemplateParameterLists();
822 for (unsigned i = 0; i < NumParamList; i++) {
823 TemplateParameterList *Params = ND->getTemplateParameterList(i);
824 if (VisitTemplateParameters(Params))
825 return true;
828 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
829 // Visit the function declaration's syntactic components in the order
830 // written. This requires a bit of work.
831 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
832 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
833 const bool HasTrailingRT = HasTrailingReturnType(ND);
835 // If we have a function declared directly (without the use of a typedef),
836 // visit just the return type. Otherwise, just visit the function's type
837 // now.
838 if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
839 Visit(FTL.getReturnLoc())) ||
840 (!FTL && Visit(TL)))
841 return true;
843 // Visit the nested-name-specifier, if present.
844 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
845 if (VisitNestedNameSpecifierLoc(QualifierLoc))
846 return true;
848 // Visit the declaration name.
849 if (!isa<CXXDestructorDecl>(ND))
850 if (VisitDeclarationNameInfo(ND->getNameInfo()))
851 return true;
853 // FIXME: Visit explicitly-specified template arguments!
855 // Visit the function parameters, if we have a function type.
856 if (FTL && VisitFunctionTypeLoc(FTL, true))
857 return true;
859 // Visit the function's trailing return type.
860 if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
861 return true;
863 // FIXME: Attributes?
866 if (auto *E = ND->getTrailingRequiresClause()) {
867 if (Visit(E))
868 return true;
871 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
872 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
873 // Find the initializers that were written in the source.
874 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
875 for (auto *I : Constructor->inits()) {
876 if (!I->isWritten())
877 continue;
879 WrittenInits.push_back(I);
882 // Sort the initializers in source order
883 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
884 &CompareCXXCtorInitializers);
886 // Visit the initializers in source order
887 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
888 CXXCtorInitializer *Init = WrittenInits[I];
889 if (Init->isAnyMemberInitializer()) {
890 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
891 Init->getMemberLocation(), TU)))
892 return true;
893 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
894 if (Visit(TInfo->getTypeLoc()))
895 return true;
898 // Visit the initializer value.
899 if (Expr *Initializer = Init->getInit())
900 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
901 return true;
905 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
906 return true;
909 return false;
912 bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
913 if (VisitDeclaratorDecl(D))
914 return true;
916 if (Expr *BitWidth = D->getBitWidth())
917 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
919 if (Expr *Init = D->getInClassInitializer())
920 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
922 return false;
925 bool CursorVisitor::VisitVarDecl(VarDecl *D) {
926 if (VisitDeclaratorDecl(D))
927 return true;
929 if (Expr *Init = D->getInit())
930 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
932 return false;
935 bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
936 if (VisitDeclaratorDecl(D))
937 return true;
939 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
940 if (Expr *DefArg = D->getDefaultArgument())
941 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
943 return false;
946 bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
947 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
948 // before visiting these template parameters.
949 if (VisitTemplateParameters(D->getTemplateParameters()))
950 return true;
952 auto *FD = D->getTemplatedDecl();
953 return VisitAttributes(FD) || VisitFunctionDecl(FD);
956 bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
957 // FIXME: Visit the "outer" template parameter lists on the TagDecl
958 // before visiting these template parameters.
959 if (VisitTemplateParameters(D->getTemplateParameters()))
960 return true;
962 auto *CD = D->getTemplatedDecl();
963 return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
966 bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
967 if (VisitTemplateParameters(D->getTemplateParameters()))
968 return true;
970 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
971 VisitTemplateArgumentLoc(D->getDefaultArgument()))
972 return true;
974 return false;
977 bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
978 // Visit the bound, if it's explicit.
979 if (D->hasExplicitBound()) {
980 if (auto TInfo = D->getTypeSourceInfo()) {
981 if (Visit(TInfo->getTypeLoc()))
982 return true;
986 return false;
989 bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
990 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
991 if (Visit(TSInfo->getTypeLoc()))
992 return true;
994 for (const auto *P : ND->parameters()) {
995 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
996 return true;
999 return ND->isThisDeclarationADefinition() &&
1000 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
1003 template <typename DeclIt>
1004 static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
1005 SourceManager &SM, SourceLocation EndLoc,
1006 SmallVectorImpl<Decl *> &Decls) {
1007 DeclIt next = *DI_current;
1008 while (++next != DE_current) {
1009 Decl *D_next = *next;
1010 if (!D_next)
1011 break;
1012 SourceLocation L = D_next->getBeginLoc();
1013 if (!L.isValid())
1014 break;
1015 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
1016 *DI_current = next;
1017 Decls.push_back(D_next);
1018 continue;
1020 break;
1024 bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
1025 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
1026 // an @implementation can lexically contain Decls that are not properly
1027 // nested in the AST. When we identify such cases, we need to retrofit
1028 // this nesting here.
1029 if (!DI_current && !FileDI_current)
1030 return VisitDeclContext(D);
1032 // Scan the Decls that immediately come after the container
1033 // in the current DeclContext. If any fall within the
1034 // container's lexical region, stash them into a vector
1035 // for later processing.
1036 SmallVector<Decl *, 24> DeclsInContainer;
1037 SourceLocation EndLoc = D->getSourceRange().getEnd();
1038 SourceManager &SM = AU->getSourceManager();
1039 if (EndLoc.isValid()) {
1040 if (DI_current) {
1041 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
1042 DeclsInContainer);
1043 } else {
1044 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
1045 DeclsInContainer);
1049 // The common case.
1050 if (DeclsInContainer.empty())
1051 return VisitDeclContext(D);
1053 // Get all the Decls in the DeclContext, and sort them with the
1054 // additional ones we've collected. Then visit them.
1055 for (auto *SubDecl : D->decls()) {
1056 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1057 SubDecl->getBeginLoc().isInvalid())
1058 continue;
1059 DeclsInContainer.push_back(SubDecl);
1062 // Now sort the Decls so that they appear in lexical order.
1063 llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {
1064 SourceLocation L_A = A->getBeginLoc();
1065 SourceLocation L_B = B->getBeginLoc();
1066 return L_A != L_B
1067 ? SM.isBeforeInTranslationUnit(L_A, L_B)
1068 : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());
1071 // Now visit the decls.
1072 for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),
1073 E = DeclsInContainer.end();
1074 I != E; ++I) {
1075 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
1076 const Optional<bool> &V = shouldVisitCursor(Cursor);
1077 if (!V)
1078 continue;
1079 if (!V.value())
1080 return false;
1081 if (Visit(Cursor, true))
1082 return true;
1084 return false;
1087 bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1088 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1089 TU)))
1090 return true;
1092 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1093 return true;
1095 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1096 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1097 E = ND->protocol_end();
1098 I != E; ++I, ++PL)
1099 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1100 return true;
1102 return VisitObjCContainerDecl(ND);
1105 bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1106 if (!PID->isThisDeclarationADefinition())
1107 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1109 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1110 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1111 E = PID->protocol_end();
1112 I != E; ++I, ++PL)
1113 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1114 return true;
1116 return VisitObjCContainerDecl(PID);
1119 bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1120 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1121 return true;
1123 // FIXME: This implements a workaround with @property declarations also being
1124 // installed in the DeclContext for the @interface. Eventually this code
1125 // should be removed.
1126 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1127 if (!CDecl || !CDecl->IsClassExtension())
1128 return false;
1130 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1131 if (!ID)
1132 return false;
1134 IdentifierInfo *PropertyId = PD->getIdentifier();
1135 ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
1136 cast<DeclContext>(ID), PropertyId, PD->getQueryKind());
1138 if (!prevDecl)
1139 return false;
1141 // Visit synthesized methods since they will be skipped when visiting
1142 // the @interface.
1143 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1144 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1145 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1146 return true;
1148 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1149 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1150 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1151 return true;
1153 return false;
1156 bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1157 if (!typeParamList)
1158 return false;
1160 for (auto *typeParam : *typeParamList) {
1161 // Visit the type parameter.
1162 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1163 return true;
1166 return false;
1169 bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1170 if (!D->isThisDeclarationADefinition()) {
1171 // Forward declaration is treated like a reference.
1172 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1175 // Objective-C type parameters.
1176 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1177 return true;
1179 // Issue callbacks for super class.
1180 if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
1181 D->getSuperClass(), D->getSuperClassLoc(), TU)))
1182 return true;
1184 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1185 if (Visit(SuperClassTInfo->getTypeLoc()))
1186 return true;
1188 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1189 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1190 E = D->protocol_end();
1191 I != E; ++I, ++PL)
1192 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1193 return true;
1195 return VisitObjCContainerDecl(D);
1198 bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1199 return VisitObjCContainerDecl(D);
1202 bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1203 // 'ID' could be null when dealing with invalid code.
1204 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1205 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1206 return true;
1208 return VisitObjCImplDecl(D);
1211 bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1212 #if 0
1213 // Issue callbacks for super class.
1214 // FIXME: No source location information!
1215 if (D->getSuperClass() &&
1216 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1217 D->getSuperClassLoc(),
1218 TU)))
1219 return true;
1220 #endif
1222 return VisitObjCImplDecl(D);
1225 bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1226 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1227 if (PD->isIvarNameSpecified())
1228 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1230 return false;
1233 bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1234 return VisitDeclContext(D);
1237 bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1238 // Visit nested-name-specifier.
1239 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1240 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1241 return true;
1243 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1244 D->getTargetNameLoc(), TU));
1247 bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1248 // Visit nested-name-specifier.
1249 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1250 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1251 return true;
1254 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1255 return true;
1257 return VisitDeclarationNameInfo(D->getNameInfo());
1260 bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1261 // Visit nested-name-specifier.
1262 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1263 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1264 return true;
1266 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1267 D->getIdentLocation(), TU));
1270 bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1271 // Visit nested-name-specifier.
1272 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1273 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1274 return true;
1277 return VisitDeclarationNameInfo(D->getNameInfo());
1280 bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1281 UnresolvedUsingTypenameDecl *D) {
1282 // Visit nested-name-specifier.
1283 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1284 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1285 return true;
1287 return false;
1290 bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
1291 if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
1292 return true;
1293 if (StringLiteral *Message = D->getMessage())
1294 if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
1295 return true;
1296 return false;
1299 bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {
1300 if (NamedDecl *FriendD = D->getFriendDecl()) {
1301 if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))
1302 return true;
1303 } else if (TypeSourceInfo *TI = D->getFriendType()) {
1304 if (Visit(TI->getTypeLoc()))
1305 return true;
1307 return false;
1310 bool CursorVisitor::VisitDecompositionDecl(DecompositionDecl *D) {
1311 for (auto *B : D->bindings()) {
1312 if (Visit(MakeCXCursor(B, TU, RegionOfInterest)))
1313 return true;
1315 return VisitVarDecl(D);
1318 bool CursorVisitor::VisitConceptDecl(ConceptDecl *D) {
1319 if (VisitTemplateParameters(D->getTemplateParameters()))
1320 return true;
1322 if (auto *E = D->getConstraintExpr()) {
1323 if (Visit(MakeCXCursor(E, D, TU, RegionOfInterest)))
1324 return true;
1326 return false;
1329 bool CursorVisitor::VisitTypeConstraint(const TypeConstraint &TC) {
1330 if (TC.getNestedNameSpecifierLoc()) {
1331 if (VisitNestedNameSpecifierLoc(TC.getNestedNameSpecifierLoc()))
1332 return true;
1334 if (TC.getNamedConcept()) {
1335 if (Visit(MakeCursorTemplateRef(TC.getNamedConcept(),
1336 TC.getConceptNameLoc(), TU)))
1337 return true;
1339 if (auto Args = TC.getTemplateArgsAsWritten()) {
1340 for (const auto &Arg : Args->arguments()) {
1341 if (VisitTemplateArgumentLoc(Arg))
1342 return true;
1345 return false;
1348 bool CursorVisitor::VisitConceptRequirement(const concepts::Requirement &R) {
1349 using namespace concepts;
1350 switch (R.getKind()) {
1351 case Requirement::RK_Type: {
1352 const TypeRequirement &TR = cast<TypeRequirement>(R);
1353 if (!TR.isSubstitutionFailure()) {
1354 if (Visit(TR.getType()->getTypeLoc()))
1355 return true;
1357 break;
1359 case Requirement::RK_Simple:
1360 case Requirement::RK_Compound: {
1361 const ExprRequirement &ER = cast<ExprRequirement>(R);
1362 if (!ER.isExprSubstitutionFailure()) {
1363 if (Visit(ER.getExpr()))
1364 return true;
1366 if (ER.getKind() == Requirement::RK_Compound) {
1367 const auto &RTR = ER.getReturnTypeRequirement();
1368 if (RTR.isTypeConstraint()) {
1369 if (const auto *Cons = RTR.getTypeConstraint())
1370 VisitTypeConstraint(*Cons);
1373 break;
1375 case Requirement::RK_Nested: {
1376 const NestedRequirement &NR = cast<NestedRequirement>(R);
1377 if (!NR.isSubstitutionFailure()) {
1378 if (Visit(NR.getConstraintExpr()))
1379 return true;
1381 break;
1384 return false;
1387 bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1388 switch (Name.getName().getNameKind()) {
1389 case clang::DeclarationName::Identifier:
1390 case clang::DeclarationName::CXXLiteralOperatorName:
1391 case clang::DeclarationName::CXXDeductionGuideName:
1392 case clang::DeclarationName::CXXOperatorName:
1393 case clang::DeclarationName::CXXUsingDirective:
1394 return false;
1396 case clang::DeclarationName::CXXConstructorName:
1397 case clang::DeclarationName::CXXDestructorName:
1398 case clang::DeclarationName::CXXConversionFunctionName:
1399 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1400 return Visit(TSInfo->getTypeLoc());
1401 return false;
1403 case clang::DeclarationName::ObjCZeroArgSelector:
1404 case clang::DeclarationName::ObjCOneArgSelector:
1405 case clang::DeclarationName::ObjCMultiArgSelector:
1406 // FIXME: Per-identifier location info?
1407 return false;
1410 llvm_unreachable("Invalid DeclarationName::Kind!");
1413 bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1414 SourceRange Range) {
1415 // FIXME: This whole routine is a hack to work around the lack of proper
1416 // source information in nested-name-specifiers (PR5791). Since we do have
1417 // a beginning source location, we can visit the first component of the
1418 // nested-name-specifier, if it's a single-token component.
1419 if (!NNS)
1420 return false;
1422 // Get the first component in the nested-name-specifier.
1423 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1424 NNS = Prefix;
1426 switch (NNS->getKind()) {
1427 case NestedNameSpecifier::Namespace:
1428 return Visit(
1429 MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
1431 case NestedNameSpecifier::NamespaceAlias:
1432 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1433 Range.getBegin(), TU));
1435 case NestedNameSpecifier::TypeSpec: {
1436 // If the type has a form where we know that the beginning of the source
1437 // range matches up with a reference cursor. Visit the appropriate reference
1438 // cursor.
1439 const Type *T = NNS->getAsType();
1440 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1441 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1442 if (const TagType *Tag = dyn_cast<TagType>(T))
1443 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1444 if (const TemplateSpecializationType *TST =
1445 dyn_cast<TemplateSpecializationType>(T))
1446 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1447 break;
1450 case NestedNameSpecifier::TypeSpecWithTemplate:
1451 case NestedNameSpecifier::Global:
1452 case NestedNameSpecifier::Identifier:
1453 case NestedNameSpecifier::Super:
1454 break;
1457 return false;
1460 bool CursorVisitor::VisitNestedNameSpecifierLoc(
1461 NestedNameSpecifierLoc Qualifier) {
1462 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1463 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1464 Qualifiers.push_back(Qualifier);
1466 while (!Qualifiers.empty()) {
1467 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1468 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1469 switch (NNS->getKind()) {
1470 case NestedNameSpecifier::Namespace:
1471 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1472 Q.getLocalBeginLoc(), TU)))
1473 return true;
1475 break;
1477 case NestedNameSpecifier::NamespaceAlias:
1478 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1479 Q.getLocalBeginLoc(), TU)))
1480 return true;
1482 break;
1484 case NestedNameSpecifier::TypeSpec:
1485 case NestedNameSpecifier::TypeSpecWithTemplate:
1486 if (Visit(Q.getTypeLoc()))
1487 return true;
1489 break;
1491 case NestedNameSpecifier::Global:
1492 case NestedNameSpecifier::Identifier:
1493 case NestedNameSpecifier::Super:
1494 break;
1498 return false;
1501 bool CursorVisitor::VisitTemplateParameters(
1502 const TemplateParameterList *Params) {
1503 if (!Params)
1504 return false;
1506 for (TemplateParameterList::const_iterator P = Params->begin(),
1507 PEnd = Params->end();
1508 P != PEnd; ++P) {
1509 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1510 return true;
1513 if (const auto *E = Params->getRequiresClause()) {
1514 if (Visit(MakeCXCursor(E, nullptr, TU, RegionOfInterest)))
1515 return true;
1518 return false;
1521 bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1522 switch (Name.getKind()) {
1523 case TemplateName::Template:
1524 case TemplateName::UsingTemplate:
1525 case TemplateName::QualifiedTemplate: // FIXME: Visit nested-name-specifier.
1526 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1528 case TemplateName::OverloadedTemplate:
1529 // Visit the overloaded template set.
1530 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1531 return true;
1533 return false;
1535 case TemplateName::AssumedTemplate:
1536 // FIXME: Visit DeclarationName?
1537 return false;
1539 case TemplateName::DependentTemplate:
1540 // FIXME: Visit nested-name-specifier.
1541 return false;
1543 case TemplateName::SubstTemplateTemplateParm:
1544 return Visit(MakeCursorTemplateRef(
1545 Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));
1547 case TemplateName::SubstTemplateTemplateParmPack:
1548 return Visit(MakeCursorTemplateRef(
1549 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
1550 TU));
1553 llvm_unreachable("Invalid TemplateName::Kind!");
1556 bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1557 switch (TAL.getArgument().getKind()) {
1558 case TemplateArgument::Null:
1559 case TemplateArgument::Integral:
1560 case TemplateArgument::Pack:
1561 return false;
1563 case TemplateArgument::Type:
1564 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1565 return Visit(TSInfo->getTypeLoc());
1566 return false;
1568 case TemplateArgument::Declaration:
1569 if (Expr *E = TAL.getSourceDeclExpression())
1570 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1571 return false;
1573 case TemplateArgument::NullPtr:
1574 if (Expr *E = TAL.getSourceNullPtrExpression())
1575 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1576 return false;
1578 case TemplateArgument::Expression:
1579 if (Expr *E = TAL.getSourceExpression())
1580 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1581 return false;
1583 case TemplateArgument::Template:
1584 case TemplateArgument::TemplateExpansion:
1585 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1586 return true;
1588 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1589 TAL.getTemplateNameLoc());
1592 llvm_unreachable("Invalid TemplateArgument::Kind!");
1595 bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1596 return VisitDeclContext(D);
1599 bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1600 return Visit(TL.getUnqualifiedLoc());
1603 bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1604 ASTContext &Context = AU->getASTContext();
1606 // Some builtin types (such as Objective-C's "id", "sel", and
1607 // "Class") have associated declarations. Create cursors for those.
1608 QualType VisitType;
1609 switch (TL.getTypePtr()->getKind()) {
1611 case BuiltinType::Void:
1612 case BuiltinType::NullPtr:
1613 case BuiltinType::Dependent:
1614 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
1615 case BuiltinType::Id:
1616 #include "clang/Basic/OpenCLImageTypes.def"
1617 #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
1618 #include "clang/Basic/OpenCLExtensionTypes.def"
1619 case BuiltinType::OCLSampler:
1620 case BuiltinType::OCLEvent:
1621 case BuiltinType::OCLClkEvent:
1622 case BuiltinType::OCLQueue:
1623 case BuiltinType::OCLReserveID:
1624 #define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1625 #include "clang/Basic/AArch64SVEACLETypes.def"
1626 #define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
1627 #include "clang/Basic/PPCTypes.def"
1628 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1629 #include "clang/Basic/RISCVVTypes.def"
1630 #define BUILTIN_TYPE(Id, SingletonId)
1631 #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1632 #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1633 #define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1634 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1635 #include "clang/AST/BuiltinTypes.def"
1636 break;
1638 case BuiltinType::ObjCId:
1639 VisitType = Context.getObjCIdType();
1640 break;
1642 case BuiltinType::ObjCClass:
1643 VisitType = Context.getObjCClassType();
1644 break;
1646 case BuiltinType::ObjCSel:
1647 VisitType = Context.getObjCSelType();
1648 break;
1651 if (!VisitType.isNull()) {
1652 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1653 return Visit(
1654 MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
1657 return false;
1660 bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1661 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1664 bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1665 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1668 bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1669 if (TL.isDefinition())
1670 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1672 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1675 bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1676 if (const auto *TC = TL.getDecl()->getTypeConstraint()) {
1677 if (VisitTypeConstraint(*TC))
1678 return true;
1681 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1684 bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1685 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
1688 bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
1689 if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
1690 return true;
1691 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1692 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1693 TU)))
1694 return true;
1697 return false;
1700 bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1701 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1702 return true;
1704 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1705 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1706 return true;
1709 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1710 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1711 TU)))
1712 return true;
1715 return false;
1718 bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1719 return Visit(TL.getPointeeLoc());
1722 bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1723 return Visit(TL.getInnerLoc());
1726 bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
1727 return Visit(TL.getInnerLoc());
1730 bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1731 return Visit(TL.getPointeeLoc());
1734 bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1735 return Visit(TL.getPointeeLoc());
1738 bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1739 return Visit(TL.getPointeeLoc());
1742 bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1743 return Visit(TL.getPointeeLoc());
1746 bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1747 return Visit(TL.getPointeeLoc());
1750 bool CursorVisitor::VisitUsingTypeLoc(UsingTypeLoc TL) { return false; }
1752 bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1753 return Visit(TL.getModifiedLoc());
1756 bool CursorVisitor::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL) {
1757 return Visit(TL.getWrappedLoc());
1760 bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1761 bool SkipResultType) {
1762 if (!SkipResultType && Visit(TL.getReturnLoc()))
1763 return true;
1765 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1766 if (Decl *D = TL.getParam(I))
1767 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1768 return true;
1770 return false;
1773 bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1774 if (Visit(TL.getElementLoc()))
1775 return true;
1777 if (Expr *Size = TL.getSizeExpr())
1778 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1780 return false;
1783 bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1784 return Visit(TL.getOriginalLoc());
1787 bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1788 return Visit(TL.getOriginalLoc());
1791 bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
1792 DeducedTemplateSpecializationTypeLoc TL) {
1793 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1794 TL.getTemplateNameLoc()))
1795 return true;
1797 return false;
1800 bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1801 TemplateSpecializationTypeLoc TL) {
1802 // Visit the template name.
1803 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1804 TL.getTemplateNameLoc()))
1805 return true;
1807 // Visit the template arguments.
1808 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1809 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1810 return true;
1812 return false;
1815 bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1816 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1819 bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1820 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1821 return Visit(TSInfo->getTypeLoc());
1823 return false;
1826 bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1827 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1828 return Visit(TSInfo->getTypeLoc());
1830 return false;
1833 bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1834 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
1837 bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1838 DependentTemplateSpecializationTypeLoc TL) {
1839 // Visit the nested-name-specifier, if there is one.
1840 if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1841 return true;
1843 // Visit the template arguments.
1844 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1845 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1846 return true;
1848 return false;
1851 bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1852 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1853 return true;
1855 return Visit(TL.getNamedTypeLoc());
1858 bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1859 return Visit(TL.getPatternLoc());
1862 bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1863 if (Expr *E = TL.getUnderlyingExpr())
1864 return Visit(MakeCXCursor(E, StmtParent, TU));
1866 return false;
1869 bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1870 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1873 bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1874 return Visit(TL.getValueLoc());
1877 bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1878 return Visit(TL.getValueLoc());
1881 #define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1882 bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1883 return Visit##PARENT##Loc(TL); \
1886 DEFAULT_TYPELOC_IMPL(Complex, Type)
1887 DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1888 DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1889 DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1890 DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1891 DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
1892 DEFAULT_TYPELOC_IMPL(DependentVector, Type)
1893 DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1894 DEFAULT_TYPELOC_IMPL(Vector, Type)
1895 DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1896 DEFAULT_TYPELOC_IMPL(ConstantMatrix, MatrixType)
1897 DEFAULT_TYPELOC_IMPL(DependentSizedMatrix, MatrixType)
1898 DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1899 DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1900 DEFAULT_TYPELOC_IMPL(Record, TagType)
1901 DEFAULT_TYPELOC_IMPL(Enum, TagType)
1902 DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1903 DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1904 DEFAULT_TYPELOC_IMPL(Auto, Type)
1905 DEFAULT_TYPELOC_IMPL(BitInt, Type)
1906 DEFAULT_TYPELOC_IMPL(DependentBitInt, Type)
1908 bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1909 // Visit the nested-name-specifier, if present.
1910 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1911 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1912 return true;
1914 if (D->isCompleteDefinition()) {
1915 for (const auto &I : D->bases()) {
1916 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
1917 return true;
1921 return VisitTagDecl(D);
1924 bool CursorVisitor::VisitAttributes(Decl *D) {
1925 for (const auto *I : D->attrs())
1926 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1927 !I->isImplicit()) &&
1928 Visit(MakeCXCursor(I, D, TU)))
1929 return true;
1931 return false;
1934 //===----------------------------------------------------------------------===//
1935 // Data-recursive visitor methods.
1936 //===----------------------------------------------------------------------===//
1938 namespace {
1939 #define DEF_JOB(NAME, DATA, KIND) \
1940 class NAME : public VisitorJob { \
1941 public: \
1942 NAME(const DATA *d, CXCursor parent) \
1943 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1944 static bool classof(const VisitorJob *VJ) { \
1945 return VJ->getKind() == KIND; \
1947 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1950 DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1951 DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1952 DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1953 DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1954 DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1955 DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1956 DEF_JOB(ConceptSpecializationExprVisit, ConceptSpecializationExpr,
1957 ConceptSpecializationExprVisitKind)
1958 DEF_JOB(RequiresExprVisit, RequiresExpr, RequiresExprVisitKind)
1959 DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1960 #undef DEF_JOB
1962 class ExplicitTemplateArgsVisit : public VisitorJob {
1963 public:
1964 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1965 const TemplateArgumentLoc *End, CXCursor parent)
1966 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1967 End) {}
1968 static bool classof(const VisitorJob *VJ) {
1969 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1971 const TemplateArgumentLoc *begin() const {
1972 return static_cast<const TemplateArgumentLoc *>(data[0]);
1974 const TemplateArgumentLoc *end() {
1975 return static_cast<const TemplateArgumentLoc *>(data[1]);
1978 class DeclVisit : public VisitorJob {
1979 public:
1980 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1981 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1982 isFirst ? (void *)1 : (void *)nullptr) {}
1983 static bool classof(const VisitorJob *VJ) {
1984 return VJ->getKind() == DeclVisitKind;
1986 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
1987 bool isFirst() const { return data[1] != nullptr; }
1989 class TypeLocVisit : public VisitorJob {
1990 public:
1991 TypeLocVisit(TypeLoc tl, CXCursor parent)
1992 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1993 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1995 static bool classof(const VisitorJob *VJ) {
1996 return VJ->getKind() == TypeLocVisitKind;
1999 TypeLoc get() const {
2000 QualType T = QualType::getFromOpaquePtr(data[0]);
2001 return TypeLoc(T, const_cast<void *>(data[1]));
2005 class LabelRefVisit : public VisitorJob {
2006 public:
2007 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
2008 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
2009 labelLoc.getPtrEncoding()) {}
2011 static bool classof(const VisitorJob *VJ) {
2012 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
2014 const LabelDecl *get() const {
2015 return static_cast<const LabelDecl *>(data[0]);
2017 SourceLocation getLoc() const {
2018 return SourceLocation::getFromPtrEncoding(data[1]);
2022 class NestedNameSpecifierLocVisit : public VisitorJob {
2023 public:
2024 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
2025 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
2026 Qualifier.getNestedNameSpecifier(),
2027 Qualifier.getOpaqueData()) {}
2029 static bool classof(const VisitorJob *VJ) {
2030 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
2033 NestedNameSpecifierLoc get() const {
2034 return NestedNameSpecifierLoc(
2035 const_cast<NestedNameSpecifier *>(
2036 static_cast<const NestedNameSpecifier *>(data[0])),
2037 const_cast<void *>(data[1]));
2041 class DeclarationNameInfoVisit : public VisitorJob {
2042 public:
2043 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
2044 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
2045 static bool classof(const VisitorJob *VJ) {
2046 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
2048 DeclarationNameInfo get() const {
2049 const Stmt *S = static_cast<const Stmt *>(data[0]);
2050 switch (S->getStmtClass()) {
2051 default:
2052 llvm_unreachable("Unhandled Stmt");
2053 case clang::Stmt::MSDependentExistsStmtClass:
2054 return cast<MSDependentExistsStmt>(S)->getNameInfo();
2055 case Stmt::CXXDependentScopeMemberExprClass:
2056 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
2057 case Stmt::DependentScopeDeclRefExprClass:
2058 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
2059 case Stmt::OMPCriticalDirectiveClass:
2060 return cast<OMPCriticalDirective>(S)->getDirectiveName();
2064 class MemberRefVisit : public VisitorJob {
2065 public:
2066 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
2067 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
2068 L.getPtrEncoding()) {}
2069 static bool classof(const VisitorJob *VJ) {
2070 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
2072 const FieldDecl *get() const {
2073 return static_cast<const FieldDecl *>(data[0]);
2075 SourceLocation getLoc() const {
2076 return SourceLocation::getFromRawEncoding(
2077 (SourceLocation::UIntTy)(uintptr_t)data[1]);
2080 class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
2081 friend class OMPClauseEnqueue;
2082 VisitorWorkList &WL;
2083 CXCursor Parent;
2085 public:
2086 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
2087 : WL(wl), Parent(parent) {}
2089 void VisitAddrLabelExpr(const AddrLabelExpr *E);
2090 void VisitBlockExpr(const BlockExpr *B);
2091 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
2092 void VisitCompoundStmt(const CompoundStmt *S);
2093 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
2095 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
2096 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
2097 void VisitCXXNewExpr(const CXXNewExpr *E);
2098 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
2099 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
2100 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
2101 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
2102 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
2103 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
2104 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
2105 void VisitCXXCatchStmt(const CXXCatchStmt *S);
2106 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
2107 void VisitDeclRefExpr(const DeclRefExpr *D);
2108 void VisitDeclStmt(const DeclStmt *S);
2109 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
2110 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
2111 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
2112 void VisitForStmt(const ForStmt *FS);
2113 void VisitGotoStmt(const GotoStmt *GS);
2114 void VisitIfStmt(const IfStmt *If);
2115 void VisitInitListExpr(const InitListExpr *IE);
2116 void VisitMemberExpr(const MemberExpr *M);
2117 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2118 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2119 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2120 void VisitOverloadExpr(const OverloadExpr *E);
2121 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2122 void VisitStmt(const Stmt *S);
2123 void VisitSwitchStmt(const SwitchStmt *S);
2124 void VisitWhileStmt(const WhileStmt *W);
2125 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2126 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2127 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2128 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2129 void VisitVAArgExpr(const VAArgExpr *E);
2130 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2131 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2132 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2133 void VisitLambdaExpr(const LambdaExpr *E);
2134 void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *E);
2135 void VisitRequiresExpr(const RequiresExpr *E);
2136 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
2137 void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D);
2138 void VisitOMPLoopDirective(const OMPLoopDirective *D);
2139 void VisitOMPParallelDirective(const OMPParallelDirective *D);
2140 void VisitOMPSimdDirective(const OMPSimdDirective *D);
2141 void
2142 VisitOMPLoopTransformationDirective(const OMPLoopTransformationDirective *D);
2143 void VisitOMPTileDirective(const OMPTileDirective *D);
2144 void VisitOMPUnrollDirective(const OMPUnrollDirective *D);
2145 void VisitOMPForDirective(const OMPForDirective *D);
2146 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
2147 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
2148 void VisitOMPSectionDirective(const OMPSectionDirective *D);
2149 void VisitOMPSingleDirective(const OMPSingleDirective *D);
2150 void VisitOMPMasterDirective(const OMPMasterDirective *D);
2151 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
2152 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
2153 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
2154 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
2155 void VisitOMPParallelMaskedDirective(const OMPParallelMaskedDirective *D);
2156 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
2157 void VisitOMPTaskDirective(const OMPTaskDirective *D);
2158 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
2159 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
2160 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
2161 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
2162 void
2163 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
2164 void VisitOMPCancelDirective(const OMPCancelDirective *D);
2165 void VisitOMPFlushDirective(const OMPFlushDirective *D);
2166 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
2167 void VisitOMPScanDirective(const OMPScanDirective *D);
2168 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
2169 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
2170 void VisitOMPTargetDirective(const OMPTargetDirective *D);
2171 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
2172 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
2173 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
2174 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
2175 void
2176 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
2177 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
2178 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
2179 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
2180 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
2181 void VisitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective *D);
2182 void
2183 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
2184 void VisitOMPMaskedTaskLoopSimdDirective(
2185 const OMPMaskedTaskLoopSimdDirective *D);
2186 void VisitOMPParallelMasterTaskLoopDirective(
2187 const OMPParallelMasterTaskLoopDirective *D);
2188 void VisitOMPParallelMaskedTaskLoopDirective(
2189 const OMPParallelMaskedTaskLoopDirective *D);
2190 void VisitOMPParallelMasterTaskLoopSimdDirective(
2191 const OMPParallelMasterTaskLoopSimdDirective *D);
2192 void VisitOMPParallelMaskedTaskLoopSimdDirective(
2193 const OMPParallelMaskedTaskLoopSimdDirective *D);
2194 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
2195 void VisitOMPDistributeParallelForDirective(
2196 const OMPDistributeParallelForDirective *D);
2197 void VisitOMPDistributeParallelForSimdDirective(
2198 const OMPDistributeParallelForSimdDirective *D);
2199 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
2200 void VisitOMPTargetParallelForSimdDirective(
2201 const OMPTargetParallelForSimdDirective *D);
2202 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
2203 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
2204 void VisitOMPTeamsDistributeSimdDirective(
2205 const OMPTeamsDistributeSimdDirective *D);
2206 void VisitOMPTeamsDistributeParallelForSimdDirective(
2207 const OMPTeamsDistributeParallelForSimdDirective *D);
2208 void VisitOMPTeamsDistributeParallelForDirective(
2209 const OMPTeamsDistributeParallelForDirective *D);
2210 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
2211 void VisitOMPTargetTeamsDistributeDirective(
2212 const OMPTargetTeamsDistributeDirective *D);
2213 void VisitOMPTargetTeamsDistributeParallelForDirective(
2214 const OMPTargetTeamsDistributeParallelForDirective *D);
2215 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2216 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
2217 void VisitOMPTargetTeamsDistributeSimdDirective(
2218 const OMPTargetTeamsDistributeSimdDirective *D);
2220 private:
2221 void AddDeclarationNameInfo(const Stmt *S);
2222 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
2223 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2224 unsigned NumTemplateArgs);
2225 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2226 void AddStmt(const Stmt *S);
2227 void AddDecl(const Decl *D, bool isFirst = true);
2228 void AddTypeLoc(TypeSourceInfo *TI);
2229 void EnqueueChildren(const Stmt *S);
2230 void EnqueueChildren(const OMPClause *S);
2232 } // namespace
2234 void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
2235 // 'S' should always be non-null, since it comes from the
2236 // statement we are visiting.
2237 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2240 void EnqueueVisitor::AddNestedNameSpecifierLoc(
2241 NestedNameSpecifierLoc Qualifier) {
2242 if (Qualifier)
2243 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2246 void EnqueueVisitor::AddStmt(const Stmt *S) {
2247 if (S)
2248 WL.push_back(StmtVisit(S, Parent));
2250 void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
2251 if (D)
2252 WL.push_back(DeclVisit(D, Parent, isFirst));
2254 void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2255 unsigned NumTemplateArgs) {
2256 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
2258 void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
2259 if (D)
2260 WL.push_back(MemberRefVisit(D, L, Parent));
2262 void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2263 if (TI)
2264 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
2266 void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
2267 unsigned size = WL.size();
2268 for (const Stmt *SubStmt : S->children()) {
2269 AddStmt(SubStmt);
2271 if (size == WL.size())
2272 return;
2273 // Now reverse the entries we just added. This will match the DFS
2274 // ordering performed by the worklist.
2275 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2276 std::reverse(I, E);
2278 namespace {
2279 class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2280 EnqueueVisitor *Visitor;
2281 /// Process clauses with list of variables.
2282 template <typename T> void VisitOMPClauseList(T *Node);
2284 public:
2285 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
2286 #define GEN_CLANG_CLAUSE_CLASS
2287 #define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2288 #include "llvm/Frontend/OpenMP/OMP.inc"
2289 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
2290 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
2293 void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2294 const OMPClauseWithPreInit *C) {
2295 Visitor->AddStmt(C->getPreInitStmt());
2298 void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2299 const OMPClauseWithPostUpdate *C) {
2300 VisitOMPClauseWithPreInit(C);
2301 Visitor->AddStmt(C->getPostUpdateExpr());
2304 void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2305 VisitOMPClauseWithPreInit(C);
2306 Visitor->AddStmt(C->getCondition());
2309 void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2310 Visitor->AddStmt(C->getCondition());
2313 void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2314 VisitOMPClauseWithPreInit(C);
2315 Visitor->AddStmt(C->getNumThreads());
2318 void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2319 Visitor->AddStmt(C->getSafelen());
2322 void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2323 Visitor->AddStmt(C->getSimdlen());
2326 void OMPClauseEnqueue::VisitOMPSizesClause(const OMPSizesClause *C) {
2327 for (auto E : C->getSizesRefs())
2328 Visitor->AddStmt(E);
2331 void OMPClauseEnqueue::VisitOMPFullClause(const OMPFullClause *C) {}
2333 void OMPClauseEnqueue::VisitOMPPartialClause(const OMPPartialClause *C) {
2334 Visitor->AddStmt(C->getFactor());
2337 void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2338 Visitor->AddStmt(C->getAllocator());
2341 void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2342 Visitor->AddStmt(C->getNumForLoops());
2345 void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
2347 void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
2349 void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2350 VisitOMPClauseWithPreInit(C);
2351 Visitor->AddStmt(C->getChunkSize());
2354 void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2355 Visitor->AddStmt(C->getNumForLoops());
2358 void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2359 Visitor->AddStmt(C->getEventHandler());
2362 void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2364 void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2366 void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2368 void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2370 void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2372 void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2374 void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2376 void OMPClauseEnqueue::VisitOMPCompareClause(const OMPCompareClause *) {}
2378 void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2380 void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2382 void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2384 void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2386 void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2388 void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2390 void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2392 void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2394 void OMPClauseEnqueue::VisitOMPInitClause(const OMPInitClause *C) {
2395 VisitOMPClauseList(C);
2398 void OMPClauseEnqueue::VisitOMPUseClause(const OMPUseClause *C) {
2399 Visitor->AddStmt(C->getInteropVar());
2402 void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *C) {
2403 if (C->getInteropVar())
2404 Visitor->AddStmt(C->getInteropVar());
2407 void OMPClauseEnqueue::VisitOMPNovariantsClause(const OMPNovariantsClause *C) {
2408 Visitor->AddStmt(C->getCondition());
2411 void OMPClauseEnqueue::VisitOMPNocontextClause(const OMPNocontextClause *C) {
2412 Visitor->AddStmt(C->getCondition());
2415 void OMPClauseEnqueue::VisitOMPFilterClause(const OMPFilterClause *C) {
2416 VisitOMPClauseWithPreInit(C);
2417 Visitor->AddStmt(C->getThreadID());
2420 void OMPClauseEnqueue::VisitOMPAlignClause(const OMPAlignClause *C) {
2421 Visitor->AddStmt(C->getAlignment());
2424 void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2425 const OMPUnifiedAddressClause *) {}
2427 void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2428 const OMPUnifiedSharedMemoryClause *) {}
2430 void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2431 const OMPReverseOffloadClause *) {}
2433 void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2434 const OMPDynamicAllocatorsClause *) {}
2436 void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2437 const OMPAtomicDefaultMemOrderClause *) {}
2439 void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2440 Visitor->AddStmt(C->getDevice());
2443 void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
2444 VisitOMPClauseWithPreInit(C);
2445 Visitor->AddStmt(C->getNumTeams());
2448 void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2449 const OMPThreadLimitClause *C) {
2450 VisitOMPClauseWithPreInit(C);
2451 Visitor->AddStmt(C->getThreadLimit());
2454 void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2455 Visitor->AddStmt(C->getPriority());
2458 void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2459 Visitor->AddStmt(C->getGrainsize());
2462 void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2463 Visitor->AddStmt(C->getNumTasks());
2466 void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2467 Visitor->AddStmt(C->getHint());
2470 template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
2471 for (const auto *I : Node->varlists()) {
2472 Visitor->AddStmt(I);
2476 void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2477 VisitOMPClauseList(C);
2479 void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2480 VisitOMPClauseList(C);
2482 void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2483 VisitOMPClauseList(C);
2484 Visitor->AddStmt(C->getAllocator());
2486 void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
2487 VisitOMPClauseList(C);
2488 for (const auto *E : C->private_copies()) {
2489 Visitor->AddStmt(E);
2492 void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2493 const OMPFirstprivateClause *C) {
2494 VisitOMPClauseList(C);
2495 VisitOMPClauseWithPreInit(C);
2496 for (const auto *E : C->private_copies()) {
2497 Visitor->AddStmt(E);
2499 for (const auto *E : C->inits()) {
2500 Visitor->AddStmt(E);
2503 void OMPClauseEnqueue::VisitOMPLastprivateClause(
2504 const OMPLastprivateClause *C) {
2505 VisitOMPClauseList(C);
2506 VisitOMPClauseWithPostUpdate(C);
2507 for (auto *E : C->private_copies()) {
2508 Visitor->AddStmt(E);
2510 for (auto *E : C->source_exprs()) {
2511 Visitor->AddStmt(E);
2513 for (auto *E : C->destination_exprs()) {
2514 Visitor->AddStmt(E);
2516 for (auto *E : C->assignment_ops()) {
2517 Visitor->AddStmt(E);
2520 void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
2521 VisitOMPClauseList(C);
2523 void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2524 VisitOMPClauseList(C);
2525 VisitOMPClauseWithPostUpdate(C);
2526 for (auto *E : C->privates()) {
2527 Visitor->AddStmt(E);
2529 for (auto *E : C->lhs_exprs()) {
2530 Visitor->AddStmt(E);
2532 for (auto *E : C->rhs_exprs()) {
2533 Visitor->AddStmt(E);
2535 for (auto *E : C->reduction_ops()) {
2536 Visitor->AddStmt(E);
2538 if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
2539 for (auto *E : C->copy_ops()) {
2540 Visitor->AddStmt(E);
2542 for (auto *E : C->copy_array_temps()) {
2543 Visitor->AddStmt(E);
2545 for (auto *E : C->copy_array_elems()) {
2546 Visitor->AddStmt(E);
2550 void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2551 const OMPTaskReductionClause *C) {
2552 VisitOMPClauseList(C);
2553 VisitOMPClauseWithPostUpdate(C);
2554 for (auto *E : C->privates()) {
2555 Visitor->AddStmt(E);
2557 for (auto *E : C->lhs_exprs()) {
2558 Visitor->AddStmt(E);
2560 for (auto *E : C->rhs_exprs()) {
2561 Visitor->AddStmt(E);
2563 for (auto *E : C->reduction_ops()) {
2564 Visitor->AddStmt(E);
2567 void OMPClauseEnqueue::VisitOMPInReductionClause(
2568 const OMPInReductionClause *C) {
2569 VisitOMPClauseList(C);
2570 VisitOMPClauseWithPostUpdate(C);
2571 for (auto *E : C->privates()) {
2572 Visitor->AddStmt(E);
2574 for (auto *E : C->lhs_exprs()) {
2575 Visitor->AddStmt(E);
2577 for (auto *E : C->rhs_exprs()) {
2578 Visitor->AddStmt(E);
2580 for (auto *E : C->reduction_ops()) {
2581 Visitor->AddStmt(E);
2583 for (auto *E : C->taskgroup_descriptors())
2584 Visitor->AddStmt(E);
2586 void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2587 VisitOMPClauseList(C);
2588 VisitOMPClauseWithPostUpdate(C);
2589 for (const auto *E : C->privates()) {
2590 Visitor->AddStmt(E);
2592 for (const auto *E : C->inits()) {
2593 Visitor->AddStmt(E);
2595 for (const auto *E : C->updates()) {
2596 Visitor->AddStmt(E);
2598 for (const auto *E : C->finals()) {
2599 Visitor->AddStmt(E);
2601 Visitor->AddStmt(C->getStep());
2602 Visitor->AddStmt(C->getCalcStep());
2604 void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2605 VisitOMPClauseList(C);
2606 Visitor->AddStmt(C->getAlignment());
2608 void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2609 VisitOMPClauseList(C);
2610 for (auto *E : C->source_exprs()) {
2611 Visitor->AddStmt(E);
2613 for (auto *E : C->destination_exprs()) {
2614 Visitor->AddStmt(E);
2616 for (auto *E : C->assignment_ops()) {
2617 Visitor->AddStmt(E);
2620 void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2621 const OMPCopyprivateClause *C) {
2622 VisitOMPClauseList(C);
2623 for (auto *E : C->source_exprs()) {
2624 Visitor->AddStmt(E);
2626 for (auto *E : C->destination_exprs()) {
2627 Visitor->AddStmt(E);
2629 for (auto *E : C->assignment_ops()) {
2630 Visitor->AddStmt(E);
2633 void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2634 VisitOMPClauseList(C);
2636 void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2637 Visitor->AddStmt(C->getDepobj());
2639 void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2640 VisitOMPClauseList(C);
2642 void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2643 VisitOMPClauseList(C);
2645 void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2646 const OMPDistScheduleClause *C) {
2647 VisitOMPClauseWithPreInit(C);
2648 Visitor->AddStmt(C->getChunkSize());
2650 void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2651 const OMPDefaultmapClause * /*C*/) {}
2652 void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2653 VisitOMPClauseList(C);
2655 void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2656 VisitOMPClauseList(C);
2658 void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2659 const OMPUseDevicePtrClause *C) {
2660 VisitOMPClauseList(C);
2662 void OMPClauseEnqueue::VisitOMPUseDeviceAddrClause(
2663 const OMPUseDeviceAddrClause *C) {
2664 VisitOMPClauseList(C);
2666 void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2667 const OMPIsDevicePtrClause *C) {
2668 VisitOMPClauseList(C);
2670 void OMPClauseEnqueue::VisitOMPHasDeviceAddrClause(
2671 const OMPHasDeviceAddrClause *C) {
2672 VisitOMPClauseList(C);
2674 void OMPClauseEnqueue::VisitOMPNontemporalClause(
2675 const OMPNontemporalClause *C) {
2676 VisitOMPClauseList(C);
2677 for (const auto *E : C->private_refs())
2678 Visitor->AddStmt(E);
2680 void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
2681 void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
2682 const OMPUsesAllocatorsClause *C) {
2683 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
2684 const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);
2685 Visitor->AddStmt(D.Allocator);
2686 Visitor->AddStmt(D.AllocatorTraits);
2689 void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) {
2690 Visitor->AddStmt(C->getModifier());
2691 for (const Expr *E : C->varlists())
2692 Visitor->AddStmt(E);
2694 void OMPClauseEnqueue::VisitOMPBindClause(const OMPBindClause *C) {}
2696 } // namespace
2698 void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2699 unsigned size = WL.size();
2700 OMPClauseEnqueue Visitor(this);
2701 Visitor.Visit(S);
2702 if (size == WL.size())
2703 return;
2704 // Now reverse the entries we just added. This will match the DFS
2705 // ordering performed by the worklist.
2706 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2707 std::reverse(I, E);
2709 void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
2710 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2712 void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
2713 AddDecl(B->getBlockDecl());
2715 void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
2716 EnqueueChildren(E);
2717 AddTypeLoc(E->getTypeSourceInfo());
2719 void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
2720 for (auto &I : llvm::reverse(S->body()))
2721 AddStmt(I);
2723 void EnqueueVisitor::VisitMSDependentExistsStmt(
2724 const MSDependentExistsStmt *S) {
2725 AddStmt(S->getSubStmt());
2726 AddDeclarationNameInfo(S);
2727 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2728 AddNestedNameSpecifierLoc(QualifierLoc);
2731 void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2732 const CXXDependentScopeMemberExpr *E) {
2733 if (E->hasExplicitTemplateArgs())
2734 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2735 AddDeclarationNameInfo(E);
2736 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2737 AddNestedNameSpecifierLoc(QualifierLoc);
2738 if (!E->isImplicitAccess())
2739 AddStmt(E->getBase());
2741 void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
2742 // Enqueue the initializer , if any.
2743 AddStmt(E->getInitializer());
2744 // Enqueue the array size, if any.
2745 AddStmt(E->getArraySize().value_or(nullptr));
2746 // Enqueue the allocated type.
2747 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2748 // Enqueue the placement arguments.
2749 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2750 AddStmt(E->getPlacementArg(I - 1));
2752 void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
2753 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2754 AddStmt(CE->getArg(I - 1));
2755 AddStmt(CE->getCallee());
2756 AddStmt(CE->getArg(0));
2758 void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2759 const CXXPseudoDestructorExpr *E) {
2760 // Visit the name of the type being destroyed.
2761 AddTypeLoc(E->getDestroyedTypeInfo());
2762 // Visit the scope type that looks disturbingly like the nested-name-specifier
2763 // but isn't.
2764 AddTypeLoc(E->getScopeTypeInfo());
2765 // Visit the nested-name-specifier.
2766 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2767 AddNestedNameSpecifierLoc(QualifierLoc);
2768 // Visit base expression.
2769 AddStmt(E->getBase());
2771 void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2772 const CXXScalarValueInitExpr *E) {
2773 AddTypeLoc(E->getTypeSourceInfo());
2775 void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2776 const CXXTemporaryObjectExpr *E) {
2777 EnqueueChildren(E);
2778 AddTypeLoc(E->getTypeSourceInfo());
2780 void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
2781 EnqueueChildren(E);
2782 if (E->isTypeOperand())
2783 AddTypeLoc(E->getTypeOperandSourceInfo());
2786 void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2787 const CXXUnresolvedConstructExpr *E) {
2788 EnqueueChildren(E);
2789 AddTypeLoc(E->getTypeSourceInfo());
2791 void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
2792 EnqueueChildren(E);
2793 if (E->isTypeOperand())
2794 AddTypeLoc(E->getTypeOperandSourceInfo());
2797 void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
2798 EnqueueChildren(S);
2799 AddDecl(S->getExceptionDecl());
2802 void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
2803 AddStmt(S->getBody());
2804 AddStmt(S->getRangeInit());
2805 AddDecl(S->getLoopVariable());
2808 void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
2809 if (DR->hasExplicitTemplateArgs())
2810 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
2811 WL.push_back(DeclRefExprParts(DR, Parent));
2813 void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2814 const DependentScopeDeclRefExpr *E) {
2815 if (E->hasExplicitTemplateArgs())
2816 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2817 AddDeclarationNameInfo(E);
2818 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2820 void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
2821 unsigned size = WL.size();
2822 bool isFirst = true;
2823 for (const auto *D : S->decls()) {
2824 AddDecl(D, isFirst);
2825 isFirst = false;
2827 if (size == WL.size())
2828 return;
2829 // Now reverse the entries we just added. This will match the DFS
2830 // ordering performed by the worklist.
2831 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2832 std::reverse(I, E);
2834 void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
2835 AddStmt(E->getInit());
2836 for (const DesignatedInitExpr::Designator &D :
2837 llvm::reverse(E->designators())) {
2838 if (D.isFieldDesignator()) {
2839 if (FieldDecl *Field = D.getField())
2840 AddMemberRef(Field, D.getFieldLoc());
2841 continue;
2843 if (D.isArrayDesignator()) {
2844 AddStmt(E->getArrayIndex(D));
2845 continue;
2847 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2848 AddStmt(E->getArrayRangeEnd(D));
2849 AddStmt(E->getArrayRangeStart(D));
2852 void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
2853 EnqueueChildren(E);
2854 AddTypeLoc(E->getTypeInfoAsWritten());
2856 void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
2857 AddStmt(FS->getBody());
2858 AddStmt(FS->getInc());
2859 AddStmt(FS->getCond());
2860 AddDecl(FS->getConditionVariable());
2861 AddStmt(FS->getInit());
2863 void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
2864 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2866 void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
2867 AddStmt(If->getElse());
2868 AddStmt(If->getThen());
2869 AddStmt(If->getCond());
2870 AddStmt(If->getInit());
2871 AddDecl(If->getConditionVariable());
2873 void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
2874 // We care about the syntactic form of the initializer list, only.
2875 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2876 IE = Syntactic;
2877 EnqueueChildren(IE);
2879 void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
2880 WL.push_back(MemberExprParts(M, Parent));
2882 // If the base of the member access expression is an implicit 'this', don't
2883 // visit it.
2884 // FIXME: If we ever want to show these implicit accesses, this will be
2885 // unfortunate. However, clang_getCursor() relies on this behavior.
2886 if (M->isImplicitAccess())
2887 return;
2889 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2890 // real field that we are interested in.
2891 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2892 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2893 if (FD->isAnonymousStructOrUnion()) {
2894 AddStmt(SubME->getBase());
2895 return;
2900 AddStmt(M->getBase());
2902 void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
2903 AddTypeLoc(E->getEncodedTypeSourceInfo());
2905 void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
2906 EnqueueChildren(M);
2907 AddTypeLoc(M->getClassReceiverTypeInfo());
2909 void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
2910 // Visit the components of the offsetof expression.
2911 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2912 const OffsetOfNode &Node = E->getComponent(I - 1);
2913 switch (Node.getKind()) {
2914 case OffsetOfNode::Array:
2915 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2916 break;
2917 case OffsetOfNode::Field:
2918 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2919 break;
2920 case OffsetOfNode::Identifier:
2921 case OffsetOfNode::Base:
2922 continue;
2925 // Visit the type into which we're computing the offset.
2926 AddTypeLoc(E->getTypeSourceInfo());
2928 void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
2929 if (E->hasExplicitTemplateArgs())
2930 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
2931 WL.push_back(OverloadExprParts(E, Parent));
2933 void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
2934 const UnaryExprOrTypeTraitExpr *E) {
2935 EnqueueChildren(E);
2936 if (E->isArgumentType())
2937 AddTypeLoc(E->getArgumentTypeInfo());
2939 void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
2940 void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
2941 AddStmt(S->getBody());
2942 AddStmt(S->getCond());
2943 AddDecl(S->getConditionVariable());
2946 void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
2947 AddStmt(W->getBody());
2948 AddStmt(W->getCond());
2949 AddDecl(W->getConditionVariable());
2952 void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
2953 for (unsigned I = E->getNumArgs(); I > 0; --I)
2954 AddTypeLoc(E->getArg(I - 1));
2957 void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
2958 AddTypeLoc(E->getQueriedTypeSourceInfo());
2961 void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
2962 EnqueueChildren(E);
2965 void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
2966 VisitOverloadExpr(U);
2967 if (!U->isImplicitAccess())
2968 AddStmt(U->getBase());
2970 void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
2971 AddStmt(E->getSubExpr());
2972 AddTypeLoc(E->getWrittenTypeInfo());
2974 void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
2975 WL.push_back(SizeOfPackExprParts(E, Parent));
2977 void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
2978 // If the opaque value has a source expression, just transparently
2979 // visit that. This is useful for (e.g.) pseudo-object expressions.
2980 if (Expr *SourceExpr = E->getSourceExpr())
2981 return Visit(SourceExpr);
2983 void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
2984 AddStmt(E->getBody());
2985 WL.push_back(LambdaExprParts(E, Parent));
2987 void EnqueueVisitor::VisitConceptSpecializationExpr(
2988 const ConceptSpecializationExpr *E) {
2989 WL.push_back(ConceptSpecializationExprVisit(E, Parent));
2991 void EnqueueVisitor::VisitRequiresExpr(const RequiresExpr *E) {
2992 WL.push_back(RequiresExprVisit(E, Parent));
2993 for (ParmVarDecl *VD : E->getLocalParameters())
2994 AddDecl(VD);
2996 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
2997 // Treat the expression like its syntactic form.
2998 Visit(E->getSyntacticForm());
3001 void EnqueueVisitor::VisitOMPExecutableDirective(
3002 const OMPExecutableDirective *D) {
3003 EnqueueChildren(D);
3004 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
3005 E = D->clauses().end();
3006 I != E; ++I)
3007 EnqueueChildren(*I);
3010 void EnqueueVisitor::VisitOMPLoopBasedDirective(
3011 const OMPLoopBasedDirective *D) {
3012 VisitOMPExecutableDirective(D);
3015 void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
3016 VisitOMPLoopBasedDirective(D);
3019 void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
3020 VisitOMPExecutableDirective(D);
3023 void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
3024 VisitOMPLoopDirective(D);
3027 void EnqueueVisitor::VisitOMPLoopTransformationDirective(
3028 const OMPLoopTransformationDirective *D) {
3029 VisitOMPLoopBasedDirective(D);
3032 void EnqueueVisitor::VisitOMPTileDirective(const OMPTileDirective *D) {
3033 VisitOMPLoopTransformationDirective(D);
3036 void EnqueueVisitor::VisitOMPUnrollDirective(const OMPUnrollDirective *D) {
3037 VisitOMPLoopTransformationDirective(D);
3040 void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
3041 VisitOMPLoopDirective(D);
3044 void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
3045 VisitOMPLoopDirective(D);
3048 void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
3049 VisitOMPExecutableDirective(D);
3052 void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
3053 VisitOMPExecutableDirective(D);
3056 void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
3057 VisitOMPExecutableDirective(D);
3060 void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
3061 VisitOMPExecutableDirective(D);
3064 void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
3065 VisitOMPExecutableDirective(D);
3066 AddDeclarationNameInfo(D);
3069 void EnqueueVisitor::VisitOMPParallelForDirective(
3070 const OMPParallelForDirective *D) {
3071 VisitOMPLoopDirective(D);
3074 void EnqueueVisitor::VisitOMPParallelForSimdDirective(
3075 const OMPParallelForSimdDirective *D) {
3076 VisitOMPLoopDirective(D);
3079 void EnqueueVisitor::VisitOMPParallelMasterDirective(
3080 const OMPParallelMasterDirective *D) {
3081 VisitOMPExecutableDirective(D);
3084 void EnqueueVisitor::VisitOMPParallelMaskedDirective(
3085 const OMPParallelMaskedDirective *D) {
3086 VisitOMPExecutableDirective(D);
3089 void EnqueueVisitor::VisitOMPParallelSectionsDirective(
3090 const OMPParallelSectionsDirective *D) {
3091 VisitOMPExecutableDirective(D);
3094 void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
3095 VisitOMPExecutableDirective(D);
3098 void EnqueueVisitor::VisitOMPTaskyieldDirective(
3099 const OMPTaskyieldDirective *D) {
3100 VisitOMPExecutableDirective(D);
3103 void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
3104 VisitOMPExecutableDirective(D);
3107 void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
3108 VisitOMPExecutableDirective(D);
3111 void EnqueueVisitor::VisitOMPTaskgroupDirective(
3112 const OMPTaskgroupDirective *D) {
3113 VisitOMPExecutableDirective(D);
3114 if (const Expr *E = D->getReductionRef())
3115 VisitStmt(E);
3118 void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
3119 VisitOMPExecutableDirective(D);
3122 void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
3123 VisitOMPExecutableDirective(D);
3126 void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
3127 VisitOMPExecutableDirective(D);
3130 void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
3131 VisitOMPExecutableDirective(D);
3134 void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
3135 VisitOMPExecutableDirective(D);
3138 void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
3139 VisitOMPExecutableDirective(D);
3142 void EnqueueVisitor::VisitOMPTargetDataDirective(
3143 const OMPTargetDataDirective *D) {
3144 VisitOMPExecutableDirective(D);
3147 void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
3148 const OMPTargetEnterDataDirective *D) {
3149 VisitOMPExecutableDirective(D);
3152 void EnqueueVisitor::VisitOMPTargetExitDataDirective(
3153 const OMPTargetExitDataDirective *D) {
3154 VisitOMPExecutableDirective(D);
3157 void EnqueueVisitor::VisitOMPTargetParallelDirective(
3158 const OMPTargetParallelDirective *D) {
3159 VisitOMPExecutableDirective(D);
3162 void EnqueueVisitor::VisitOMPTargetParallelForDirective(
3163 const OMPTargetParallelForDirective *D) {
3164 VisitOMPLoopDirective(D);
3167 void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
3168 VisitOMPExecutableDirective(D);
3171 void EnqueueVisitor::VisitOMPCancellationPointDirective(
3172 const OMPCancellationPointDirective *D) {
3173 VisitOMPExecutableDirective(D);
3176 void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
3177 VisitOMPExecutableDirective(D);
3180 void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
3181 VisitOMPLoopDirective(D);
3184 void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
3185 const OMPTaskLoopSimdDirective *D) {
3186 VisitOMPLoopDirective(D);
3189 void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
3190 const OMPMasterTaskLoopDirective *D) {
3191 VisitOMPLoopDirective(D);
3194 void EnqueueVisitor::VisitOMPMaskedTaskLoopDirective(
3195 const OMPMaskedTaskLoopDirective *D) {
3196 VisitOMPLoopDirective(D);
3199 void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
3200 const OMPMasterTaskLoopSimdDirective *D) {
3201 VisitOMPLoopDirective(D);
3204 void EnqueueVisitor::VisitOMPMaskedTaskLoopSimdDirective(
3205 const OMPMaskedTaskLoopSimdDirective *D) {
3206 VisitOMPLoopDirective(D);
3209 void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
3210 const OMPParallelMasterTaskLoopDirective *D) {
3211 VisitOMPLoopDirective(D);
3214 void EnqueueVisitor::VisitOMPParallelMaskedTaskLoopDirective(
3215 const OMPParallelMaskedTaskLoopDirective *D) {
3216 VisitOMPLoopDirective(D);
3219 void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
3220 const OMPParallelMasterTaskLoopSimdDirective *D) {
3221 VisitOMPLoopDirective(D);
3224 void EnqueueVisitor::VisitOMPParallelMaskedTaskLoopSimdDirective(
3225 const OMPParallelMaskedTaskLoopSimdDirective *D) {
3226 VisitOMPLoopDirective(D);
3229 void EnqueueVisitor::VisitOMPDistributeDirective(
3230 const OMPDistributeDirective *D) {
3231 VisitOMPLoopDirective(D);
3234 void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
3235 const OMPDistributeParallelForDirective *D) {
3236 VisitOMPLoopDirective(D);
3239 void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
3240 const OMPDistributeParallelForSimdDirective *D) {
3241 VisitOMPLoopDirective(D);
3244 void EnqueueVisitor::VisitOMPDistributeSimdDirective(
3245 const OMPDistributeSimdDirective *D) {
3246 VisitOMPLoopDirective(D);
3249 void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
3250 const OMPTargetParallelForSimdDirective *D) {
3251 VisitOMPLoopDirective(D);
3254 void EnqueueVisitor::VisitOMPTargetSimdDirective(
3255 const OMPTargetSimdDirective *D) {
3256 VisitOMPLoopDirective(D);
3259 void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3260 const OMPTeamsDistributeDirective *D) {
3261 VisitOMPLoopDirective(D);
3264 void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3265 const OMPTeamsDistributeSimdDirective *D) {
3266 VisitOMPLoopDirective(D);
3269 void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3270 const OMPTeamsDistributeParallelForSimdDirective *D) {
3271 VisitOMPLoopDirective(D);
3274 void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3275 const OMPTeamsDistributeParallelForDirective *D) {
3276 VisitOMPLoopDirective(D);
3279 void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3280 const OMPTargetTeamsDirective *D) {
3281 VisitOMPExecutableDirective(D);
3284 void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3285 const OMPTargetTeamsDistributeDirective *D) {
3286 VisitOMPLoopDirective(D);
3289 void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3290 const OMPTargetTeamsDistributeParallelForDirective *D) {
3291 VisitOMPLoopDirective(D);
3294 void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3295 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3296 VisitOMPLoopDirective(D);
3299 void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3300 const OMPTargetTeamsDistributeSimdDirective *D) {
3301 VisitOMPLoopDirective(D);
3304 void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
3305 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3306 .Visit(S);
3309 bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3310 if (RegionOfInterest.isValid()) {
3311 SourceRange Range = getRawCursorExtent(C);
3312 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3313 return false;
3315 return true;
3318 bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3319 while (!WL.empty()) {
3320 // Dequeue the worklist item.
3321 VisitorJob LI = WL.pop_back_val();
3323 // Set the Parent field, then back to its old value once we're done.
3324 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
3326 switch (LI.getKind()) {
3327 case VisitorJob::DeclVisitKind: {
3328 const Decl *D = cast<DeclVisit>(&LI)->get();
3329 if (!D)
3330 continue;
3332 // For now, perform default visitation for Decls.
3333 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3334 cast<DeclVisit>(&LI)->isFirst())))
3335 return true;
3337 continue;
3339 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3340 for (const TemplateArgumentLoc &Arg :
3341 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3342 if (VisitTemplateArgumentLoc(Arg))
3343 return true;
3345 continue;
3347 case VisitorJob::TypeLocVisitKind: {
3348 // Perform default visitation for TypeLocs.
3349 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3350 return true;
3351 continue;
3353 case VisitorJob::LabelRefVisitKind: {
3354 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3355 if (LabelStmt *stmt = LS->getStmt()) {
3356 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3357 TU))) {
3358 return true;
3361 continue;
3364 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3365 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3366 if (VisitNestedNameSpecifierLoc(V->get()))
3367 return true;
3368 continue;
3371 case VisitorJob::DeclarationNameInfoVisitKind: {
3372 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3373 return true;
3374 continue;
3376 case VisitorJob::MemberRefVisitKind: {
3377 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3378 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3379 return true;
3380 continue;
3382 case VisitorJob::StmtVisitKind: {
3383 const Stmt *S = cast<StmtVisit>(&LI)->get();
3384 if (!S)
3385 continue;
3387 // Update the current cursor.
3388 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3389 if (!IsInRegionOfInterest(Cursor))
3390 continue;
3391 switch (Visitor(Cursor, Parent, ClientData)) {
3392 case CXChildVisit_Break:
3393 return true;
3394 case CXChildVisit_Continue:
3395 break;
3396 case CXChildVisit_Recurse:
3397 if (PostChildrenVisitor)
3398 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3399 EnqueueWorkList(WL, S);
3400 break;
3402 continue;
3404 case VisitorJob::MemberExprPartsKind: {
3405 // Handle the other pieces in the MemberExpr besides the base.
3406 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
3408 // Visit the nested-name-specifier
3409 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3410 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3411 return true;
3413 // Visit the declaration name.
3414 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3415 return true;
3417 // Visit the explicitly-specified template arguments, if any.
3418 if (M->hasExplicitTemplateArgs()) {
3419 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3420 *ArgEnd = Arg + M->getNumTemplateArgs();
3421 Arg != ArgEnd; ++Arg) {
3422 if (VisitTemplateArgumentLoc(*Arg))
3423 return true;
3426 continue;
3428 case VisitorJob::DeclRefExprPartsKind: {
3429 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3430 // Visit nested-name-specifier, if present.
3431 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3432 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3433 return true;
3434 // Visit declaration name.
3435 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3436 return true;
3437 continue;
3439 case VisitorJob::OverloadExprPartsKind: {
3440 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3441 // Visit the nested-name-specifier.
3442 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3443 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3444 return true;
3445 // Visit the declaration name.
3446 if (VisitDeclarationNameInfo(O->getNameInfo()))
3447 return true;
3448 // Visit the overloaded declaration reference.
3449 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3450 return true;
3451 continue;
3453 case VisitorJob::SizeOfPackExprPartsKind: {
3454 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3455 NamedDecl *Pack = E->getPack();
3456 if (isa<TemplateTypeParmDecl>(Pack)) {
3457 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3458 E->getPackLoc(), TU)))
3459 return true;
3461 continue;
3464 if (isa<TemplateTemplateParmDecl>(Pack)) {
3465 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3466 E->getPackLoc(), TU)))
3467 return true;
3469 continue;
3472 // Non-type template parameter packs and function parameter packs are
3473 // treated like DeclRefExpr cursors.
3474 continue;
3477 case VisitorJob::LambdaExprPartsKind: {
3478 // Visit non-init captures.
3479 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3480 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3481 CEnd = E->explicit_capture_end();
3482 C != CEnd; ++C) {
3483 if (!C->capturesVariable())
3484 continue;
3485 // TODO: handle structured bindings here ?
3486 if (!isa<VarDecl>(C->getCapturedVar()))
3487 continue;
3488 if (Visit(MakeCursorVariableRef(cast<VarDecl>(C->getCapturedVar()),
3489 C->getLocation(), TU)))
3490 return true;
3492 // Visit init captures
3493 for (auto InitExpr : E->capture_inits()) {
3494 if (InitExpr && Visit(InitExpr))
3495 return true;
3498 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3499 // Visit parameters and return type, if present.
3500 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3501 if (E->hasExplicitParameters()) {
3502 // Visit parameters.
3503 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3504 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3505 return true;
3507 if (E->hasExplicitResultType()) {
3508 // Visit result type.
3509 if (Visit(Proto.getReturnLoc()))
3510 return true;
3513 break;
3516 case VisitorJob::ConceptSpecializationExprVisitKind: {
3517 const ConceptSpecializationExpr *E =
3518 cast<ConceptSpecializationExprVisit>(&LI)->get();
3519 if (NestedNameSpecifierLoc QualifierLoc =
3520 E->getNestedNameSpecifierLoc()) {
3521 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3522 return true;
3525 if (E->getNamedConcept() &&
3526 Visit(MakeCursorTemplateRef(E->getNamedConcept(),
3527 E->getConceptNameLoc(), TU)))
3528 return true;
3530 if (auto Args = E->getTemplateArgsAsWritten()) {
3531 for (const auto &Arg : Args->arguments()) {
3532 if (VisitTemplateArgumentLoc(Arg))
3533 return true;
3536 break;
3539 case VisitorJob::RequiresExprVisitKind: {
3540 const RequiresExpr *E = cast<RequiresExprVisit>(&LI)->get();
3541 for (const concepts::Requirement *R : E->getRequirements())
3542 VisitConceptRequirement(*R);
3543 break;
3546 case VisitorJob::PostChildrenVisitKind:
3547 if (PostChildrenVisitor(Parent, ClientData))
3548 return true;
3549 break;
3552 return false;
3555 bool CursorVisitor::Visit(const Stmt *S) {
3556 VisitorWorkList *WL = nullptr;
3557 if (!WorkListFreeList.empty()) {
3558 WL = WorkListFreeList.back();
3559 WL->clear();
3560 WorkListFreeList.pop_back();
3561 } else {
3562 WL = new VisitorWorkList();
3563 WorkListCache.push_back(WL);
3565 EnqueueWorkList(*WL, S);
3566 bool result = RunVisitorWorkList(*WL);
3567 WorkListFreeList.push_back(WL);
3568 return result;
3571 namespace {
3572 typedef SmallVector<SourceRange, 4> RefNamePieces;
3573 RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3574 const DeclarationNameInfo &NI, SourceRange QLoc,
3575 const SourceRange *TemplateArgsLoc = nullptr) {
3576 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3577 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3578 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
3580 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
3582 RefNamePieces Pieces;
3584 if (WantQualifier && QLoc.isValid())
3585 Pieces.push_back(QLoc);
3587 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3588 Pieces.push_back(NI.getLoc());
3590 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3591 Pieces.push_back(*TemplateArgsLoc);
3593 if (Kind == DeclarationName::CXXOperatorName) {
3594 Pieces.push_back(NI.getInfo().getCXXOperatorNameBeginLoc());
3595 Pieces.push_back(NI.getInfo().getCXXOperatorNameEndLoc());
3598 if (WantSinglePiece) {
3599 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3600 Pieces.clear();
3601 Pieces.push_back(R);
3604 return Pieces;
3606 } // namespace
3608 //===----------------------------------------------------------------------===//
3609 // Misc. API hooks.
3610 //===----------------------------------------------------------------------===//
3612 namespace {
3613 struct RegisterFatalErrorHandler {
3614 RegisterFatalErrorHandler() {
3615 clang_install_aborting_llvm_fatal_error_handler();
3618 } // namespace
3620 static llvm::ManagedStatic<RegisterFatalErrorHandler>
3621 RegisterFatalErrorHandlerOnce;
3623 CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3624 int displayDiagnostics) {
3625 // We use crash recovery to make some of our APIs more reliable, implicitly
3626 // enable it.
3627 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3628 llvm::CrashRecoveryContext::Enable();
3630 // Look through the managed static to trigger construction of the managed
3631 // static which registers our fatal error handler. This ensures it is only
3632 // registered once.
3633 (void)*RegisterFatalErrorHandlerOnce;
3635 // Initialize targets for clang module support.
3636 llvm::InitializeAllTargets();
3637 llvm::InitializeAllTargetMCs();
3638 llvm::InitializeAllAsmPrinters();
3639 llvm::InitializeAllAsmParsers();
3641 CIndexer *CIdxr = new CIndexer();
3643 if (excludeDeclarationsFromPCH)
3644 CIdxr->setOnlyLocalDecls();
3645 if (displayDiagnostics)
3646 CIdxr->setDisplayDiagnostics();
3648 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3649 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3650 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3651 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3652 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3653 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3655 return CIdxr;
3658 void clang_disposeIndex(CXIndex CIdx) {
3659 if (CIdx)
3660 delete static_cast<CIndexer *>(CIdx);
3663 void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3664 if (CIdx)
3665 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3668 unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3669 if (CIdx)
3670 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3671 return 0;
3674 void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
3675 const char *Path) {
3676 if (CIdx)
3677 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
3680 void clang_toggleCrashRecovery(unsigned isEnabled) {
3681 if (isEnabled)
3682 llvm::CrashRecoveryContext::Enable();
3683 else
3684 llvm::CrashRecoveryContext::Disable();
3687 CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3688 const char *ast_filename) {
3689 CXTranslationUnit TU;
3690 enum CXErrorCode Result =
3691 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
3692 (void)Result;
3693 assert((TU && Result == CXError_Success) ||
3694 (!TU && Result != CXError_Success));
3695 return TU;
3698 enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3699 const char *ast_filename,
3700 CXTranslationUnit *out_TU) {
3701 if (out_TU)
3702 *out_TU = nullptr;
3704 if (!CIdx || !ast_filename || !out_TU)
3705 return CXError_InvalidArguments;
3707 LOG_FUNC_SECTION { *Log << ast_filename; }
3709 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3710 FileSystemOptions FileSystemOpts;
3712 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3713 CompilerInstance::createDiagnostics(new DiagnosticOptions());
3714 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
3715 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
3716 ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3717 CXXIdx->getOnlyLocalDecls(), CaptureDiagsKind::All,
3718 /*AllowASTWithCompilerErrors=*/true,
3719 /*UserFilesAreVolatile=*/true);
3720 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
3721 return *out_TU ? CXError_Success : CXError_Failure;
3724 unsigned clang_defaultEditingTranslationUnitOptions() {
3725 return CXTranslationUnit_PrecompiledPreamble |
3726 CXTranslationUnit_CacheCompletionResults;
3729 CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3730 CXIndex CIdx, const char *source_filename, int num_command_line_args,
3731 const char *const *command_line_args, unsigned num_unsaved_files,
3732 struct CXUnsavedFile *unsaved_files) {
3733 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3734 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3735 num_command_line_args, unsaved_files,
3736 num_unsaved_files, Options);
3739 static CXErrorCode
3740 clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3741 const char *const *command_line_args,
3742 int num_command_line_args,
3743 ArrayRef<CXUnsavedFile> unsaved_files,
3744 unsigned options, CXTranslationUnit *out_TU) {
3745 // Set up the initial return values.
3746 if (out_TU)
3747 *out_TU = nullptr;
3749 // Check arguments.
3750 if (!CIdx || !out_TU)
3751 return CXError_InvalidArguments;
3753 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3755 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3756 setThreadBackgroundPriority();
3758 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3759 bool CreatePreambleOnFirstParse =
3760 options & CXTranslationUnit_CreatePreambleOnFirstParse;
3761 // FIXME: Add a flag for modules.
3762 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3763 CXTranslationUnit_SingleFileParse))
3764 ? TU_Prefix
3765 : TU_Complete;
3766 bool CacheCodeCompletionResults =
3767 options & CXTranslationUnit_CacheCompletionResults;
3768 bool IncludeBriefCommentsInCodeCompletion =
3769 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3770 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
3771 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3772 bool RetainExcludedCB =
3773 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
3774 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
3775 if (options & CXTranslationUnit_SkipFunctionBodies) {
3776 SkipFunctionBodies =
3777 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
3778 ? SkipFunctionBodiesScope::Preamble
3779 : SkipFunctionBodiesScope::PreambleAndMainFile;
3782 // Configure the diagnostics.
3783 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3784 CompilerInstance::createDiagnostics(new DiagnosticOptions));
3786 if (options & CXTranslationUnit_KeepGoing)
3787 Diags->setFatalsAsError(true);
3789 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
3790 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
3791 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
3793 // Recover resources if we crash before exiting this function.
3794 llvm::CrashRecoveryContextCleanupRegistrar<
3795 DiagnosticsEngine,
3796 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
3797 DiagCleanup(Diags.get());
3799 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3800 new std::vector<ASTUnit::RemappedFile>());
3802 // Recover resources if we crash before exiting this function.
3803 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3804 RemappedCleanup(RemappedFiles.get());
3806 for (auto &UF : unsaved_files) {
3807 std::unique_ptr<llvm::MemoryBuffer> MB =
3808 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
3809 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
3812 std::unique_ptr<std::vector<const char *>> Args(
3813 new std::vector<const char *>());
3815 // Recover resources if we crash before exiting this method.
3816 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
3817 ArgsCleanup(Args.get());
3819 // Since the Clang C library is primarily used by batch tools dealing with
3820 // (often very broken) source code, where spell-checking can have a
3821 // significant negative impact on performance (particularly when
3822 // precompiled headers are involved), we disable it by default.
3823 // Only do this if we haven't found a spell-checking-related argument.
3824 bool FoundSpellCheckingArgument = false;
3825 for (int I = 0; I != num_command_line_args; ++I) {
3826 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3827 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3828 FoundSpellCheckingArgument = true;
3829 break;
3832 Args->insert(Args->end(), command_line_args,
3833 command_line_args + num_command_line_args);
3835 if (!FoundSpellCheckingArgument)
3836 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3838 // The 'source_filename' argument is optional. If the caller does not
3839 // specify it then it is assumed that the source file is specified
3840 // in the actual argument list.
3841 // Put the source file after command_line_args otherwise if '-x' flag is
3842 // present it will be unused.
3843 if (source_filename)
3844 Args->push_back(source_filename);
3846 // Do we need the detailed preprocessing record?
3847 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3848 Args->push_back("-Xclang");
3849 Args->push_back("-detailed-preprocessing-record");
3852 // Suppress any editor placeholder diagnostics.
3853 Args->push_back("-fallow-editor-placeholders");
3855 unsigned NumErrors = Diags->getClient()->getNumErrors();
3856 std::unique_ptr<ASTUnit> ErrUnit;
3857 // Unless the user specified that they want the preamble on the first parse
3858 // set it up to be created on the first reparse. This makes the first parse
3859 // faster, trading for a slower (first) reparse.
3860 unsigned PrecompilePreambleAfterNParses =
3861 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
3863 LibclangInvocationReporter InvocationReporter(
3864 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
3865 options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
3866 unsaved_files);
3867 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
3868 Args->data(), Args->data() + Args->size(),
3869 CXXIdx->getPCHContainerOperations(), Diags,
3870 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3871 CaptureDiagnostics, *RemappedFiles.get(),
3872 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3873 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3874 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
3875 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
3876 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3877 &ErrUnit));
3879 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
3880 if (!Unit && !ErrUnit)
3881 return CXError_ASTReadError;
3883 if (NumErrors != Diags->getClient()->getNumErrors()) {
3884 // Make sure to check that 'Unit' is non-NULL.
3885 if (CXXIdx->getDisplayDiagnostics())
3886 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3889 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3890 return CXError_ASTReadError;
3892 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
3893 if (CXTranslationUnitImpl *TU = *out_TU) {
3894 TU->ParsingOptions = options;
3895 TU->Arguments.reserve(Args->size());
3896 for (const char *Arg : *Args)
3897 TU->Arguments.push_back(Arg);
3898 return CXError_Success;
3900 return CXError_Failure;
3903 CXTranslationUnit
3904 clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
3905 const char *const *command_line_args,
3906 int num_command_line_args,
3907 struct CXUnsavedFile *unsaved_files,
3908 unsigned num_unsaved_files, unsigned options) {
3909 CXTranslationUnit TU;
3910 enum CXErrorCode Result = clang_parseTranslationUnit2(
3911 CIdx, source_filename, command_line_args, num_command_line_args,
3912 unsaved_files, num_unsaved_files, options, &TU);
3913 (void)Result;
3914 assert((TU && Result == CXError_Success) ||
3915 (!TU && Result != CXError_Success));
3916 return TU;
3919 enum CXErrorCode clang_parseTranslationUnit2(
3920 CXIndex CIdx, const char *source_filename,
3921 const char *const *command_line_args, int num_command_line_args,
3922 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3923 unsigned options, CXTranslationUnit *out_TU) {
3924 noteBottomOfStack();
3925 SmallVector<const char *, 4> Args;
3926 Args.push_back("clang");
3927 Args.append(command_line_args, command_line_args + num_command_line_args);
3928 return clang_parseTranslationUnit2FullArgv(
3929 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3930 num_unsaved_files, options, out_TU);
3933 enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3934 CXIndex CIdx, const char *source_filename,
3935 const char *const *command_line_args, int num_command_line_args,
3936 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3937 unsigned options, CXTranslationUnit *out_TU) {
3938 LOG_FUNC_SECTION {
3939 *Log << source_filename << ": ";
3940 for (int i = 0; i != num_command_line_args; ++i)
3941 *Log << command_line_args[i] << " ";
3944 if (num_unsaved_files && !unsaved_files)
3945 return CXError_InvalidArguments;
3947 CXErrorCode result = CXError_Failure;
3948 auto ParseTranslationUnitImpl = [=, &result] {
3949 noteBottomOfStack();
3950 result = clang_parseTranslationUnit_Impl(
3951 CIdx, source_filename, command_line_args, num_command_line_args,
3952 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3955 llvm::CrashRecoveryContext CRC;
3957 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
3958 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3959 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3960 fprintf(stderr, " 'command_line_args' : [");
3961 for (int i = 0; i != num_command_line_args; ++i) {
3962 if (i)
3963 fprintf(stderr, ", ");
3964 fprintf(stderr, "'%s'", command_line_args[i]);
3966 fprintf(stderr, "],\n");
3967 fprintf(stderr, " 'unsaved_files' : [");
3968 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3969 if (i)
3970 fprintf(stderr, ", ");
3971 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3972 unsaved_files[i].Length);
3974 fprintf(stderr, "],\n");
3975 fprintf(stderr, " 'options' : %d,\n", options);
3976 fprintf(stderr, "}\n");
3978 return CXError_Crashed;
3979 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3980 if (CXTranslationUnit *TU = out_TU)
3981 PrintLibclangResourceUsage(*TU);
3984 return result;
3987 CXString clang_Type_getObjCEncoding(CXType CT) {
3988 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3989 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3990 std::string encoding;
3991 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
3993 return cxstring::createDup(encoding);
3996 static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3997 if (C.kind == CXCursor_MacroDefinition) {
3998 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3999 return MDR->getName();
4000 } else if (C.kind == CXCursor_MacroExpansion) {
4001 MacroExpansionCursor ME = getCursorMacroExpansion(C);
4002 return ME.getName();
4004 return nullptr;
4007 unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
4008 const IdentifierInfo *II = getMacroIdentifier(C);
4009 if (!II) {
4010 return false;
4012 ASTUnit *ASTU = getCursorASTUnit(C);
4013 Preprocessor &PP = ASTU->getPreprocessor();
4014 if (const MacroInfo *MI = PP.getMacroInfo(II))
4015 return MI->isFunctionLike();
4016 return false;
4019 unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
4020 const IdentifierInfo *II = getMacroIdentifier(C);
4021 if (!II) {
4022 return false;
4024 ASTUnit *ASTU = getCursorASTUnit(C);
4025 Preprocessor &PP = ASTU->getPreprocessor();
4026 if (const MacroInfo *MI = PP.getMacroInfo(II))
4027 return MI->isBuiltinMacro();
4028 return false;
4031 unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
4032 const Decl *D = getCursorDecl(C);
4033 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
4034 if (!FD) {
4035 return false;
4037 return FD->isInlined();
4040 static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
4041 if (callExpr->getNumArgs() != 1) {
4042 return nullptr;
4045 StringLiteral *S = nullptr;
4046 auto *arg = callExpr->getArg(0);
4047 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
4048 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
4049 auto *subExpr = I->getSubExprAsWritten();
4051 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
4052 return nullptr;
4055 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
4056 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
4057 S = static_cast<StringLiteral *>(callExpr->getArg(0));
4058 } else {
4059 return nullptr;
4061 return S;
4064 struct ExprEvalResult {
4065 CXEvalResultKind EvalType;
4066 union {
4067 unsigned long long unsignedVal;
4068 long long intVal;
4069 double floatVal;
4070 char *stringVal;
4071 } EvalData;
4072 bool IsUnsignedInt;
4073 ~ExprEvalResult() {
4074 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
4075 EvalType != CXEval_Int) {
4076 delete[] EvalData.stringVal;
4081 void clang_EvalResult_dispose(CXEvalResult E) {
4082 delete static_cast<ExprEvalResult *>(E);
4085 CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
4086 if (!E) {
4087 return CXEval_UnExposed;
4089 return ((ExprEvalResult *)E)->EvalType;
4092 int clang_EvalResult_getAsInt(CXEvalResult E) {
4093 return clang_EvalResult_getAsLongLong(E);
4096 long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
4097 if (!E) {
4098 return 0;
4100 ExprEvalResult *Result = (ExprEvalResult *)E;
4101 if (Result->IsUnsignedInt)
4102 return Result->EvalData.unsignedVal;
4103 return Result->EvalData.intVal;
4106 unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
4107 return ((ExprEvalResult *)E)->IsUnsignedInt;
4110 unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
4111 if (!E) {
4112 return 0;
4115 ExprEvalResult *Result = (ExprEvalResult *)E;
4116 if (Result->IsUnsignedInt)
4117 return Result->EvalData.unsignedVal;
4118 return Result->EvalData.intVal;
4121 double clang_EvalResult_getAsDouble(CXEvalResult E) {
4122 if (!E) {
4123 return 0;
4125 return ((ExprEvalResult *)E)->EvalData.floatVal;
4128 const char *clang_EvalResult_getAsStr(CXEvalResult E) {
4129 if (!E) {
4130 return nullptr;
4132 return ((ExprEvalResult *)E)->EvalData.stringVal;
4135 static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
4136 Expr::EvalResult ER;
4137 ASTContext &ctx = getCursorContext(C);
4138 if (!expr)
4139 return nullptr;
4141 expr = expr->IgnoreParens();
4142 if (expr->isValueDependent())
4143 return nullptr;
4144 if (!expr->EvaluateAsRValue(ER, ctx))
4145 return nullptr;
4147 QualType rettype;
4148 CallExpr *callExpr;
4149 auto result = std::make_unique<ExprEvalResult>();
4150 result->EvalType = CXEval_UnExposed;
4151 result->IsUnsignedInt = false;
4153 if (ER.Val.isInt()) {
4154 result->EvalType = CXEval_Int;
4156 auto &val = ER.Val.getInt();
4157 if (val.isUnsigned()) {
4158 result->IsUnsignedInt = true;
4159 result->EvalData.unsignedVal = val.getZExtValue();
4160 } else {
4161 result->EvalData.intVal = val.getExtValue();
4164 return result.release();
4167 if (ER.Val.isFloat()) {
4168 llvm::SmallVector<char, 100> Buffer;
4169 ER.Val.getFloat().toString(Buffer);
4170 std::string floatStr(Buffer.data(), Buffer.size());
4171 result->EvalType = CXEval_Float;
4172 bool ignored;
4173 llvm::APFloat apFloat = ER.Val.getFloat();
4174 apFloat.convert(llvm::APFloat::IEEEdouble(),
4175 llvm::APFloat::rmNearestTiesToEven, &ignored);
4176 result->EvalData.floatVal = apFloat.convertToDouble();
4177 return result.release();
4180 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
4181 const auto *I = cast<ImplicitCastExpr>(expr);
4182 auto *subExpr = I->getSubExprAsWritten();
4183 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
4184 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
4185 const StringLiteral *StrE = nullptr;
4186 const ObjCStringLiteral *ObjCExpr;
4187 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
4189 if (ObjCExpr) {
4190 StrE = ObjCExpr->getString();
4191 result->EvalType = CXEval_ObjCStrLiteral;
4192 } else {
4193 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
4194 result->EvalType = CXEval_StrLiteral;
4197 std::string strRef(StrE->getString().str());
4198 result->EvalData.stringVal = new char[strRef.size() + 1];
4199 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
4200 strRef.size());
4201 result->EvalData.stringVal[strRef.size()] = '\0';
4202 return result.release();
4204 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
4205 expr->getStmtClass() == Stmt::StringLiteralClass) {
4206 const StringLiteral *StrE = nullptr;
4207 const ObjCStringLiteral *ObjCExpr;
4208 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
4210 if (ObjCExpr) {
4211 StrE = ObjCExpr->getString();
4212 result->EvalType = CXEval_ObjCStrLiteral;
4213 } else {
4214 StrE = cast<StringLiteral>(expr);
4215 result->EvalType = CXEval_StrLiteral;
4218 std::string strRef(StrE->getString().str());
4219 result->EvalData.stringVal = new char[strRef.size() + 1];
4220 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
4221 result->EvalData.stringVal[strRef.size()] = '\0';
4222 return result.release();
4225 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
4226 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
4228 rettype = CC->getType();
4229 if (rettype.getAsString() == "CFStringRef" &&
4230 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
4232 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
4233 StringLiteral *S = getCFSTR_value(callExpr);
4234 if (S) {
4235 std::string strLiteral(S->getString().str());
4236 result->EvalType = CXEval_CFStr;
4238 result->EvalData.stringVal = new char[strLiteral.size() + 1];
4239 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
4240 strLiteral.size());
4241 result->EvalData.stringVal[strLiteral.size()] = '\0';
4242 return result.release();
4246 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
4247 callExpr = static_cast<CallExpr *>(expr);
4248 rettype = callExpr->getCallReturnType(ctx);
4250 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
4251 return nullptr;
4253 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
4254 if (callExpr->getNumArgs() == 1 &&
4255 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
4256 return nullptr;
4257 } else if (rettype.getAsString() == "CFStringRef") {
4259 StringLiteral *S = getCFSTR_value(callExpr);
4260 if (S) {
4261 std::string strLiteral(S->getString().str());
4262 result->EvalType = CXEval_CFStr;
4263 result->EvalData.stringVal = new char[strLiteral.size() + 1];
4264 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
4265 strLiteral.size());
4266 result->EvalData.stringVal[strLiteral.size()] = '\0';
4267 return result.release();
4270 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
4271 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
4272 ValueDecl *V = D->getDecl();
4273 if (V->getKind() == Decl::Function) {
4274 std::string strName = V->getNameAsString();
4275 result->EvalType = CXEval_Other;
4276 result->EvalData.stringVal = new char[strName.size() + 1];
4277 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
4278 result->EvalData.stringVal[strName.size()] = '\0';
4279 return result.release();
4283 return nullptr;
4286 static const Expr *evaluateDeclExpr(const Decl *D) {
4287 if (!D)
4288 return nullptr;
4289 if (auto *Var = dyn_cast<VarDecl>(D))
4290 return Var->getInit();
4291 else if (auto *Field = dyn_cast<FieldDecl>(D))
4292 return Field->getInClassInitializer();
4293 return nullptr;
4296 static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4297 assert(CS && "invalid compound statement");
4298 for (auto *bodyIterator : CS->body()) {
4299 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4300 return E;
4302 return nullptr;
4305 CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
4306 const Expr *E = nullptr;
4307 if (clang_getCursorKind(C) == CXCursor_CompoundStmt)
4308 E = evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)));
4309 else if (clang_isDeclaration(C.kind))
4310 E = evaluateDeclExpr(getCursorDecl(C));
4311 else if (clang_isExpression(C.kind))
4312 E = getCursorExpr(C);
4313 if (E)
4314 return const_cast<CXEvalResult>(
4315 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4316 return nullptr;
4319 unsigned clang_Cursor_hasAttrs(CXCursor C) {
4320 const Decl *D = getCursorDecl(C);
4321 if (!D) {
4322 return 0;
4325 if (D->hasAttrs()) {
4326 return 1;
4329 return 0;
4331 unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4332 return CXSaveTranslationUnit_None;
4335 static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4336 const char *FileName,
4337 unsigned options) {
4338 CIndexer *CXXIdx = TU->CIdx;
4339 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4340 setThreadBackgroundPriority();
4342 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4343 return hadError ? CXSaveError_Unknown : CXSaveError_None;
4346 int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4347 unsigned options) {
4348 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
4350 if (isNotUsableTU(TU)) {
4351 LOG_BAD_TU(TU);
4352 return CXSaveError_InvalidTU;
4355 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4356 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4357 if (!CXXUnit->hasSema())
4358 return CXSaveError_InvalidTU;
4360 CXSaveError result;
4361 auto SaveTranslationUnitImpl = [=, &result]() {
4362 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4365 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
4366 SaveTranslationUnitImpl();
4368 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4369 PrintLibclangResourceUsage(TU);
4371 return result;
4374 // We have an AST that has invalid nodes due to compiler errors.
4375 // Use a crash recovery thread for protection.
4377 llvm::CrashRecoveryContext CRC;
4379 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
4380 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4381 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4382 fprintf(stderr, " 'options' : %d,\n", options);
4383 fprintf(stderr, "}\n");
4385 return CXSaveError_Unknown;
4387 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4388 PrintLibclangResourceUsage(TU);
4391 return result;
4394 void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4395 if (CTUnit) {
4396 // If the translation unit has been marked as unsafe to free, just discard
4397 // it.
4398 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4399 if (Unit && Unit->isUnsafeToFree())
4400 return;
4402 delete cxtu::getASTUnit(CTUnit);
4403 delete CTUnit->StringPool;
4404 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4405 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
4406 delete CTUnit->CommentToXML;
4407 delete CTUnit;
4411 unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4412 if (CTUnit) {
4413 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4415 if (Unit && Unit->isUnsafeToFree())
4416 return false;
4418 Unit->ResetForParse();
4419 return true;
4422 return false;
4425 unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4426 return CXReparse_None;
4429 static CXErrorCode
4430 clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4431 ArrayRef<CXUnsavedFile> unsaved_files,
4432 unsigned options) {
4433 // Check arguments.
4434 if (isNotUsableTU(TU)) {
4435 LOG_BAD_TU(TU);
4436 return CXError_InvalidArguments;
4439 // Reset the associated diagnostics.
4440 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
4441 TU->Diagnostics = nullptr;
4443 CIndexer *CXXIdx = TU->CIdx;
4444 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4445 setThreadBackgroundPriority();
4447 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4448 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4450 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4451 new std::vector<ASTUnit::RemappedFile>());
4453 // Recover resources if we crash before exiting this function.
4454 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4455 RemappedCleanup(RemappedFiles.get());
4457 for (auto &UF : unsaved_files) {
4458 std::unique_ptr<llvm::MemoryBuffer> MB =
4459 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
4460 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
4463 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4464 *RemappedFiles.get()))
4465 return CXError_Success;
4466 if (isASTReadError(CXXUnit))
4467 return CXError_ASTReadError;
4468 return CXError_Failure;
4471 int clang_reparseTranslationUnit(CXTranslationUnit TU,
4472 unsigned num_unsaved_files,
4473 struct CXUnsavedFile *unsaved_files,
4474 unsigned options) {
4475 LOG_FUNC_SECTION { *Log << TU; }
4477 if (num_unsaved_files && !unsaved_files)
4478 return CXError_InvalidArguments;
4480 CXErrorCode result;
4481 auto ReparseTranslationUnitImpl = [=, &result]() {
4482 result = clang_reparseTranslationUnit_Impl(
4483 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
4486 llvm::CrashRecoveryContext CRC;
4488 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
4489 fprintf(stderr, "libclang: crash detected during reparsing\n");
4490 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
4491 return CXError_Crashed;
4492 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4493 PrintLibclangResourceUsage(TU);
4495 return result;
4498 CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
4499 if (isNotUsableTU(CTUnit)) {
4500 LOG_BAD_TU(CTUnit);
4501 return cxstring::createEmpty();
4504 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4505 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
4508 CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
4509 if (isNotUsableTU(TU)) {
4510 LOG_BAD_TU(TU);
4511 return clang_getNullCursor();
4514 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4515 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4518 CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4519 if (isNotUsableTU(CTUnit)) {
4520 LOG_BAD_TU(CTUnit);
4521 return nullptr;
4524 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
4525 impl->TranslationUnit = CTUnit;
4526 return impl;
4529 CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4530 if (!TargetInfo)
4531 return cxstring::createEmpty();
4533 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4534 assert(!isNotUsableTU(CTUnit) &&
4535 "Unexpected unusable translation unit in TargetInfo");
4537 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4538 std::string Triple =
4539 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
4540 return cxstring::createDup(Triple);
4543 int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4544 if (!TargetInfo)
4545 return -1;
4547 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4548 assert(!isNotUsableTU(CTUnit) &&
4549 "Unexpected unusable translation unit in TargetInfo");
4551 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4552 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4555 void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4556 if (!TargetInfo)
4557 return;
4559 delete TargetInfo;
4562 //===----------------------------------------------------------------------===//
4563 // CXFile Operations.
4564 //===----------------------------------------------------------------------===//
4566 CXString clang_getFileName(CXFile SFile) {
4567 if (!SFile)
4568 return cxstring::createNull();
4570 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4571 return cxstring::createRef(FEnt->getName());
4574 time_t clang_getFileTime(CXFile SFile) {
4575 if (!SFile)
4576 return 0;
4578 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4579 return FEnt->getModificationTime();
4582 CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
4583 if (isNotUsableTU(TU)) {
4584 LOG_BAD_TU(TU);
4585 return nullptr;
4588 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4590 FileManager &FMgr = CXXUnit->getFileManager();
4591 auto File = FMgr.getFile(file_name);
4592 if (!File)
4593 return nullptr;
4594 return const_cast<FileEntry *>(*File);
4597 const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4598 size_t *size) {
4599 if (isNotUsableTU(TU)) {
4600 LOG_BAD_TU(TU);
4601 return nullptr;
4604 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4605 FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
4606 llvm::Optional<llvm::MemoryBufferRef> buf = SM.getBufferOrNone(fid);
4607 if (!buf) {
4608 if (size)
4609 *size = 0;
4610 return nullptr;
4612 if (size)
4613 *size = buf->getBufferSize();
4614 return buf->getBufferStart();
4617 unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
4618 if (isNotUsableTU(TU)) {
4619 LOG_BAD_TU(TU);
4620 return 0;
4623 if (!file)
4624 return 0;
4626 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
4627 FileEntry *FEnt = static_cast<FileEntry *>(file);
4628 return CXXUnit->getPreprocessor()
4629 .getHeaderSearchInfo()
4630 .isFileMultipleIncludeGuarded(FEnt);
4633 int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
4634 if (!file || !outID)
4635 return 1;
4637 FileEntry *FEnt = static_cast<FileEntry *>(file);
4638 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
4639 outID->data[0] = ID.getDevice();
4640 outID->data[1] = ID.getFile();
4641 outID->data[2] = FEnt->getModificationTime();
4642 return 0;
4645 int clang_File_isEqual(CXFile file1, CXFile file2) {
4646 if (file1 == file2)
4647 return true;
4649 if (!file1 || !file2)
4650 return false;
4652 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
4653 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
4654 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
4657 CXString clang_File_tryGetRealPathName(CXFile SFile) {
4658 if (!SFile)
4659 return cxstring::createNull();
4661 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4662 return cxstring::createRef(FEnt->tryGetRealPathName());
4665 //===----------------------------------------------------------------------===//
4666 // CXCursor Operations.
4667 //===----------------------------------------------------------------------===//
4669 static const Decl *getDeclFromExpr(const Stmt *E) {
4670 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
4671 return getDeclFromExpr(CE->getSubExpr());
4673 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
4674 return RefExpr->getDecl();
4675 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
4676 return ME->getMemberDecl();
4677 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
4678 return RE->getDecl();
4679 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
4680 if (PRE->isExplicitProperty())
4681 return PRE->getExplicitProperty();
4682 // It could be messaging both getter and setter as in:
4683 // ++myobj.myprop;
4684 // in which case prefer to associate the setter since it is less obvious
4685 // from inspecting the source that the setter is going to get called.
4686 if (PRE->isMessagingSetter())
4687 return PRE->getImplicitPropertySetter();
4688 return PRE->getImplicitPropertyGetter();
4690 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
4691 return getDeclFromExpr(POE->getSyntacticForm());
4692 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
4693 if (Expr *Src = OVE->getSourceExpr())
4694 return getDeclFromExpr(Src);
4696 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
4697 return getDeclFromExpr(CE->getCallee());
4698 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
4699 if (!CE->isElidable())
4700 return CE->getConstructor();
4701 if (const CXXInheritedCtorInitExpr *CE =
4702 dyn_cast<CXXInheritedCtorInitExpr>(E))
4703 return CE->getConstructor();
4704 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
4705 return OME->getMethodDecl();
4707 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
4708 return PE->getProtocol();
4709 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4710 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
4711 return NTTP->getParameterPack();
4712 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
4713 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
4714 isa<ParmVarDecl>(SizeOfPack->getPack()))
4715 return SizeOfPack->getPack();
4717 return nullptr;
4720 static SourceLocation getLocationFromExpr(const Expr *E) {
4721 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
4722 return getLocationFromExpr(CE->getSubExpr());
4724 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
4725 return /*FIXME:*/ Msg->getLeftLoc();
4726 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
4727 return DRE->getLocation();
4728 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
4729 return Member->getMemberLoc();
4730 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
4731 return Ivar->getLocation();
4732 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
4733 return SizeOfPack->getPackLoc();
4734 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
4735 return PropRef->getLocation();
4737 return E->getBeginLoc();
4740 extern "C" {
4742 unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
4743 CXClientData client_data) {
4744 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4745 /*VisitPreprocessorLast=*/false);
4746 return CursorVis.VisitChildren(parent);
4749 #ifndef __has_feature
4750 #define __has_feature(x) 0
4751 #endif
4752 #if __has_feature(blocks)
4753 typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4754 CXCursor parent);
4756 static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4757 CXClientData client_data) {
4758 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4759 return block(cursor, parent);
4761 #else
4762 // If we are compiled with a compiler that doesn't have native blocks support,
4763 // define and call the block manually, so the
4764 typedef struct _CXChildVisitResult {
4765 void *isa;
4766 int flags;
4767 int reserved;
4768 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
4769 CXCursor);
4770 } * CXCursorVisitorBlock;
4772 static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
4773 CXClientData client_data) {
4774 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4775 return block->invoke(block, cursor, parent);
4777 #endif
4779 unsigned clang_visitChildrenWithBlock(CXCursor parent,
4780 CXCursorVisitorBlock block) {
4781 return clang_visitChildren(parent, visitWithBlock, block);
4784 static CXString getDeclSpelling(const Decl *D) {
4785 if (!D)
4786 return cxstring::createEmpty();
4788 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
4789 if (!ND) {
4790 if (const ObjCPropertyImplDecl *PropImpl =
4791 dyn_cast<ObjCPropertyImplDecl>(D))
4792 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4793 return cxstring::createDup(Property->getIdentifier()->getName());
4795 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
4796 if (Module *Mod = ImportD->getImportedModule())
4797 return cxstring::createDup(Mod->getFullModuleName());
4799 return cxstring::createEmpty();
4802 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
4803 return cxstring::createDup(OMD->getSelector().getAsString());
4805 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
4806 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4807 // and returns different names. NamedDecl returns the class name and
4808 // ObjCCategoryImplDecl returns the category name.
4809 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
4811 if (isa<UsingDirectiveDecl>(D))
4812 return cxstring::createEmpty();
4814 SmallString<1024> S;
4815 llvm::raw_svector_ostream os(S);
4816 ND->printName(os);
4818 return cxstring::createDup(os.str());
4821 CXString clang_getCursorSpelling(CXCursor C) {
4822 if (clang_isTranslationUnit(C.kind))
4823 return clang_getTranslationUnitSpelling(getCursorTU(C));
4825 if (clang_isReference(C.kind)) {
4826 switch (C.kind) {
4827 case CXCursor_ObjCSuperClassRef: {
4828 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
4829 return cxstring::createRef(Super->getIdentifier()->getNameStart());
4831 case CXCursor_ObjCClassRef: {
4832 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4833 return cxstring::createRef(Class->getIdentifier()->getNameStart());
4835 case CXCursor_ObjCProtocolRef: {
4836 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
4837 assert(OID && "getCursorSpelling(): Missing protocol decl");
4838 return cxstring::createRef(OID->getIdentifier()->getNameStart());
4840 case CXCursor_CXXBaseSpecifier: {
4841 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
4842 return cxstring::createDup(B->getType().getAsString());
4844 case CXCursor_TypeRef: {
4845 const TypeDecl *Type = getCursorTypeRef(C).first;
4846 assert(Type && "Missing type decl");
4848 return cxstring::createDup(
4849 getCursorContext(C).getTypeDeclType(Type).getAsString());
4851 case CXCursor_TemplateRef: {
4852 const TemplateDecl *Template = getCursorTemplateRef(C).first;
4853 assert(Template && "Missing template decl");
4855 return cxstring::createDup(Template->getNameAsString());
4858 case CXCursor_NamespaceRef: {
4859 const NamedDecl *NS = getCursorNamespaceRef(C).first;
4860 assert(NS && "Missing namespace decl");
4862 return cxstring::createDup(NS->getNameAsString());
4865 case CXCursor_MemberRef: {
4866 const FieldDecl *Field = getCursorMemberRef(C).first;
4867 assert(Field && "Missing member decl");
4869 return cxstring::createDup(Field->getNameAsString());
4872 case CXCursor_LabelRef: {
4873 const LabelStmt *Label = getCursorLabelRef(C).first;
4874 assert(Label && "Missing label");
4876 return cxstring::createRef(Label->getName());
4879 case CXCursor_OverloadedDeclRef: {
4880 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
4881 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4882 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
4883 return cxstring::createDup(ND->getNameAsString());
4884 return cxstring::createEmpty();
4886 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
4887 return cxstring::createDup(E->getName().getAsString());
4888 OverloadedTemplateStorage *Ovl =
4889 Storage.get<OverloadedTemplateStorage *>();
4890 if (Ovl->size() == 0)
4891 return cxstring::createEmpty();
4892 return cxstring::createDup((*Ovl->begin())->getNameAsString());
4895 case CXCursor_VariableRef: {
4896 const VarDecl *Var = getCursorVariableRef(C).first;
4897 assert(Var && "Missing variable decl");
4899 return cxstring::createDup(Var->getNameAsString());
4902 default:
4903 return cxstring::createRef("<not implemented>");
4907 if (clang_isExpression(C.kind)) {
4908 const Expr *E = getCursorExpr(C);
4910 if (C.kind == CXCursor_ObjCStringLiteral ||
4911 C.kind == CXCursor_StringLiteral) {
4912 const StringLiteral *SLit;
4913 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4914 SLit = OSL->getString();
4915 } else {
4916 SLit = cast<StringLiteral>(E);
4918 SmallString<256> Buf;
4919 llvm::raw_svector_ostream OS(Buf);
4920 SLit->outputString(OS);
4921 return cxstring::createDup(OS.str());
4924 const Decl *D = getDeclFromExpr(getCursorExpr(C));
4925 if (D)
4926 return getDeclSpelling(D);
4927 return cxstring::createEmpty();
4930 if (clang_isStatement(C.kind)) {
4931 const Stmt *S = getCursorStmt(C);
4932 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
4933 return cxstring::createRef(Label->getName());
4935 return cxstring::createEmpty();
4938 if (C.kind == CXCursor_MacroExpansion)
4939 return cxstring::createRef(
4940 getCursorMacroExpansion(C).getName()->getNameStart());
4942 if (C.kind == CXCursor_MacroDefinition)
4943 return cxstring::createRef(
4944 getCursorMacroDefinition(C)->getName()->getNameStart());
4946 if (C.kind == CXCursor_InclusionDirective)
4947 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
4949 if (clang_isDeclaration(C.kind))
4950 return getDeclSpelling(getCursorDecl(C));
4952 if (C.kind == CXCursor_AnnotateAttr) {
4953 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
4954 return cxstring::createDup(AA->getAnnotation());
4957 if (C.kind == CXCursor_AsmLabelAttr) {
4958 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
4959 return cxstring::createDup(AA->getLabel());
4962 if (C.kind == CXCursor_PackedAttr) {
4963 return cxstring::createRef("packed");
4966 if (C.kind == CXCursor_VisibilityAttr) {
4967 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4968 switch (AA->getVisibility()) {
4969 case VisibilityAttr::VisibilityType::Default:
4970 return cxstring::createRef("default");
4971 case VisibilityAttr::VisibilityType::Hidden:
4972 return cxstring::createRef("hidden");
4973 case VisibilityAttr::VisibilityType::Protected:
4974 return cxstring::createRef("protected");
4976 llvm_unreachable("unknown visibility type");
4979 return cxstring::createEmpty();
4982 CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
4983 unsigned options) {
4984 if (clang_Cursor_isNull(C))
4985 return clang_getNullRange();
4987 ASTContext &Ctx = getCursorContext(C);
4989 if (clang_isStatement(C.kind)) {
4990 const Stmt *S = getCursorStmt(C);
4991 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
4992 if (pieceIndex > 0)
4993 return clang_getNullRange();
4994 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4997 return clang_getNullRange();
5000 if (C.kind == CXCursor_ObjCMessageExpr) {
5001 if (const ObjCMessageExpr *ME =
5002 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
5003 if (pieceIndex >= ME->getNumSelectorLocs())
5004 return clang_getNullRange();
5005 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
5009 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
5010 C.kind == CXCursor_ObjCClassMethodDecl) {
5011 if (const ObjCMethodDecl *MD =
5012 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
5013 if (pieceIndex >= MD->getNumSelectorLocs())
5014 return clang_getNullRange();
5015 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
5019 if (C.kind == CXCursor_ObjCCategoryDecl ||
5020 C.kind == CXCursor_ObjCCategoryImplDecl) {
5021 if (pieceIndex > 0)
5022 return clang_getNullRange();
5023 if (const ObjCCategoryDecl *CD =
5024 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
5025 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
5026 if (const ObjCCategoryImplDecl *CID =
5027 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
5028 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
5031 if (C.kind == CXCursor_ModuleImportDecl) {
5032 if (pieceIndex > 0)
5033 return clang_getNullRange();
5034 if (const ImportDecl *ImportD =
5035 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
5036 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
5037 if (!Locs.empty())
5038 return cxloc::translateSourceRange(
5039 Ctx, SourceRange(Locs.front(), Locs.back()));
5041 return clang_getNullRange();
5044 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
5045 C.kind == CXCursor_ConversionFunction ||
5046 C.kind == CXCursor_FunctionDecl) {
5047 if (pieceIndex > 0)
5048 return clang_getNullRange();
5049 if (const FunctionDecl *FD =
5050 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
5051 DeclarationNameInfo FunctionName = FD->getNameInfo();
5052 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
5054 return clang_getNullRange();
5057 // FIXME: A CXCursor_InclusionDirective should give the location of the
5058 // filename, but we don't keep track of this.
5060 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
5061 // but we don't keep track of this.
5063 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
5064 // but we don't keep track of this.
5066 // Default handling, give the location of the cursor.
5068 if (pieceIndex > 0)
5069 return clang_getNullRange();
5071 CXSourceLocation CXLoc = clang_getCursorLocation(C);
5072 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
5073 return cxloc::translateSourceRange(Ctx, Loc);
5076 CXString clang_Cursor_getMangling(CXCursor C) {
5077 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
5078 return cxstring::createEmpty();
5080 // Mangling only works for functions and variables.
5081 const Decl *D = getCursorDecl(C);
5082 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
5083 return cxstring::createEmpty();
5085 ASTContext &Ctx = D->getASTContext();
5086 ASTNameGenerator ASTNameGen(Ctx);
5087 return cxstring::createDup(ASTNameGen.getName(D));
5090 CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
5091 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
5092 return nullptr;
5094 const Decl *D = getCursorDecl(C);
5095 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
5096 return nullptr;
5098 ASTContext &Ctx = D->getASTContext();
5099 ASTNameGenerator ASTNameGen(Ctx);
5100 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
5101 return cxstring::createSet(Manglings);
5104 CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
5105 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
5106 return nullptr;
5108 const Decl *D = getCursorDecl(C);
5109 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
5110 return nullptr;
5112 ASTContext &Ctx = D->getASTContext();
5113 ASTNameGenerator ASTNameGen(Ctx);
5114 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
5115 return cxstring::createSet(Manglings);
5118 CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
5119 if (clang_Cursor_isNull(C))
5120 return nullptr;
5121 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
5124 void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
5125 if (Policy)
5126 delete static_cast<PrintingPolicy *>(Policy);
5129 unsigned
5130 clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
5131 enum CXPrintingPolicyProperty Property) {
5132 if (!Policy)
5133 return 0;
5135 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
5136 switch (Property) {
5137 case CXPrintingPolicy_Indentation:
5138 return P->Indentation;
5139 case CXPrintingPolicy_SuppressSpecifiers:
5140 return P->SuppressSpecifiers;
5141 case CXPrintingPolicy_SuppressTagKeyword:
5142 return P->SuppressTagKeyword;
5143 case CXPrintingPolicy_IncludeTagDefinition:
5144 return P->IncludeTagDefinition;
5145 case CXPrintingPolicy_SuppressScope:
5146 return P->SuppressScope;
5147 case CXPrintingPolicy_SuppressUnwrittenScope:
5148 return P->SuppressUnwrittenScope;
5149 case CXPrintingPolicy_SuppressInitializers:
5150 return P->SuppressInitializers;
5151 case CXPrintingPolicy_ConstantArraySizeAsWritten:
5152 return P->ConstantArraySizeAsWritten;
5153 case CXPrintingPolicy_AnonymousTagLocations:
5154 return P->AnonymousTagLocations;
5155 case CXPrintingPolicy_SuppressStrongLifetime:
5156 return P->SuppressStrongLifetime;
5157 case CXPrintingPolicy_SuppressLifetimeQualifiers:
5158 return P->SuppressLifetimeQualifiers;
5159 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
5160 return P->SuppressTemplateArgsInCXXConstructors;
5161 case CXPrintingPolicy_Bool:
5162 return P->Bool;
5163 case CXPrintingPolicy_Restrict:
5164 return P->Restrict;
5165 case CXPrintingPolicy_Alignof:
5166 return P->Alignof;
5167 case CXPrintingPolicy_UnderscoreAlignof:
5168 return P->UnderscoreAlignof;
5169 case CXPrintingPolicy_UseVoidForZeroParams:
5170 return P->UseVoidForZeroParams;
5171 case CXPrintingPolicy_TerseOutput:
5172 return P->TerseOutput;
5173 case CXPrintingPolicy_PolishForDeclaration:
5174 return P->PolishForDeclaration;
5175 case CXPrintingPolicy_Half:
5176 return P->Half;
5177 case CXPrintingPolicy_MSWChar:
5178 return P->MSWChar;
5179 case CXPrintingPolicy_IncludeNewlines:
5180 return P->IncludeNewlines;
5181 case CXPrintingPolicy_MSVCFormatting:
5182 return P->MSVCFormatting;
5183 case CXPrintingPolicy_ConstantsAsWritten:
5184 return P->ConstantsAsWritten;
5185 case CXPrintingPolicy_SuppressImplicitBase:
5186 return P->SuppressImplicitBase;
5187 case CXPrintingPolicy_FullyQualifiedName:
5188 return P->FullyQualifiedName;
5191 assert(false && "Invalid CXPrintingPolicyProperty");
5192 return 0;
5195 void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
5196 enum CXPrintingPolicyProperty Property,
5197 unsigned Value) {
5198 if (!Policy)
5199 return;
5201 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
5202 switch (Property) {
5203 case CXPrintingPolicy_Indentation:
5204 P->Indentation = Value;
5205 return;
5206 case CXPrintingPolicy_SuppressSpecifiers:
5207 P->SuppressSpecifiers = Value;
5208 return;
5209 case CXPrintingPolicy_SuppressTagKeyword:
5210 P->SuppressTagKeyword = Value;
5211 return;
5212 case CXPrintingPolicy_IncludeTagDefinition:
5213 P->IncludeTagDefinition = Value;
5214 return;
5215 case CXPrintingPolicy_SuppressScope:
5216 P->SuppressScope = Value;
5217 return;
5218 case CXPrintingPolicy_SuppressUnwrittenScope:
5219 P->SuppressUnwrittenScope = Value;
5220 return;
5221 case CXPrintingPolicy_SuppressInitializers:
5222 P->SuppressInitializers = Value;
5223 return;
5224 case CXPrintingPolicy_ConstantArraySizeAsWritten:
5225 P->ConstantArraySizeAsWritten = Value;
5226 return;
5227 case CXPrintingPolicy_AnonymousTagLocations:
5228 P->AnonymousTagLocations = Value;
5229 return;
5230 case CXPrintingPolicy_SuppressStrongLifetime:
5231 P->SuppressStrongLifetime = Value;
5232 return;
5233 case CXPrintingPolicy_SuppressLifetimeQualifiers:
5234 P->SuppressLifetimeQualifiers = Value;
5235 return;
5236 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
5237 P->SuppressTemplateArgsInCXXConstructors = Value;
5238 return;
5239 case CXPrintingPolicy_Bool:
5240 P->Bool = Value;
5241 return;
5242 case CXPrintingPolicy_Restrict:
5243 P->Restrict = Value;
5244 return;
5245 case CXPrintingPolicy_Alignof:
5246 P->Alignof = Value;
5247 return;
5248 case CXPrintingPolicy_UnderscoreAlignof:
5249 P->UnderscoreAlignof = Value;
5250 return;
5251 case CXPrintingPolicy_UseVoidForZeroParams:
5252 P->UseVoidForZeroParams = Value;
5253 return;
5254 case CXPrintingPolicy_TerseOutput:
5255 P->TerseOutput = Value;
5256 return;
5257 case CXPrintingPolicy_PolishForDeclaration:
5258 P->PolishForDeclaration = Value;
5259 return;
5260 case CXPrintingPolicy_Half:
5261 P->Half = Value;
5262 return;
5263 case CXPrintingPolicy_MSWChar:
5264 P->MSWChar = Value;
5265 return;
5266 case CXPrintingPolicy_IncludeNewlines:
5267 P->IncludeNewlines = Value;
5268 return;
5269 case CXPrintingPolicy_MSVCFormatting:
5270 P->MSVCFormatting = Value;
5271 return;
5272 case CXPrintingPolicy_ConstantsAsWritten:
5273 P->ConstantsAsWritten = Value;
5274 return;
5275 case CXPrintingPolicy_SuppressImplicitBase:
5276 P->SuppressImplicitBase = Value;
5277 return;
5278 case CXPrintingPolicy_FullyQualifiedName:
5279 P->FullyQualifiedName = Value;
5280 return;
5283 assert(false && "Invalid CXPrintingPolicyProperty");
5286 CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
5287 if (clang_Cursor_isNull(C))
5288 return cxstring::createEmpty();
5290 if (clang_isDeclaration(C.kind)) {
5291 const Decl *D = getCursorDecl(C);
5292 if (!D)
5293 return cxstring::createEmpty();
5295 SmallString<128> Str;
5296 llvm::raw_svector_ostream OS(Str);
5297 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5298 D->print(OS, UserPolicy ? *UserPolicy
5299 : getCursorContext(C).getPrintingPolicy());
5301 return cxstring::createDup(OS.str());
5304 return cxstring::createEmpty();
5307 CXString clang_getCursorDisplayName(CXCursor C) {
5308 if (!clang_isDeclaration(C.kind))
5309 return clang_getCursorSpelling(C);
5311 const Decl *D = getCursorDecl(C);
5312 if (!D)
5313 return cxstring::createEmpty();
5315 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
5316 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
5317 D = FunTmpl->getTemplatedDecl();
5319 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
5320 SmallString<64> Str;
5321 llvm::raw_svector_ostream OS(Str);
5322 OS << *Function;
5323 if (Function->getPrimaryTemplate())
5324 OS << "<>";
5325 OS << "(";
5326 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5327 if (I)
5328 OS << ", ";
5329 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5332 if (Function->isVariadic()) {
5333 if (Function->getNumParams())
5334 OS << ", ";
5335 OS << "...";
5337 OS << ")";
5338 return cxstring::createDup(OS.str());
5341 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
5342 SmallString<64> Str;
5343 llvm::raw_svector_ostream OS(Str);
5344 OS << *ClassTemplate;
5345 OS << "<";
5346 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5347 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5348 if (I)
5349 OS << ", ";
5351 NamedDecl *Param = Params->getParam(I);
5352 if (Param->getIdentifier()) {
5353 OS << Param->getIdentifier()->getName();
5354 continue;
5357 // There is no parameter name, which makes this tricky. Try to come up
5358 // with something useful that isn't too long.
5359 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
5360 if (const auto *TC = TTP->getTypeConstraint()) {
5361 TC->getConceptNameInfo().printName(OS, Policy);
5362 if (TC->hasExplicitTemplateArgs())
5363 OS << "<...>";
5364 } else
5365 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5366 else if (NonTypeTemplateParmDecl *NTTP =
5367 dyn_cast<NonTypeTemplateParmDecl>(Param))
5368 OS << NTTP->getType().getAsString(Policy);
5369 else
5370 OS << "template<...> class";
5373 OS << ">";
5374 return cxstring::createDup(OS.str());
5377 if (const ClassTemplateSpecializationDecl *ClassSpec =
5378 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
5379 // If the type was explicitly written, use that.
5380 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
5381 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
5383 SmallString<128> Str;
5384 llvm::raw_svector_ostream OS(Str);
5385 OS << *ClassSpec;
5386 printTemplateArgumentList(
5387 OS, ClassSpec->getTemplateArgs().asArray(), Policy,
5388 ClassSpec->getSpecializedTemplate()->getTemplateParameters());
5389 return cxstring::createDup(OS.str());
5392 return clang_getCursorSpelling(C);
5395 CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5396 switch (Kind) {
5397 case CXCursor_FunctionDecl:
5398 return cxstring::createRef("FunctionDecl");
5399 case CXCursor_TypedefDecl:
5400 return cxstring::createRef("TypedefDecl");
5401 case CXCursor_EnumDecl:
5402 return cxstring::createRef("EnumDecl");
5403 case CXCursor_EnumConstantDecl:
5404 return cxstring::createRef("EnumConstantDecl");
5405 case CXCursor_StructDecl:
5406 return cxstring::createRef("StructDecl");
5407 case CXCursor_UnionDecl:
5408 return cxstring::createRef("UnionDecl");
5409 case CXCursor_ClassDecl:
5410 return cxstring::createRef("ClassDecl");
5411 case CXCursor_FieldDecl:
5412 return cxstring::createRef("FieldDecl");
5413 case CXCursor_VarDecl:
5414 return cxstring::createRef("VarDecl");
5415 case CXCursor_ParmDecl:
5416 return cxstring::createRef("ParmDecl");
5417 case CXCursor_ObjCInterfaceDecl:
5418 return cxstring::createRef("ObjCInterfaceDecl");
5419 case CXCursor_ObjCCategoryDecl:
5420 return cxstring::createRef("ObjCCategoryDecl");
5421 case CXCursor_ObjCProtocolDecl:
5422 return cxstring::createRef("ObjCProtocolDecl");
5423 case CXCursor_ObjCPropertyDecl:
5424 return cxstring::createRef("ObjCPropertyDecl");
5425 case CXCursor_ObjCIvarDecl:
5426 return cxstring::createRef("ObjCIvarDecl");
5427 case CXCursor_ObjCInstanceMethodDecl:
5428 return cxstring::createRef("ObjCInstanceMethodDecl");
5429 case CXCursor_ObjCClassMethodDecl:
5430 return cxstring::createRef("ObjCClassMethodDecl");
5431 case CXCursor_ObjCImplementationDecl:
5432 return cxstring::createRef("ObjCImplementationDecl");
5433 case CXCursor_ObjCCategoryImplDecl:
5434 return cxstring::createRef("ObjCCategoryImplDecl");
5435 case CXCursor_CXXMethod:
5436 return cxstring::createRef("CXXMethod");
5437 case CXCursor_UnexposedDecl:
5438 return cxstring::createRef("UnexposedDecl");
5439 case CXCursor_ObjCSuperClassRef:
5440 return cxstring::createRef("ObjCSuperClassRef");
5441 case CXCursor_ObjCProtocolRef:
5442 return cxstring::createRef("ObjCProtocolRef");
5443 case CXCursor_ObjCClassRef:
5444 return cxstring::createRef("ObjCClassRef");
5445 case CXCursor_TypeRef:
5446 return cxstring::createRef("TypeRef");
5447 case CXCursor_TemplateRef:
5448 return cxstring::createRef("TemplateRef");
5449 case CXCursor_NamespaceRef:
5450 return cxstring::createRef("NamespaceRef");
5451 case CXCursor_MemberRef:
5452 return cxstring::createRef("MemberRef");
5453 case CXCursor_LabelRef:
5454 return cxstring::createRef("LabelRef");
5455 case CXCursor_OverloadedDeclRef:
5456 return cxstring::createRef("OverloadedDeclRef");
5457 case CXCursor_VariableRef:
5458 return cxstring::createRef("VariableRef");
5459 case CXCursor_IntegerLiteral:
5460 return cxstring::createRef("IntegerLiteral");
5461 case CXCursor_FixedPointLiteral:
5462 return cxstring::createRef("FixedPointLiteral");
5463 case CXCursor_FloatingLiteral:
5464 return cxstring::createRef("FloatingLiteral");
5465 case CXCursor_ImaginaryLiteral:
5466 return cxstring::createRef("ImaginaryLiteral");
5467 case CXCursor_StringLiteral:
5468 return cxstring::createRef("StringLiteral");
5469 case CXCursor_CharacterLiteral:
5470 return cxstring::createRef("CharacterLiteral");
5471 case CXCursor_ParenExpr:
5472 return cxstring::createRef("ParenExpr");
5473 case CXCursor_UnaryOperator:
5474 return cxstring::createRef("UnaryOperator");
5475 case CXCursor_ArraySubscriptExpr:
5476 return cxstring::createRef("ArraySubscriptExpr");
5477 case CXCursor_OMPArraySectionExpr:
5478 return cxstring::createRef("OMPArraySectionExpr");
5479 case CXCursor_OMPArrayShapingExpr:
5480 return cxstring::createRef("OMPArrayShapingExpr");
5481 case CXCursor_OMPIteratorExpr:
5482 return cxstring::createRef("OMPIteratorExpr");
5483 case CXCursor_BinaryOperator:
5484 return cxstring::createRef("BinaryOperator");
5485 case CXCursor_CompoundAssignOperator:
5486 return cxstring::createRef("CompoundAssignOperator");
5487 case CXCursor_ConditionalOperator:
5488 return cxstring::createRef("ConditionalOperator");
5489 case CXCursor_CStyleCastExpr:
5490 return cxstring::createRef("CStyleCastExpr");
5491 case CXCursor_CompoundLiteralExpr:
5492 return cxstring::createRef("CompoundLiteralExpr");
5493 case CXCursor_InitListExpr:
5494 return cxstring::createRef("InitListExpr");
5495 case CXCursor_AddrLabelExpr:
5496 return cxstring::createRef("AddrLabelExpr");
5497 case CXCursor_StmtExpr:
5498 return cxstring::createRef("StmtExpr");
5499 case CXCursor_GenericSelectionExpr:
5500 return cxstring::createRef("GenericSelectionExpr");
5501 case CXCursor_GNUNullExpr:
5502 return cxstring::createRef("GNUNullExpr");
5503 case CXCursor_CXXStaticCastExpr:
5504 return cxstring::createRef("CXXStaticCastExpr");
5505 case CXCursor_CXXDynamicCastExpr:
5506 return cxstring::createRef("CXXDynamicCastExpr");
5507 case CXCursor_CXXReinterpretCastExpr:
5508 return cxstring::createRef("CXXReinterpretCastExpr");
5509 case CXCursor_CXXConstCastExpr:
5510 return cxstring::createRef("CXXConstCastExpr");
5511 case CXCursor_CXXFunctionalCastExpr:
5512 return cxstring::createRef("CXXFunctionalCastExpr");
5513 case CXCursor_CXXAddrspaceCastExpr:
5514 return cxstring::createRef("CXXAddrspaceCastExpr");
5515 case CXCursor_CXXTypeidExpr:
5516 return cxstring::createRef("CXXTypeidExpr");
5517 case CXCursor_CXXBoolLiteralExpr:
5518 return cxstring::createRef("CXXBoolLiteralExpr");
5519 case CXCursor_CXXNullPtrLiteralExpr:
5520 return cxstring::createRef("CXXNullPtrLiteralExpr");
5521 case CXCursor_CXXThisExpr:
5522 return cxstring::createRef("CXXThisExpr");
5523 case CXCursor_CXXThrowExpr:
5524 return cxstring::createRef("CXXThrowExpr");
5525 case CXCursor_CXXNewExpr:
5526 return cxstring::createRef("CXXNewExpr");
5527 case CXCursor_CXXDeleteExpr:
5528 return cxstring::createRef("CXXDeleteExpr");
5529 case CXCursor_UnaryExpr:
5530 return cxstring::createRef("UnaryExpr");
5531 case CXCursor_ObjCStringLiteral:
5532 return cxstring::createRef("ObjCStringLiteral");
5533 case CXCursor_ObjCBoolLiteralExpr:
5534 return cxstring::createRef("ObjCBoolLiteralExpr");
5535 case CXCursor_ObjCAvailabilityCheckExpr:
5536 return cxstring::createRef("ObjCAvailabilityCheckExpr");
5537 case CXCursor_ObjCSelfExpr:
5538 return cxstring::createRef("ObjCSelfExpr");
5539 case CXCursor_ObjCEncodeExpr:
5540 return cxstring::createRef("ObjCEncodeExpr");
5541 case CXCursor_ObjCSelectorExpr:
5542 return cxstring::createRef("ObjCSelectorExpr");
5543 case CXCursor_ObjCProtocolExpr:
5544 return cxstring::createRef("ObjCProtocolExpr");
5545 case CXCursor_ObjCBridgedCastExpr:
5546 return cxstring::createRef("ObjCBridgedCastExpr");
5547 case CXCursor_BlockExpr:
5548 return cxstring::createRef("BlockExpr");
5549 case CXCursor_PackExpansionExpr:
5550 return cxstring::createRef("PackExpansionExpr");
5551 case CXCursor_SizeOfPackExpr:
5552 return cxstring::createRef("SizeOfPackExpr");
5553 case CXCursor_LambdaExpr:
5554 return cxstring::createRef("LambdaExpr");
5555 case CXCursor_UnexposedExpr:
5556 return cxstring::createRef("UnexposedExpr");
5557 case CXCursor_DeclRefExpr:
5558 return cxstring::createRef("DeclRefExpr");
5559 case CXCursor_MemberRefExpr:
5560 return cxstring::createRef("MemberRefExpr");
5561 case CXCursor_CallExpr:
5562 return cxstring::createRef("CallExpr");
5563 case CXCursor_ObjCMessageExpr:
5564 return cxstring::createRef("ObjCMessageExpr");
5565 case CXCursor_BuiltinBitCastExpr:
5566 return cxstring::createRef("BuiltinBitCastExpr");
5567 case CXCursor_ConceptSpecializationExpr:
5568 return cxstring::createRef("ConceptSpecializationExpr");
5569 case CXCursor_RequiresExpr:
5570 return cxstring::createRef("RequiresExpr");
5571 case CXCursor_UnexposedStmt:
5572 return cxstring::createRef("UnexposedStmt");
5573 case CXCursor_DeclStmt:
5574 return cxstring::createRef("DeclStmt");
5575 case CXCursor_LabelStmt:
5576 return cxstring::createRef("LabelStmt");
5577 case CXCursor_CompoundStmt:
5578 return cxstring::createRef("CompoundStmt");
5579 case CXCursor_CaseStmt:
5580 return cxstring::createRef("CaseStmt");
5581 case CXCursor_DefaultStmt:
5582 return cxstring::createRef("DefaultStmt");
5583 case CXCursor_IfStmt:
5584 return cxstring::createRef("IfStmt");
5585 case CXCursor_SwitchStmt:
5586 return cxstring::createRef("SwitchStmt");
5587 case CXCursor_WhileStmt:
5588 return cxstring::createRef("WhileStmt");
5589 case CXCursor_DoStmt:
5590 return cxstring::createRef("DoStmt");
5591 case CXCursor_ForStmt:
5592 return cxstring::createRef("ForStmt");
5593 case CXCursor_GotoStmt:
5594 return cxstring::createRef("GotoStmt");
5595 case CXCursor_IndirectGotoStmt:
5596 return cxstring::createRef("IndirectGotoStmt");
5597 case CXCursor_ContinueStmt:
5598 return cxstring::createRef("ContinueStmt");
5599 case CXCursor_BreakStmt:
5600 return cxstring::createRef("BreakStmt");
5601 case CXCursor_ReturnStmt:
5602 return cxstring::createRef("ReturnStmt");
5603 case CXCursor_GCCAsmStmt:
5604 return cxstring::createRef("GCCAsmStmt");
5605 case CXCursor_MSAsmStmt:
5606 return cxstring::createRef("MSAsmStmt");
5607 case CXCursor_ObjCAtTryStmt:
5608 return cxstring::createRef("ObjCAtTryStmt");
5609 case CXCursor_ObjCAtCatchStmt:
5610 return cxstring::createRef("ObjCAtCatchStmt");
5611 case CXCursor_ObjCAtFinallyStmt:
5612 return cxstring::createRef("ObjCAtFinallyStmt");
5613 case CXCursor_ObjCAtThrowStmt:
5614 return cxstring::createRef("ObjCAtThrowStmt");
5615 case CXCursor_ObjCAtSynchronizedStmt:
5616 return cxstring::createRef("ObjCAtSynchronizedStmt");
5617 case CXCursor_ObjCAutoreleasePoolStmt:
5618 return cxstring::createRef("ObjCAutoreleasePoolStmt");
5619 case CXCursor_ObjCForCollectionStmt:
5620 return cxstring::createRef("ObjCForCollectionStmt");
5621 case CXCursor_CXXCatchStmt:
5622 return cxstring::createRef("CXXCatchStmt");
5623 case CXCursor_CXXTryStmt:
5624 return cxstring::createRef("CXXTryStmt");
5625 case CXCursor_CXXForRangeStmt:
5626 return cxstring::createRef("CXXForRangeStmt");
5627 case CXCursor_SEHTryStmt:
5628 return cxstring::createRef("SEHTryStmt");
5629 case CXCursor_SEHExceptStmt:
5630 return cxstring::createRef("SEHExceptStmt");
5631 case CXCursor_SEHFinallyStmt:
5632 return cxstring::createRef("SEHFinallyStmt");
5633 case CXCursor_SEHLeaveStmt:
5634 return cxstring::createRef("SEHLeaveStmt");
5635 case CXCursor_NullStmt:
5636 return cxstring::createRef("NullStmt");
5637 case CXCursor_InvalidFile:
5638 return cxstring::createRef("InvalidFile");
5639 case CXCursor_InvalidCode:
5640 return cxstring::createRef("InvalidCode");
5641 case CXCursor_NoDeclFound:
5642 return cxstring::createRef("NoDeclFound");
5643 case CXCursor_NotImplemented:
5644 return cxstring::createRef("NotImplemented");
5645 case CXCursor_TranslationUnit:
5646 return cxstring::createRef("TranslationUnit");
5647 case CXCursor_UnexposedAttr:
5648 return cxstring::createRef("UnexposedAttr");
5649 case CXCursor_IBActionAttr:
5650 return cxstring::createRef("attribute(ibaction)");
5651 case CXCursor_IBOutletAttr:
5652 return cxstring::createRef("attribute(iboutlet)");
5653 case CXCursor_IBOutletCollectionAttr:
5654 return cxstring::createRef("attribute(iboutletcollection)");
5655 case CXCursor_CXXFinalAttr:
5656 return cxstring::createRef("attribute(final)");
5657 case CXCursor_CXXOverrideAttr:
5658 return cxstring::createRef("attribute(override)");
5659 case CXCursor_AnnotateAttr:
5660 return cxstring::createRef("attribute(annotate)");
5661 case CXCursor_AsmLabelAttr:
5662 return cxstring::createRef("asm label");
5663 case CXCursor_PackedAttr:
5664 return cxstring::createRef("attribute(packed)");
5665 case CXCursor_PureAttr:
5666 return cxstring::createRef("attribute(pure)");
5667 case CXCursor_ConstAttr:
5668 return cxstring::createRef("attribute(const)");
5669 case CXCursor_NoDuplicateAttr:
5670 return cxstring::createRef("attribute(noduplicate)");
5671 case CXCursor_CUDAConstantAttr:
5672 return cxstring::createRef("attribute(constant)");
5673 case CXCursor_CUDADeviceAttr:
5674 return cxstring::createRef("attribute(device)");
5675 case CXCursor_CUDAGlobalAttr:
5676 return cxstring::createRef("attribute(global)");
5677 case CXCursor_CUDAHostAttr:
5678 return cxstring::createRef("attribute(host)");
5679 case CXCursor_CUDASharedAttr:
5680 return cxstring::createRef("attribute(shared)");
5681 case CXCursor_VisibilityAttr:
5682 return cxstring::createRef("attribute(visibility)");
5683 case CXCursor_DLLExport:
5684 return cxstring::createRef("attribute(dllexport)");
5685 case CXCursor_DLLImport:
5686 return cxstring::createRef("attribute(dllimport)");
5687 case CXCursor_NSReturnsRetained:
5688 return cxstring::createRef("attribute(ns_returns_retained)");
5689 case CXCursor_NSReturnsNotRetained:
5690 return cxstring::createRef("attribute(ns_returns_not_retained)");
5691 case CXCursor_NSReturnsAutoreleased:
5692 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5693 case CXCursor_NSConsumesSelf:
5694 return cxstring::createRef("attribute(ns_consumes_self)");
5695 case CXCursor_NSConsumed:
5696 return cxstring::createRef("attribute(ns_consumed)");
5697 case CXCursor_ObjCException:
5698 return cxstring::createRef("attribute(objc_exception)");
5699 case CXCursor_ObjCNSObject:
5700 return cxstring::createRef("attribute(NSObject)");
5701 case CXCursor_ObjCIndependentClass:
5702 return cxstring::createRef("attribute(objc_independent_class)");
5703 case CXCursor_ObjCPreciseLifetime:
5704 return cxstring::createRef("attribute(objc_precise_lifetime)");
5705 case CXCursor_ObjCReturnsInnerPointer:
5706 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5707 case CXCursor_ObjCRequiresSuper:
5708 return cxstring::createRef("attribute(objc_requires_super)");
5709 case CXCursor_ObjCRootClass:
5710 return cxstring::createRef("attribute(objc_root_class)");
5711 case CXCursor_ObjCSubclassingRestricted:
5712 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5713 case CXCursor_ObjCExplicitProtocolImpl:
5714 return cxstring::createRef(
5715 "attribute(objc_protocol_requires_explicit_implementation)");
5716 case CXCursor_ObjCDesignatedInitializer:
5717 return cxstring::createRef("attribute(objc_designated_initializer)");
5718 case CXCursor_ObjCRuntimeVisible:
5719 return cxstring::createRef("attribute(objc_runtime_visible)");
5720 case CXCursor_ObjCBoxable:
5721 return cxstring::createRef("attribute(objc_boxable)");
5722 case CXCursor_FlagEnum:
5723 return cxstring::createRef("attribute(flag_enum)");
5724 case CXCursor_PreprocessingDirective:
5725 return cxstring::createRef("preprocessing directive");
5726 case CXCursor_MacroDefinition:
5727 return cxstring::createRef("macro definition");
5728 case CXCursor_MacroExpansion:
5729 return cxstring::createRef("macro expansion");
5730 case CXCursor_InclusionDirective:
5731 return cxstring::createRef("inclusion directive");
5732 case CXCursor_Namespace:
5733 return cxstring::createRef("Namespace");
5734 case CXCursor_LinkageSpec:
5735 return cxstring::createRef("LinkageSpec");
5736 case CXCursor_CXXBaseSpecifier:
5737 return cxstring::createRef("C++ base class specifier");
5738 case CXCursor_Constructor:
5739 return cxstring::createRef("CXXConstructor");
5740 case CXCursor_Destructor:
5741 return cxstring::createRef("CXXDestructor");
5742 case CXCursor_ConversionFunction:
5743 return cxstring::createRef("CXXConversion");
5744 case CXCursor_TemplateTypeParameter:
5745 return cxstring::createRef("TemplateTypeParameter");
5746 case CXCursor_NonTypeTemplateParameter:
5747 return cxstring::createRef("NonTypeTemplateParameter");
5748 case CXCursor_TemplateTemplateParameter:
5749 return cxstring::createRef("TemplateTemplateParameter");
5750 case CXCursor_FunctionTemplate:
5751 return cxstring::createRef("FunctionTemplate");
5752 case CXCursor_ClassTemplate:
5753 return cxstring::createRef("ClassTemplate");
5754 case CXCursor_ClassTemplatePartialSpecialization:
5755 return cxstring::createRef("ClassTemplatePartialSpecialization");
5756 case CXCursor_NamespaceAlias:
5757 return cxstring::createRef("NamespaceAlias");
5758 case CXCursor_UsingDirective:
5759 return cxstring::createRef("UsingDirective");
5760 case CXCursor_UsingDeclaration:
5761 return cxstring::createRef("UsingDeclaration");
5762 case CXCursor_TypeAliasDecl:
5763 return cxstring::createRef("TypeAliasDecl");
5764 case CXCursor_ObjCSynthesizeDecl:
5765 return cxstring::createRef("ObjCSynthesizeDecl");
5766 case CXCursor_ObjCDynamicDecl:
5767 return cxstring::createRef("ObjCDynamicDecl");
5768 case CXCursor_CXXAccessSpecifier:
5769 return cxstring::createRef("CXXAccessSpecifier");
5770 case CXCursor_ModuleImportDecl:
5771 return cxstring::createRef("ModuleImport");
5772 case CXCursor_OMPCanonicalLoop:
5773 return cxstring::createRef("OMPCanonicalLoop");
5774 case CXCursor_OMPMetaDirective:
5775 return cxstring::createRef("OMPMetaDirective");
5776 case CXCursor_OMPParallelDirective:
5777 return cxstring::createRef("OMPParallelDirective");
5778 case CXCursor_OMPSimdDirective:
5779 return cxstring::createRef("OMPSimdDirective");
5780 case CXCursor_OMPTileDirective:
5781 return cxstring::createRef("OMPTileDirective");
5782 case CXCursor_OMPUnrollDirective:
5783 return cxstring::createRef("OMPUnrollDirective");
5784 case CXCursor_OMPForDirective:
5785 return cxstring::createRef("OMPForDirective");
5786 case CXCursor_OMPForSimdDirective:
5787 return cxstring::createRef("OMPForSimdDirective");
5788 case CXCursor_OMPSectionsDirective:
5789 return cxstring::createRef("OMPSectionsDirective");
5790 case CXCursor_OMPSectionDirective:
5791 return cxstring::createRef("OMPSectionDirective");
5792 case CXCursor_OMPSingleDirective:
5793 return cxstring::createRef("OMPSingleDirective");
5794 case CXCursor_OMPMasterDirective:
5795 return cxstring::createRef("OMPMasterDirective");
5796 case CXCursor_OMPCriticalDirective:
5797 return cxstring::createRef("OMPCriticalDirective");
5798 case CXCursor_OMPParallelForDirective:
5799 return cxstring::createRef("OMPParallelForDirective");
5800 case CXCursor_OMPParallelForSimdDirective:
5801 return cxstring::createRef("OMPParallelForSimdDirective");
5802 case CXCursor_OMPParallelMasterDirective:
5803 return cxstring::createRef("OMPParallelMasterDirective");
5804 case CXCursor_OMPParallelMaskedDirective:
5805 return cxstring::createRef("OMPParallelMaskedDirective");
5806 case CXCursor_OMPParallelSectionsDirective:
5807 return cxstring::createRef("OMPParallelSectionsDirective");
5808 case CXCursor_OMPTaskDirective:
5809 return cxstring::createRef("OMPTaskDirective");
5810 case CXCursor_OMPTaskyieldDirective:
5811 return cxstring::createRef("OMPTaskyieldDirective");
5812 case CXCursor_OMPBarrierDirective:
5813 return cxstring::createRef("OMPBarrierDirective");
5814 case CXCursor_OMPTaskwaitDirective:
5815 return cxstring::createRef("OMPTaskwaitDirective");
5816 case CXCursor_OMPTaskgroupDirective:
5817 return cxstring::createRef("OMPTaskgroupDirective");
5818 case CXCursor_OMPFlushDirective:
5819 return cxstring::createRef("OMPFlushDirective");
5820 case CXCursor_OMPDepobjDirective:
5821 return cxstring::createRef("OMPDepobjDirective");
5822 case CXCursor_OMPScanDirective:
5823 return cxstring::createRef("OMPScanDirective");
5824 case CXCursor_OMPOrderedDirective:
5825 return cxstring::createRef("OMPOrderedDirective");
5826 case CXCursor_OMPAtomicDirective:
5827 return cxstring::createRef("OMPAtomicDirective");
5828 case CXCursor_OMPTargetDirective:
5829 return cxstring::createRef("OMPTargetDirective");
5830 case CXCursor_OMPTargetDataDirective:
5831 return cxstring::createRef("OMPTargetDataDirective");
5832 case CXCursor_OMPTargetEnterDataDirective:
5833 return cxstring::createRef("OMPTargetEnterDataDirective");
5834 case CXCursor_OMPTargetExitDataDirective:
5835 return cxstring::createRef("OMPTargetExitDataDirective");
5836 case CXCursor_OMPTargetParallelDirective:
5837 return cxstring::createRef("OMPTargetParallelDirective");
5838 case CXCursor_OMPTargetParallelForDirective:
5839 return cxstring::createRef("OMPTargetParallelForDirective");
5840 case CXCursor_OMPTargetUpdateDirective:
5841 return cxstring::createRef("OMPTargetUpdateDirective");
5842 case CXCursor_OMPTeamsDirective:
5843 return cxstring::createRef("OMPTeamsDirective");
5844 case CXCursor_OMPCancellationPointDirective:
5845 return cxstring::createRef("OMPCancellationPointDirective");
5846 case CXCursor_OMPCancelDirective:
5847 return cxstring::createRef("OMPCancelDirective");
5848 case CXCursor_OMPTaskLoopDirective:
5849 return cxstring::createRef("OMPTaskLoopDirective");
5850 case CXCursor_OMPTaskLoopSimdDirective:
5851 return cxstring::createRef("OMPTaskLoopSimdDirective");
5852 case CXCursor_OMPMasterTaskLoopDirective:
5853 return cxstring::createRef("OMPMasterTaskLoopDirective");
5854 case CXCursor_OMPMaskedTaskLoopDirective:
5855 return cxstring::createRef("OMPMaskedTaskLoopDirective");
5856 case CXCursor_OMPMasterTaskLoopSimdDirective:
5857 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
5858 case CXCursor_OMPMaskedTaskLoopSimdDirective:
5859 return cxstring::createRef("OMPMaskedTaskLoopSimdDirective");
5860 case CXCursor_OMPParallelMasterTaskLoopDirective:
5861 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
5862 case CXCursor_OMPParallelMaskedTaskLoopDirective:
5863 return cxstring::createRef("OMPParallelMaskedTaskLoopDirective");
5864 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5865 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
5866 case CXCursor_OMPParallelMaskedTaskLoopSimdDirective:
5867 return cxstring::createRef("OMPParallelMaskedTaskLoopSimdDirective");
5868 case CXCursor_OMPDistributeDirective:
5869 return cxstring::createRef("OMPDistributeDirective");
5870 case CXCursor_OMPDistributeParallelForDirective:
5871 return cxstring::createRef("OMPDistributeParallelForDirective");
5872 case CXCursor_OMPDistributeParallelForSimdDirective:
5873 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
5874 case CXCursor_OMPDistributeSimdDirective:
5875 return cxstring::createRef("OMPDistributeSimdDirective");
5876 case CXCursor_OMPTargetParallelForSimdDirective:
5877 return cxstring::createRef("OMPTargetParallelForSimdDirective");
5878 case CXCursor_OMPTargetSimdDirective:
5879 return cxstring::createRef("OMPTargetSimdDirective");
5880 case CXCursor_OMPTeamsDistributeDirective:
5881 return cxstring::createRef("OMPTeamsDistributeDirective");
5882 case CXCursor_OMPTeamsDistributeSimdDirective:
5883 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
5884 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5885 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
5886 case CXCursor_OMPTeamsDistributeParallelForDirective:
5887 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
5888 case CXCursor_OMPTargetTeamsDirective:
5889 return cxstring::createRef("OMPTargetTeamsDirective");
5890 case CXCursor_OMPTargetTeamsDistributeDirective:
5891 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
5892 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5893 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
5894 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5895 return cxstring::createRef(
5896 "OMPTargetTeamsDistributeParallelForSimdDirective");
5897 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5898 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
5899 case CXCursor_OMPInteropDirective:
5900 return cxstring::createRef("OMPInteropDirective");
5901 case CXCursor_OMPDispatchDirective:
5902 return cxstring::createRef("OMPDispatchDirective");
5903 case CXCursor_OMPMaskedDirective:
5904 return cxstring::createRef("OMPMaskedDirective");
5905 case CXCursor_OMPGenericLoopDirective:
5906 return cxstring::createRef("OMPGenericLoopDirective");
5907 case CXCursor_OMPTeamsGenericLoopDirective:
5908 return cxstring::createRef("OMPTeamsGenericLoopDirective");
5909 case CXCursor_OMPTargetTeamsGenericLoopDirective:
5910 return cxstring::createRef("OMPTargetTeamsGenericLoopDirective");
5911 case CXCursor_OMPParallelGenericLoopDirective:
5912 return cxstring::createRef("OMPParallelGenericLoopDirective");
5913 case CXCursor_OMPTargetParallelGenericLoopDirective:
5914 return cxstring::createRef("OMPTargetParallelGenericLoopDirective");
5915 case CXCursor_OverloadCandidate:
5916 return cxstring::createRef("OverloadCandidate");
5917 case CXCursor_TypeAliasTemplateDecl:
5918 return cxstring::createRef("TypeAliasTemplateDecl");
5919 case CXCursor_StaticAssert:
5920 return cxstring::createRef("StaticAssert");
5921 case CXCursor_FriendDecl:
5922 return cxstring::createRef("FriendDecl");
5923 case CXCursor_ConvergentAttr:
5924 return cxstring::createRef("attribute(convergent)");
5925 case CXCursor_WarnUnusedAttr:
5926 return cxstring::createRef("attribute(warn_unused)");
5927 case CXCursor_WarnUnusedResultAttr:
5928 return cxstring::createRef("attribute(warn_unused_result)");
5929 case CXCursor_AlignedAttr:
5930 return cxstring::createRef("attribute(aligned)");
5931 case CXCursor_ConceptDecl:
5932 return cxstring::createRef("ConceptDecl");
5935 llvm_unreachable("Unhandled CXCursorKind");
5938 struct GetCursorData {
5939 SourceLocation TokenBeginLoc;
5940 bool PointsAtMacroArgExpansion;
5941 bool VisitedObjCPropertyImplDecl;
5942 SourceLocation VisitedDeclaratorDeclStartLoc;
5943 CXCursor &BestCursor;
5945 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5946 CXCursor &outputCursor)
5947 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
5948 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5949 VisitedObjCPropertyImplDecl = false;
5953 static enum CXChildVisitResult
5954 GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
5955 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5956 CXCursor *BestCursor = &Data->BestCursor;
5958 // If we point inside a macro argument we should provide info of what the
5959 // token is so use the actual cursor, don't replace it with a macro expansion
5960 // cursor.
5961 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5962 return CXChildVisit_Recurse;
5964 if (clang_isDeclaration(cursor.kind)) {
5965 // Avoid having the implicit methods override the property decls.
5966 if (const ObjCMethodDecl *MD =
5967 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5968 if (MD->isImplicit())
5969 return CXChildVisit_Break;
5971 } else if (const ObjCInterfaceDecl *ID =
5972 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
5973 // Check that when we have multiple @class references in the same line,
5974 // that later ones do not override the previous ones.
5975 // If we have:
5976 // @class Foo, Bar;
5977 // source ranges for both start at '@', so 'Bar' will end up overriding
5978 // 'Foo' even though the cursor location was at 'Foo'.
5979 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5980 BestCursor->kind == CXCursor_ObjCClassRef)
5981 if (const ObjCInterfaceDecl *PrevID =
5982 dyn_cast_or_null<ObjCInterfaceDecl>(
5983 getCursorDecl(*BestCursor))) {
5984 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5985 !ID->isThisDeclarationADefinition())
5986 return CXChildVisit_Break;
5989 } else if (const DeclaratorDecl *DD =
5990 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
5991 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5992 // Check that when we have multiple declarators in the same line,
5993 // that later ones do not override the previous ones.
5994 // If we have:
5995 // int Foo, Bar;
5996 // source ranges for both start at 'int', so 'Bar' will end up overriding
5997 // 'Foo' even though the cursor location was at 'Foo'.
5998 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5999 return CXChildVisit_Break;
6000 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
6002 } else if (const ObjCPropertyImplDecl *PropImp =
6003 dyn_cast_or_null<ObjCPropertyImplDecl>(
6004 getCursorDecl(cursor))) {
6005 (void)PropImp;
6006 // Check that when we have multiple @synthesize in the same line,
6007 // that later ones do not override the previous ones.
6008 // If we have:
6009 // @synthesize Foo, Bar;
6010 // source ranges for both start at '@', so 'Bar' will end up overriding
6011 // 'Foo' even though the cursor location was at 'Foo'.
6012 if (Data->VisitedObjCPropertyImplDecl)
6013 return CXChildVisit_Break;
6014 Data->VisitedObjCPropertyImplDecl = true;
6018 if (clang_isExpression(cursor.kind) &&
6019 clang_isDeclaration(BestCursor->kind)) {
6020 if (const Decl *D = getCursorDecl(*BestCursor)) {
6021 // Avoid having the cursor of an expression replace the declaration cursor
6022 // when the expression source range overlaps the declaration range.
6023 // This can happen for C++ constructor expressions whose range generally
6024 // include the variable declaration, e.g.:
6025 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
6026 // cursor.
6027 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
6028 D->getLocation() == Data->TokenBeginLoc)
6029 return CXChildVisit_Break;
6033 // If our current best cursor is the construction of a temporary object,
6034 // don't replace that cursor with a type reference, because we want
6035 // clang_getCursor() to point at the constructor.
6036 if (clang_isExpression(BestCursor->kind) &&
6037 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
6038 cursor.kind == CXCursor_TypeRef) {
6039 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
6040 // as having the actual point on the type reference.
6041 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
6042 return CXChildVisit_Recurse;
6045 // If we already have an Objective-C superclass reference, don't
6046 // update it further.
6047 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
6048 return CXChildVisit_Break;
6050 *BestCursor = cursor;
6051 return CXChildVisit_Recurse;
6054 CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
6055 if (isNotUsableTU(TU)) {
6056 LOG_BAD_TU(TU);
6057 return clang_getNullCursor();
6060 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6061 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
6063 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
6064 CXCursor Result = cxcursor::getCursor(TU, SLoc);
6066 LOG_FUNC_SECTION {
6067 CXFile SearchFile;
6068 unsigned SearchLine, SearchColumn;
6069 CXFile ResultFile;
6070 unsigned ResultLine, ResultColumn;
6071 CXString SearchFileName, ResultFileName, KindSpelling, USR;
6072 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
6073 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
6075 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
6076 nullptr);
6077 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
6078 nullptr);
6079 SearchFileName = clang_getFileName(SearchFile);
6080 ResultFileName = clang_getFileName(ResultFile);
6081 KindSpelling = clang_getCursorKindSpelling(Result.kind);
6082 USR = clang_getCursorUSR(Result);
6083 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
6084 SearchLine, SearchColumn,
6085 clang_getCString(KindSpelling))
6086 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
6087 ResultLine, ResultColumn, clang_getCString(USR),
6088 IsDef);
6089 clang_disposeString(SearchFileName);
6090 clang_disposeString(ResultFileName);
6091 clang_disposeString(KindSpelling);
6092 clang_disposeString(USR);
6094 CXCursor Definition = clang_getCursorDefinition(Result);
6095 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
6096 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
6097 CXString DefinitionKindSpelling =
6098 clang_getCursorKindSpelling(Definition.kind);
6099 CXFile DefinitionFile;
6100 unsigned DefinitionLine, DefinitionColumn;
6101 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
6102 &DefinitionColumn, nullptr);
6103 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
6104 *Log << llvm::format(" -> %s(%s:%d:%d)",
6105 clang_getCString(DefinitionKindSpelling),
6106 clang_getCString(DefinitionFileName), DefinitionLine,
6107 DefinitionColumn);
6108 clang_disposeString(DefinitionFileName);
6109 clang_disposeString(DefinitionKindSpelling);
6113 return Result;
6116 CXCursor clang_getNullCursor(void) {
6117 return MakeCXCursorInvalid(CXCursor_InvalidFile);
6120 unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
6121 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
6122 // can't set consistently. For example, when visiting a DeclStmt we will set
6123 // it but we don't set it on the result of clang_getCursorDefinition for
6124 // a reference of the same declaration.
6125 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
6126 // when visiting a DeclStmt currently, the AST should be enhanced to be able
6127 // to provide that kind of info.
6128 if (clang_isDeclaration(X.kind))
6129 X.data[1] = nullptr;
6130 if (clang_isDeclaration(Y.kind))
6131 Y.data[1] = nullptr;
6133 return X == Y;
6136 unsigned clang_hashCursor(CXCursor C) {
6137 unsigned Index = 0;
6138 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
6139 Index = 1;
6141 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
6142 std::make_pair(C.kind, C.data[Index]));
6145 unsigned clang_isInvalid(enum CXCursorKind K) {
6146 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
6149 unsigned clang_isDeclaration(enum CXCursorKind K) {
6150 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
6151 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
6154 unsigned clang_isInvalidDeclaration(CXCursor C) {
6155 if (clang_isDeclaration(C.kind)) {
6156 if (const Decl *D = getCursorDecl(C))
6157 return D->isInvalidDecl();
6160 return 0;
6163 unsigned clang_isReference(enum CXCursorKind K) {
6164 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
6167 unsigned clang_isExpression(enum CXCursorKind K) {
6168 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
6171 unsigned clang_isStatement(enum CXCursorKind K) {
6172 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
6175 unsigned clang_isAttribute(enum CXCursorKind K) {
6176 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
6179 unsigned clang_isTranslationUnit(enum CXCursorKind K) {
6180 return K == CXCursor_TranslationUnit;
6183 unsigned clang_isPreprocessing(enum CXCursorKind K) {
6184 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
6187 unsigned clang_isUnexposed(enum CXCursorKind K) {
6188 switch (K) {
6189 case CXCursor_UnexposedDecl:
6190 case CXCursor_UnexposedExpr:
6191 case CXCursor_UnexposedStmt:
6192 case CXCursor_UnexposedAttr:
6193 return true;
6194 default:
6195 return false;
6199 CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
6201 CXSourceLocation clang_getCursorLocation(CXCursor C) {
6202 if (clang_isReference(C.kind)) {
6203 switch (C.kind) {
6204 case CXCursor_ObjCSuperClassRef: {
6205 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
6206 getCursorObjCSuperClassRef(C);
6207 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6210 case CXCursor_ObjCProtocolRef: {
6211 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
6212 getCursorObjCProtocolRef(C);
6213 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6216 case CXCursor_ObjCClassRef: {
6217 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
6218 getCursorObjCClassRef(C);
6219 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6222 case CXCursor_TypeRef: {
6223 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
6224 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6227 case CXCursor_TemplateRef: {
6228 std::pair<const TemplateDecl *, SourceLocation> P =
6229 getCursorTemplateRef(C);
6230 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6233 case CXCursor_NamespaceRef: {
6234 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
6235 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6238 case CXCursor_MemberRef: {
6239 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
6240 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6243 case CXCursor_VariableRef: {
6244 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
6245 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
6248 case CXCursor_CXXBaseSpecifier: {
6249 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
6250 if (!BaseSpec)
6251 return clang_getNullLocation();
6253 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
6254 return cxloc::translateSourceLocation(
6255 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
6257 return cxloc::translateSourceLocation(getCursorContext(C),
6258 BaseSpec->getBeginLoc());
6261 case CXCursor_LabelRef: {
6262 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
6263 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
6266 case CXCursor_OverloadedDeclRef:
6267 return cxloc::translateSourceLocation(
6268 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
6270 default:
6271 // FIXME: Need a way to enumerate all non-reference cases.
6272 llvm_unreachable("Missed a reference kind");
6276 if (clang_isExpression(C.kind))
6277 return cxloc::translateSourceLocation(
6278 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
6280 if (clang_isStatement(C.kind))
6281 return cxloc::translateSourceLocation(getCursorContext(C),
6282 getCursorStmt(C)->getBeginLoc());
6284 if (C.kind == CXCursor_PreprocessingDirective) {
6285 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
6286 return cxloc::translateSourceLocation(getCursorContext(C), L);
6289 if (C.kind == CXCursor_MacroExpansion) {
6290 SourceLocation L =
6291 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
6292 return cxloc::translateSourceLocation(getCursorContext(C), L);
6295 if (C.kind == CXCursor_MacroDefinition) {
6296 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
6297 return cxloc::translateSourceLocation(getCursorContext(C), L);
6300 if (C.kind == CXCursor_InclusionDirective) {
6301 SourceLocation L =
6302 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
6303 return cxloc::translateSourceLocation(getCursorContext(C), L);
6306 if (clang_isAttribute(C.kind)) {
6307 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
6308 return cxloc::translateSourceLocation(getCursorContext(C), L);
6311 if (!clang_isDeclaration(C.kind))
6312 return clang_getNullLocation();
6314 const Decl *D = getCursorDecl(C);
6315 if (!D)
6316 return clang_getNullLocation();
6318 SourceLocation Loc = D->getLocation();
6319 // FIXME: Multiple variables declared in a single declaration
6320 // currently lack the information needed to correctly determine their
6321 // ranges when accounting for the type-specifier. We use context
6322 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6323 // and if so, whether it is the first decl.
6324 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6325 if (!cxcursor::isFirstInDeclGroup(C))
6326 Loc = VD->getLocation();
6329 // For ObjC methods, give the start location of the method name.
6330 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6331 Loc = MD->getSelectorStartLoc();
6333 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
6336 } // end extern "C"
6338 CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6339 assert(TU);
6341 // Guard against an invalid SourceLocation, or we may assert in one
6342 // of the following calls.
6343 if (SLoc.isInvalid())
6344 return clang_getNullCursor();
6346 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6348 // Translate the given source location to make it point at the beginning of
6349 // the token under the cursor.
6350 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6351 CXXUnit->getASTContext().getLangOpts());
6353 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6354 if (SLoc.isValid()) {
6355 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6356 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
6357 /*VisitPreprocessorLast=*/true,
6358 /*VisitIncludedEntities=*/false,
6359 SourceLocation(SLoc));
6360 CursorVis.visitFileRegion();
6363 return Result;
6366 static SourceRange getRawCursorExtent(CXCursor C) {
6367 if (clang_isReference(C.kind)) {
6368 switch (C.kind) {
6369 case CXCursor_ObjCSuperClassRef:
6370 return getCursorObjCSuperClassRef(C).second;
6372 case CXCursor_ObjCProtocolRef:
6373 return getCursorObjCProtocolRef(C).second;
6375 case CXCursor_ObjCClassRef:
6376 return getCursorObjCClassRef(C).second;
6378 case CXCursor_TypeRef:
6379 return getCursorTypeRef(C).second;
6381 case CXCursor_TemplateRef:
6382 return getCursorTemplateRef(C).second;
6384 case CXCursor_NamespaceRef:
6385 return getCursorNamespaceRef(C).second;
6387 case CXCursor_MemberRef:
6388 return getCursorMemberRef(C).second;
6390 case CXCursor_CXXBaseSpecifier:
6391 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6393 case CXCursor_LabelRef:
6394 return getCursorLabelRef(C).second;
6396 case CXCursor_OverloadedDeclRef:
6397 return getCursorOverloadedDeclRef(C).second;
6399 case CXCursor_VariableRef:
6400 return getCursorVariableRef(C).second;
6402 default:
6403 // FIXME: Need a way to enumerate all non-reference cases.
6404 llvm_unreachable("Missed a reference kind");
6408 if (clang_isExpression(C.kind))
6409 return getCursorExpr(C)->getSourceRange();
6411 if (clang_isStatement(C.kind))
6412 return getCursorStmt(C)->getSourceRange();
6414 if (clang_isAttribute(C.kind))
6415 return getCursorAttr(C)->getRange();
6417 if (C.kind == CXCursor_PreprocessingDirective)
6418 return cxcursor::getCursorPreprocessingDirective(C);
6420 if (C.kind == CXCursor_MacroExpansion) {
6421 ASTUnit *TU = getCursorASTUnit(C);
6422 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
6423 return TU->mapRangeFromPreamble(Range);
6426 if (C.kind == CXCursor_MacroDefinition) {
6427 ASTUnit *TU = getCursorASTUnit(C);
6428 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6429 return TU->mapRangeFromPreamble(Range);
6432 if (C.kind == CXCursor_InclusionDirective) {
6433 ASTUnit *TU = getCursorASTUnit(C);
6434 SourceRange Range =
6435 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
6436 return TU->mapRangeFromPreamble(Range);
6439 if (C.kind == CXCursor_TranslationUnit) {
6440 ASTUnit *TU = getCursorASTUnit(C);
6441 FileID MainID = TU->getSourceManager().getMainFileID();
6442 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6443 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6444 return SourceRange(Start, End);
6447 if (clang_isDeclaration(C.kind)) {
6448 const Decl *D = cxcursor::getCursorDecl(C);
6449 if (!D)
6450 return SourceRange();
6452 SourceRange R = D->getSourceRange();
6453 // FIXME: Multiple variables declared in a single declaration
6454 // currently lack the information needed to correctly determine their
6455 // ranges when accounting for the type-specifier. We use context
6456 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6457 // and if so, whether it is the first decl.
6458 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6459 if (!cxcursor::isFirstInDeclGroup(C))
6460 R.setBegin(VD->getLocation());
6462 return R;
6464 return SourceRange();
6467 /// Retrieves the "raw" cursor extent, which is then extended to include
6468 /// the decl-specifier-seq for declarations.
6469 static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6470 if (clang_isDeclaration(C.kind)) {
6471 const Decl *D = cxcursor::getCursorDecl(C);
6472 if (!D)
6473 return SourceRange();
6475 SourceRange R = D->getSourceRange();
6477 // Adjust the start of the location for declarations preceded by
6478 // declaration specifiers.
6479 SourceLocation StartLoc;
6480 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6481 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
6482 StartLoc = TI->getTypeLoc().getBeginLoc();
6483 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
6484 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
6485 StartLoc = TI->getTypeLoc().getBeginLoc();
6488 if (StartLoc.isValid() && R.getBegin().isValid() &&
6489 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6490 R.setBegin(StartLoc);
6492 // FIXME: Multiple variables declared in a single declaration
6493 // currently lack the information needed to correctly determine their
6494 // ranges when accounting for the type-specifier. We use context
6495 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6496 // and if so, whether it is the first decl.
6497 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6498 if (!cxcursor::isFirstInDeclGroup(C))
6499 R.setBegin(VD->getLocation());
6502 return R;
6505 return getRawCursorExtent(C);
6508 CXSourceRange clang_getCursorExtent(CXCursor C) {
6509 SourceRange R = getRawCursorExtent(C);
6510 if (R.isInvalid())
6511 return clang_getNullRange();
6513 return cxloc::translateSourceRange(getCursorContext(C), R);
6516 CXCursor clang_getCursorReferenced(CXCursor C) {
6517 if (clang_isInvalid(C.kind))
6518 return clang_getNullCursor();
6520 CXTranslationUnit tu = getCursorTU(C);
6521 if (clang_isDeclaration(C.kind)) {
6522 const Decl *D = getCursorDecl(C);
6523 if (!D)
6524 return clang_getNullCursor();
6525 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
6526 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
6527 if (const ObjCPropertyImplDecl *PropImpl =
6528 dyn_cast<ObjCPropertyImplDecl>(D))
6529 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6530 return MakeCXCursor(Property, tu);
6532 return C;
6535 if (clang_isExpression(C.kind)) {
6536 const Expr *E = getCursorExpr(C);
6537 const Decl *D = getDeclFromExpr(E);
6538 if (D) {
6539 CXCursor declCursor = MakeCXCursor(D, tu);
6540 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6541 declCursor);
6542 return declCursor;
6545 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
6546 return MakeCursorOverloadedDeclRef(Ovl, tu);
6548 return clang_getNullCursor();
6551 if (clang_isStatement(C.kind)) {
6552 const Stmt *S = getCursorStmt(C);
6553 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
6554 if (LabelDecl *label = Goto->getLabel())
6555 if (LabelStmt *labelS = label->getStmt())
6556 return MakeCXCursor(labelS, getCursorDecl(C), tu);
6558 return clang_getNullCursor();
6561 if (C.kind == CXCursor_MacroExpansion) {
6562 if (const MacroDefinitionRecord *Def =
6563 getCursorMacroExpansion(C).getDefinition())
6564 return MakeMacroDefinitionCursor(Def, tu);
6567 if (!clang_isReference(C.kind))
6568 return clang_getNullCursor();
6570 switch (C.kind) {
6571 case CXCursor_ObjCSuperClassRef:
6572 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
6574 case CXCursor_ObjCProtocolRef: {
6575 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6576 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6577 return MakeCXCursor(Def, tu);
6579 return MakeCXCursor(Prot, tu);
6582 case CXCursor_ObjCClassRef: {
6583 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6584 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6585 return MakeCXCursor(Def, tu);
6587 return MakeCXCursor(Class, tu);
6590 case CXCursor_TypeRef:
6591 return MakeCXCursor(getCursorTypeRef(C).first, tu);
6593 case CXCursor_TemplateRef:
6594 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
6596 case CXCursor_NamespaceRef:
6597 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
6599 case CXCursor_MemberRef:
6600 return MakeCXCursor(getCursorMemberRef(C).first, tu);
6602 case CXCursor_CXXBaseSpecifier: {
6603 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6604 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6607 case CXCursor_LabelRef:
6608 // FIXME: We end up faking the "parent" declaration here because we
6609 // don't want to make CXCursor larger.
6610 return MakeCXCursor(
6611 getCursorLabelRef(C).first,
6612 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
6614 case CXCursor_OverloadedDeclRef:
6615 return C;
6617 case CXCursor_VariableRef:
6618 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6620 default:
6621 // We would prefer to enumerate all non-reference cursor kinds here.
6622 llvm_unreachable("Unhandled reference cursor kind");
6626 CXCursor clang_getCursorDefinition(CXCursor C) {
6627 if (clang_isInvalid(C.kind))
6628 return clang_getNullCursor();
6630 CXTranslationUnit TU = getCursorTU(C);
6632 bool WasReference = false;
6633 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6634 C = clang_getCursorReferenced(C);
6635 WasReference = true;
6638 if (C.kind == CXCursor_MacroExpansion)
6639 return clang_getCursorReferenced(C);
6641 if (!clang_isDeclaration(C.kind))
6642 return clang_getNullCursor();
6644 const Decl *D = getCursorDecl(C);
6645 if (!D)
6646 return clang_getNullCursor();
6648 switch (D->getKind()) {
6649 // Declaration kinds that don't really separate the notions of
6650 // declaration and definition.
6651 case Decl::Namespace:
6652 case Decl::Typedef:
6653 case Decl::TypeAlias:
6654 case Decl::TypeAliasTemplate:
6655 case Decl::TemplateTypeParm:
6656 case Decl::EnumConstant:
6657 case Decl::Field:
6658 case Decl::Binding:
6659 case Decl::MSProperty:
6660 case Decl::MSGuid:
6661 case Decl::UnnamedGlobalConstant:
6662 case Decl::TemplateParamObject:
6663 case Decl::IndirectField:
6664 case Decl::ObjCIvar:
6665 case Decl::ObjCAtDefsField:
6666 case Decl::ImplicitParam:
6667 case Decl::ParmVar:
6668 case Decl::NonTypeTemplateParm:
6669 case Decl::TemplateTemplateParm:
6670 case Decl::ObjCCategoryImpl:
6671 case Decl::ObjCImplementation:
6672 case Decl::AccessSpec:
6673 case Decl::LinkageSpec:
6674 case Decl::Export:
6675 case Decl::ObjCPropertyImpl:
6676 case Decl::FileScopeAsm:
6677 case Decl::StaticAssert:
6678 case Decl::Block:
6679 case Decl::Captured:
6680 case Decl::OMPCapturedExpr:
6681 case Decl::Label: // FIXME: Is this right??
6682 case Decl::ClassScopeFunctionSpecialization:
6683 case Decl::CXXDeductionGuide:
6684 case Decl::Import:
6685 case Decl::OMPThreadPrivate:
6686 case Decl::OMPAllocate:
6687 case Decl::OMPDeclareReduction:
6688 case Decl::OMPDeclareMapper:
6689 case Decl::OMPRequires:
6690 case Decl::ObjCTypeParam:
6691 case Decl::BuiltinTemplate:
6692 case Decl::PragmaComment:
6693 case Decl::PragmaDetectMismatch:
6694 case Decl::UsingPack:
6695 case Decl::Concept:
6696 case Decl::LifetimeExtendedTemporary:
6697 case Decl::RequiresExprBody:
6698 case Decl::UnresolvedUsingIfExists:
6699 return C;
6701 // Declaration kinds that don't make any sense here, but are
6702 // nonetheless harmless.
6703 case Decl::Empty:
6704 case Decl::TranslationUnit:
6705 case Decl::ExternCContext:
6706 break;
6708 // Declaration kinds for which the definition is not resolvable.
6709 case Decl::UnresolvedUsingTypename:
6710 case Decl::UnresolvedUsingValue:
6711 break;
6713 case Decl::UsingDirective:
6714 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6715 TU);
6717 case Decl::NamespaceAlias:
6718 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6720 case Decl::Enum:
6721 case Decl::Record:
6722 case Decl::CXXRecord:
6723 case Decl::ClassTemplateSpecialization:
6724 case Decl::ClassTemplatePartialSpecialization:
6725 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6726 return MakeCXCursor(Def, TU);
6727 return clang_getNullCursor();
6729 case Decl::Function:
6730 case Decl::CXXMethod:
6731 case Decl::CXXConstructor:
6732 case Decl::CXXDestructor:
6733 case Decl::CXXConversion: {
6734 const FunctionDecl *Def = nullptr;
6735 if (cast<FunctionDecl>(D)->getBody(Def))
6736 return MakeCXCursor(Def, TU);
6737 return clang_getNullCursor();
6740 case Decl::Var:
6741 case Decl::VarTemplateSpecialization:
6742 case Decl::VarTemplatePartialSpecialization:
6743 case Decl::Decomposition: {
6744 // Ask the variable if it has a definition.
6745 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
6746 return MakeCXCursor(Def, TU);
6747 return clang_getNullCursor();
6750 case Decl::FunctionTemplate: {
6751 const FunctionDecl *Def = nullptr;
6752 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6753 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6754 return clang_getNullCursor();
6757 case Decl::ClassTemplate: {
6758 if (RecordDecl *Def =
6759 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6760 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6761 TU);
6762 return clang_getNullCursor();
6765 case Decl::VarTemplate: {
6766 if (VarDecl *Def =
6767 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6768 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6769 return clang_getNullCursor();
6772 case Decl::Using:
6773 case Decl::UsingEnum:
6774 return MakeCursorOverloadedDeclRef(cast<BaseUsingDecl>(D), D->getLocation(),
6775 TU);
6777 case Decl::UsingShadow:
6778 case Decl::ConstructorUsingShadow:
6779 return clang_getCursorDefinition(
6780 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
6782 case Decl::ObjCMethod: {
6783 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
6784 if (Method->isThisDeclarationADefinition())
6785 return C;
6787 // Dig out the method definition in the associated
6788 // @implementation, if we have it.
6789 // FIXME: The ASTs should make finding the definition easier.
6790 if (const ObjCInterfaceDecl *Class =
6791 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
6792 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
6793 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6794 Method->getSelector(), Method->isInstanceMethod()))
6795 if (Def->isThisDeclarationADefinition())
6796 return MakeCXCursor(Def, TU);
6798 return clang_getNullCursor();
6801 case Decl::ObjCCategory:
6802 if (ObjCCategoryImplDecl *Impl =
6803 cast<ObjCCategoryDecl>(D)->getImplementation())
6804 return MakeCXCursor(Impl, TU);
6805 return clang_getNullCursor();
6807 case Decl::ObjCProtocol:
6808 if (const ObjCProtocolDecl *Def =
6809 cast<ObjCProtocolDecl>(D)->getDefinition())
6810 return MakeCXCursor(Def, TU);
6811 return clang_getNullCursor();
6813 case Decl::ObjCInterface: {
6814 // There are two notions of a "definition" for an Objective-C
6815 // class: the interface and its implementation. When we resolved a
6816 // reference to an Objective-C class, produce the @interface as
6817 // the definition; when we were provided with the interface,
6818 // produce the @implementation as the definition.
6819 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
6820 if (WasReference) {
6821 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
6822 return MakeCXCursor(Def, TU);
6823 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6824 return MakeCXCursor(Impl, TU);
6825 return clang_getNullCursor();
6828 case Decl::ObjCProperty:
6829 // FIXME: We don't really know where to find the
6830 // ObjCPropertyImplDecls that implement this property.
6831 return clang_getNullCursor();
6833 case Decl::ObjCCompatibleAlias:
6834 if (const ObjCInterfaceDecl *Class =
6835 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
6836 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6837 return MakeCXCursor(Def, TU);
6839 return clang_getNullCursor();
6841 case Decl::Friend:
6842 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6843 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6844 return clang_getNullCursor();
6846 case Decl::FriendTemplate:
6847 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6848 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6849 return clang_getNullCursor();
6852 return clang_getNullCursor();
6855 unsigned clang_isCursorDefinition(CXCursor C) {
6856 if (!clang_isDeclaration(C.kind))
6857 return 0;
6859 return clang_getCursorDefinition(C) == C;
6862 CXCursor clang_getCanonicalCursor(CXCursor C) {
6863 if (!clang_isDeclaration(C.kind))
6864 return C;
6866 if (const Decl *D = getCursorDecl(C)) {
6867 if (const ObjCCategoryImplDecl *CatImplD =
6868 dyn_cast<ObjCCategoryImplDecl>(D))
6869 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6870 return MakeCXCursor(CatD, getCursorTU(C));
6872 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6873 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
6874 return MakeCXCursor(IFD, getCursorTU(C));
6876 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6879 return C;
6882 int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6883 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6886 unsigned clang_getNumOverloadedDecls(CXCursor C) {
6887 if (C.kind != CXCursor_OverloadedDeclRef)
6888 return 0;
6890 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
6891 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
6892 return E->getNumDecls();
6894 if (OverloadedTemplateStorage *S =
6895 Storage.dyn_cast<OverloadedTemplateStorage *>())
6896 return S->size();
6898 const Decl *D = Storage.get<const Decl *>();
6899 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
6900 return Using->shadow_size();
6902 return 0;
6905 CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6906 if (cursor.kind != CXCursor_OverloadedDeclRef)
6907 return clang_getNullCursor();
6909 if (index >= clang_getNumOverloadedDecls(cursor))
6910 return clang_getNullCursor();
6912 CXTranslationUnit TU = getCursorTU(cursor);
6913 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
6914 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
6915 return MakeCXCursor(E->decls_begin()[index], TU);
6917 if (OverloadedTemplateStorage *S =
6918 Storage.dyn_cast<OverloadedTemplateStorage *>())
6919 return MakeCXCursor(S->begin()[index], TU);
6921 const Decl *D = Storage.get<const Decl *>();
6922 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
6923 // FIXME: This is, unfortunately, linear time.
6924 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6925 std::advance(Pos, index);
6926 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6929 return clang_getNullCursor();
6932 void clang_getDefinitionSpellingAndExtent(
6933 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6934 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
6935 assert(getCursorDecl(C) && "CXCursor has null decl");
6936 const auto *FD = cast<FunctionDecl>(getCursorDecl(C));
6937 const auto *Body = cast<CompoundStmt>(FD->getBody());
6939 SourceManager &SM = FD->getASTContext().getSourceManager();
6940 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6941 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6942 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6943 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6944 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6945 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6948 CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6949 unsigned PieceIndex) {
6950 RefNamePieces Pieces;
6952 switch (C.kind) {
6953 case CXCursor_MemberRefExpr:
6954 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
6955 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6956 E->getQualifierLoc().getSourceRange());
6957 break;
6959 case CXCursor_DeclRefExpr:
6960 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6961 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6962 Pieces =
6963 buildPieces(NameFlags, false, E->getNameInfo(),
6964 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6966 break;
6968 case CXCursor_CallExpr:
6969 if (const CXXOperatorCallExpr *OCE =
6970 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
6971 const Expr *Callee = OCE->getCallee();
6972 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
6973 Callee = ICE->getSubExpr();
6975 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
6976 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6977 DRE->getQualifierLoc().getSourceRange());
6979 break;
6981 default:
6982 break;
6985 if (Pieces.empty()) {
6986 if (PieceIndex == 0)
6987 return clang_getCursorExtent(C);
6988 } else if (PieceIndex < Pieces.size()) {
6989 SourceRange R = Pieces[PieceIndex];
6990 if (R.isValid())
6991 return cxloc::translateSourceRange(getCursorContext(C), R);
6994 return clang_getNullRange();
6997 void clang_enableStackTraces(void) {
6998 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6999 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
7002 void clang_executeOnThread(void (*fn)(void *), void *user_data,
7003 unsigned stack_size) {
7004 llvm::thread Thread(stack_size == 0 ? clang::DesiredStackSize
7005 : llvm::Optional<unsigned>(stack_size),
7006 fn, user_data);
7007 Thread.join();
7010 //===----------------------------------------------------------------------===//
7011 // Token-based Operations.
7012 //===----------------------------------------------------------------------===//
7014 /* CXToken layout:
7015 * int_data[0]: a CXTokenKind
7016 * int_data[1]: starting token location
7017 * int_data[2]: token length
7018 * int_data[3]: reserved
7019 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
7020 * otherwise unused.
7022 CXTokenKind clang_getTokenKind(CXToken CXTok) {
7023 return static_cast<CXTokenKind>(CXTok.int_data[0]);
7026 CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
7027 switch (clang_getTokenKind(CXTok)) {
7028 case CXToken_Identifier:
7029 case CXToken_Keyword:
7030 // We know we have an IdentifierInfo*, so use that.
7031 return cxstring::createRef(
7032 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
7034 case CXToken_Literal: {
7035 // We have stashed the starting pointer in the ptr_data field. Use it.
7036 const char *Text = static_cast<const char *>(CXTok.ptr_data);
7037 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
7040 case CXToken_Punctuation:
7041 case CXToken_Comment:
7042 break;
7045 if (isNotUsableTU(TU)) {
7046 LOG_BAD_TU(TU);
7047 return cxstring::createEmpty();
7050 // We have to find the starting buffer pointer the hard way, by
7051 // deconstructing the source location.
7052 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7053 if (!CXXUnit)
7054 return cxstring::createEmpty();
7056 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
7057 std::pair<FileID, unsigned> LocInfo =
7058 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
7059 bool Invalid = false;
7060 StringRef Buffer =
7061 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
7062 if (Invalid)
7063 return cxstring::createEmpty();
7065 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
7068 CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
7069 if (isNotUsableTU(TU)) {
7070 LOG_BAD_TU(TU);
7071 return clang_getNullLocation();
7074 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7075 if (!CXXUnit)
7076 return clang_getNullLocation();
7078 return cxloc::translateSourceLocation(
7079 CXXUnit->getASTContext(),
7080 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
7083 CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
7084 if (isNotUsableTU(TU)) {
7085 LOG_BAD_TU(TU);
7086 return clang_getNullRange();
7089 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7090 if (!CXXUnit)
7091 return clang_getNullRange();
7093 return cxloc::translateSourceRange(
7094 CXXUnit->getASTContext(),
7095 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
7098 static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
7099 SmallVectorImpl<CXToken> &CXTokens) {
7100 SourceManager &SourceMgr = CXXUnit->getSourceManager();
7101 std::pair<FileID, unsigned> BeginLocInfo =
7102 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
7103 std::pair<FileID, unsigned> EndLocInfo =
7104 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
7106 // Cannot tokenize across files.
7107 if (BeginLocInfo.first != EndLocInfo.first)
7108 return;
7110 // Create a lexer
7111 bool Invalid = false;
7112 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7113 if (Invalid)
7114 return;
7116 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
7117 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7118 Buffer.data() + BeginLocInfo.second, Buffer.end());
7119 Lex.SetCommentRetentionState(true);
7121 // Lex tokens until we hit the end of the range.
7122 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
7123 Token Tok;
7124 bool previousWasAt = false;
7125 do {
7126 // Lex the next token
7127 Lex.LexFromRawLexer(Tok);
7128 if (Tok.is(tok::eof))
7129 break;
7131 // Initialize the CXToken.
7132 CXToken CXTok;
7134 // - Common fields
7135 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
7136 CXTok.int_data[2] = Tok.getLength();
7137 CXTok.int_data[3] = 0;
7139 // - Kind-specific fields
7140 if (Tok.isLiteral()) {
7141 CXTok.int_data[0] = CXToken_Literal;
7142 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
7143 } else if (Tok.is(tok::raw_identifier)) {
7144 // Lookup the identifier to determine whether we have a keyword.
7145 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
7147 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
7148 CXTok.int_data[0] = CXToken_Keyword;
7149 } else {
7150 CXTok.int_data[0] =
7151 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
7153 CXTok.ptr_data = II;
7154 } else if (Tok.is(tok::comment)) {
7155 CXTok.int_data[0] = CXToken_Comment;
7156 CXTok.ptr_data = nullptr;
7157 } else {
7158 CXTok.int_data[0] = CXToken_Punctuation;
7159 CXTok.ptr_data = nullptr;
7161 CXTokens.push_back(CXTok);
7162 previousWasAt = Tok.is(tok::at);
7163 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
7166 CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
7167 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
7169 if (isNotUsableTU(TU)) {
7170 LOG_BAD_TU(TU);
7171 return nullptr;
7174 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7175 if (!CXXUnit)
7176 return nullptr;
7178 SourceLocation Begin = cxloc::translateSourceLocation(Location);
7179 if (Begin.isInvalid())
7180 return nullptr;
7181 SourceManager &SM = CXXUnit->getSourceManager();
7182 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
7183 DecomposedEnd.second +=
7184 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
7186 SourceLocation End =
7187 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
7189 SmallVector<CXToken, 32> CXTokens;
7190 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
7192 if (CXTokens.empty())
7193 return nullptr;
7195 CXTokens.resize(1);
7196 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
7198 memmove(Token, CXTokens.data(), sizeof(CXToken));
7199 return Token;
7202 void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
7203 unsigned *NumTokens) {
7204 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
7206 if (Tokens)
7207 *Tokens = nullptr;
7208 if (NumTokens)
7209 *NumTokens = 0;
7211 if (isNotUsableTU(TU)) {
7212 LOG_BAD_TU(TU);
7213 return;
7216 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7217 if (!CXXUnit || !Tokens || !NumTokens)
7218 return;
7220 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
7222 SourceRange R = cxloc::translateCXSourceRange(Range);
7223 if (R.isInvalid())
7224 return;
7226 SmallVector<CXToken, 32> CXTokens;
7227 getTokens(CXXUnit, R, CXTokens);
7229 if (CXTokens.empty())
7230 return;
7232 *Tokens = static_cast<CXToken *>(
7233 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
7234 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
7235 *NumTokens = CXTokens.size();
7238 void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
7239 unsigned NumTokens) {
7240 free(Tokens);
7243 //===----------------------------------------------------------------------===//
7244 // Token annotation APIs.
7245 //===----------------------------------------------------------------------===//
7247 static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7248 CXCursor parent,
7249 CXClientData client_data);
7250 static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7251 CXClientData client_data);
7253 namespace {
7254 class AnnotateTokensWorker {
7255 CXToken *Tokens;
7256 CXCursor *Cursors;
7257 unsigned NumTokens;
7258 unsigned TokIdx;
7259 unsigned PreprocessingTokIdx;
7260 CursorVisitor AnnotateVis;
7261 SourceManager &SrcMgr;
7262 bool HasContextSensitiveKeywords;
7264 struct PostChildrenAction {
7265 CXCursor cursor;
7266 enum Action { Invalid, Ignore, Postpone } action;
7268 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
7270 struct PostChildrenInfo {
7271 CXCursor Cursor;
7272 SourceRange CursorRange;
7273 unsigned BeforeReachingCursorIdx;
7274 unsigned BeforeChildrenTokenIdx;
7275 PostChildrenActions ChildActions;
7277 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
7279 CXToken &getTok(unsigned Idx) {
7280 assert(Idx < NumTokens);
7281 return Tokens[Idx];
7283 const CXToken &getTok(unsigned Idx) const {
7284 assert(Idx < NumTokens);
7285 return Tokens[Idx];
7287 bool MoreTokens() const { return TokIdx < NumTokens; }
7288 unsigned NextToken() const { return TokIdx; }
7289 void AdvanceToken() { ++TokIdx; }
7290 SourceLocation GetTokenLoc(unsigned tokI) {
7291 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
7293 bool isFunctionMacroToken(unsigned tokI) const {
7294 return getTok(tokI).int_data[3] != 0;
7296 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
7297 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
7300 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
7301 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
7302 SourceRange);
7304 public:
7305 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
7306 CXTranslationUnit TU, SourceRange RegionOfInterest)
7307 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
7308 PreprocessingTokIdx(0),
7309 AnnotateVis(TU, AnnotateTokensVisitor, this,
7310 /*VisitPreprocessorLast=*/true,
7311 /*VisitIncludedEntities=*/false, RegionOfInterest,
7312 /*VisitDeclsOnly=*/false,
7313 AnnotateTokensPostChildrenVisitor),
7314 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
7315 HasContextSensitiveKeywords(false) {}
7317 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
7318 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
7319 bool IsIgnoredChildCursor(CXCursor cursor) const;
7320 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
7322 bool postVisitChildren(CXCursor cursor);
7323 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
7324 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
7326 void AnnotateTokens();
7328 /// Determine whether the annotator saw any cursors that have
7329 /// context-sensitive keywords.
7330 bool hasContextSensitiveKeywords() const {
7331 return HasContextSensitiveKeywords;
7334 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
7336 } // namespace
7338 void AnnotateTokensWorker::AnnotateTokens() {
7339 // Walk the AST within the region of interest, annotating tokens
7340 // along the way.
7341 AnnotateVis.visitFileRegion();
7344 bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7345 if (PostChildrenInfos.empty())
7346 return false;
7348 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7349 if (ChildAction.cursor == cursor &&
7350 ChildAction.action == PostChildrenAction::Ignore) {
7351 return true;
7355 return false;
7358 const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7359 if (!clang_isExpression(Cursor.kind))
7360 return nullptr;
7362 const Expr *E = getCursorExpr(Cursor);
7363 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7364 const OverloadedOperatorKind Kind = OCE->getOperator();
7365 if (Kind == OO_Call || Kind == OO_Subscript)
7366 return OCE;
7369 return nullptr;
7372 AnnotateTokensWorker::PostChildrenActions
7373 AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7374 PostChildrenActions actions;
7376 // The DeclRefExpr of CXXOperatorCallExpr referring to the custom operator is
7377 // visited before the arguments to the operator call. For the Call and
7378 // Subscript operator the range of this DeclRefExpr includes the whole call
7379 // expression, so that all tokens in that range would be mapped to the
7380 // operator function, including the tokens of the arguments. To avoid that,
7381 // ensure to visit this DeclRefExpr as last node.
7382 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7383 const Expr *Callee = OCE->getCallee();
7384 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7385 const Expr *SubExpr = ICE->getSubExpr();
7386 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
7387 const Decl *parentDecl = getCursorDecl(Cursor);
7388 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7390 // Visit the DeclRefExpr as last.
7391 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7392 actions.push_back({cxChild, PostChildrenAction::Postpone});
7394 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7395 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7396 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7397 actions.push_back({cxChild, PostChildrenAction::Ignore});
7402 return actions;
7405 static inline void updateCursorAnnotation(CXCursor &Cursor,
7406 const CXCursor &updateC) {
7407 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
7408 return;
7409 Cursor = updateC;
7412 /// It annotates and advances tokens with a cursor until the comparison
7413 //// between the cursor location and the source range is the same as
7414 /// \arg compResult.
7416 /// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7417 /// Pass RangeOverlap to annotate tokens inside a range.
7418 void AnnotateTokensWorker::annotateAndAdvanceTokens(
7419 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
7420 while (MoreTokens()) {
7421 const unsigned I = NextToken();
7422 if (isFunctionMacroToken(I))
7423 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7424 return;
7426 SourceLocation TokLoc = GetTokenLoc(I);
7427 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7428 updateCursorAnnotation(Cursors[I], updateC);
7429 AdvanceToken();
7430 continue;
7432 break;
7436 /// Special annotation handling for macro argument tokens.
7437 /// \returns true if it advanced beyond all macro tokens, false otherwise.
7438 bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
7439 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
7440 assert(MoreTokens());
7441 assert(isFunctionMacroToken(NextToken()) &&
7442 "Should be called only for macro arg tokens");
7444 // This works differently than annotateAndAdvanceTokens; because expanded
7445 // macro arguments can have arbitrary translation-unit source order, we do not
7446 // advance the token index one by one until a token fails the range test.
7447 // We only advance once past all of the macro arg tokens if all of them
7448 // pass the range test. If one of them fails we keep the token index pointing
7449 // at the start of the macro arg tokens so that the failing token will be
7450 // annotated by a subsequent annotation try.
7452 bool atLeastOneCompFail = false;
7454 unsigned I = NextToken();
7455 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7456 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7457 if (TokLoc.isFileID())
7458 continue; // not macro arg token, it's parens or comma.
7459 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7460 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7461 Cursors[I] = updateC;
7462 } else
7463 atLeastOneCompFail = true;
7466 if (atLeastOneCompFail)
7467 return false;
7469 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7470 return true;
7473 enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7474 CXCursor parent) {
7475 SourceRange cursorRange = getRawCursorExtent(cursor);
7476 if (cursorRange.isInvalid())
7477 return CXChildVisit_Recurse;
7479 if (IsIgnoredChildCursor(cursor))
7480 return CXChildVisit_Continue;
7482 if (!HasContextSensitiveKeywords) {
7483 // Objective-C properties can have context-sensitive keywords.
7484 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
7485 if (const ObjCPropertyDecl *Property =
7486 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7487 HasContextSensitiveKeywords =
7488 Property->getPropertyAttributesAsWritten() != 0;
7490 // Objective-C methods can have context-sensitive keywords.
7491 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7492 cursor.kind == CXCursor_ObjCClassMethodDecl) {
7493 if (const ObjCMethodDecl *Method =
7494 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
7495 if (Method->getObjCDeclQualifier())
7496 HasContextSensitiveKeywords = true;
7497 else {
7498 for (const auto *P : Method->parameters()) {
7499 if (P->getObjCDeclQualifier()) {
7500 HasContextSensitiveKeywords = true;
7501 break;
7507 // C++ methods can have context-sensitive keywords.
7508 else if (cursor.kind == CXCursor_CXXMethod) {
7509 if (const CXXMethodDecl *Method =
7510 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
7511 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7512 HasContextSensitiveKeywords = true;
7515 // C++ classes can have context-sensitive keywords.
7516 else if (cursor.kind == CXCursor_StructDecl ||
7517 cursor.kind == CXCursor_ClassDecl ||
7518 cursor.kind == CXCursor_ClassTemplate ||
7519 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
7520 if (const Decl *D = getCursorDecl(cursor))
7521 if (D->hasAttr<FinalAttr>())
7522 HasContextSensitiveKeywords = true;
7526 // Don't override a property annotation with its getter/setter method.
7527 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7528 parent.kind == CXCursor_ObjCPropertyDecl)
7529 return CXChildVisit_Continue;
7531 if (clang_isPreprocessing(cursor.kind)) {
7532 // Items in the preprocessing record are kept separate from items in
7533 // declarations, so we keep a separate token index.
7534 unsigned SavedTokIdx = TokIdx;
7535 TokIdx = PreprocessingTokIdx;
7537 // Skip tokens up until we catch up to the beginning of the preprocessing
7538 // entry.
7539 while (MoreTokens()) {
7540 const unsigned I = NextToken();
7541 SourceLocation TokLoc = GetTokenLoc(I);
7542 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7543 case RangeBefore:
7544 AdvanceToken();
7545 continue;
7546 case RangeAfter:
7547 case RangeOverlap:
7548 break;
7550 break;
7553 // Look at all of the tokens within this range.
7554 while (MoreTokens()) {
7555 const unsigned I = NextToken();
7556 SourceLocation TokLoc = GetTokenLoc(I);
7557 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7558 case RangeBefore:
7559 llvm_unreachable("Infeasible");
7560 case RangeAfter:
7561 break;
7562 case RangeOverlap:
7563 // For macro expansions, just note where the beginning of the macro
7564 // expansion occurs.
7565 if (cursor.kind == CXCursor_MacroExpansion) {
7566 if (TokLoc == cursorRange.getBegin())
7567 Cursors[I] = cursor;
7568 AdvanceToken();
7569 break;
7571 // We may have already annotated macro names inside macro definitions.
7572 if (Cursors[I].kind != CXCursor_MacroExpansion)
7573 Cursors[I] = cursor;
7574 AdvanceToken();
7575 continue;
7577 break;
7580 // Save the preprocessing token index; restore the non-preprocessing
7581 // token index.
7582 PreprocessingTokIdx = TokIdx;
7583 TokIdx = SavedTokIdx;
7584 return CXChildVisit_Recurse;
7587 if (cursorRange.isInvalid())
7588 return CXChildVisit_Continue;
7590 unsigned BeforeReachingCursorIdx = NextToken();
7591 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
7592 const enum CXCursorKind K = clang_getCursorKind(parent);
7593 const CXCursor updateC =
7594 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7595 // Attributes are annotated out-of-order, skip tokens until we reach it.
7596 clang_isAttribute(cursor.kind))
7597 ? clang_getNullCursor()
7598 : parent;
7600 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7602 // Avoid having the cursor of an expression "overwrite" the annotation of the
7603 // variable declaration that it belongs to.
7604 // This can happen for C++ constructor expressions whose range generally
7605 // include the variable declaration, e.g.:
7606 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
7607 if (clang_isExpression(cursorK) && MoreTokens()) {
7608 const Expr *E = getCursorExpr(cursor);
7609 if (const Decl *D = getCursorDecl(cursor)) {
7610 const unsigned I = NextToken();
7611 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7612 E->getBeginLoc() == D->getLocation() &&
7613 E->getBeginLoc() == GetTokenLoc(I)) {
7614 updateCursorAnnotation(Cursors[I], updateC);
7615 AdvanceToken();
7620 // Before recursing into the children keep some state that we are going
7621 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7622 // extra work after the child nodes are visited.
7623 // Note that we don't call VisitChildren here to avoid traversing statements
7624 // code-recursively which can blow the stack.
7626 PostChildrenInfo Info;
7627 Info.Cursor = cursor;
7628 Info.CursorRange = cursorRange;
7629 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
7630 Info.BeforeChildrenTokenIdx = NextToken();
7631 Info.ChildActions = DetermineChildActions(cursor);
7632 PostChildrenInfos.push_back(Info);
7634 return CXChildVisit_Recurse;
7637 bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7638 if (PostChildrenInfos.empty())
7639 return false;
7640 const PostChildrenInfo &Info = PostChildrenInfos.back();
7641 if (!clang_equalCursors(Info.Cursor, cursor))
7642 return false;
7644 HandlePostPonedChildCursors(Info);
7646 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7647 const unsigned AfterChildren = NextToken();
7648 SourceRange cursorRange = Info.CursorRange;
7650 // Scan the tokens that are at the end of the cursor, but are not captured
7651 // but the child cursors.
7652 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7654 // Scan the tokens that are at the beginning of the cursor, but are not
7655 // capture by the child cursors.
7656 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7657 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7658 break;
7660 Cursors[I] = cursor;
7663 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7664 // encountered the attribute cursor.
7665 if (clang_isAttribute(cursor.kind))
7666 TokIdx = Info.BeforeReachingCursorIdx;
7668 PostChildrenInfos.pop_back();
7669 return false;
7672 void AnnotateTokensWorker::HandlePostPonedChildCursors(
7673 const PostChildrenInfo &Info) {
7674 for (const auto &ChildAction : Info.ChildActions) {
7675 if (ChildAction.action == PostChildrenAction::Postpone) {
7676 HandlePostPonedChildCursor(ChildAction.cursor,
7677 Info.BeforeChildrenTokenIdx);
7682 void AnnotateTokensWorker::HandlePostPonedChildCursor(
7683 CXCursor Cursor, unsigned StartTokenIndex) {
7684 unsigned I = StartTokenIndex;
7686 // The bracket tokens of a Call or Subscript operator are mapped to
7687 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7688 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7689 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
7690 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7691 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
7692 if (clang_Range_isNull(CXRefNameRange))
7693 break; // All ranges handled.
7695 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7696 while (I < NumTokens) {
7697 const SourceLocation TokenLocation = GetTokenLoc(I);
7698 if (!TokenLocation.isValid())
7699 break;
7701 // Adapt the end range, because LocationCompare() reports
7702 // RangeOverlap even for the not-inclusive end location.
7703 const SourceLocation fixedEnd =
7704 RefNameRange.getEnd().getLocWithOffset(-1);
7705 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7707 const RangeComparisonResult ComparisonResult =
7708 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7710 if (ComparisonResult == RangeOverlap) {
7711 Cursors[I++] = Cursor;
7712 } else if (ComparisonResult == RangeBefore) {
7713 ++I; // Not relevant token, check next one.
7714 } else if (ComparisonResult == RangeAfter) {
7715 break; // All tokens updated for current range, check next.
7721 static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7722 CXCursor parent,
7723 CXClientData client_data) {
7724 return static_cast<AnnotateTokensWorker *>(client_data)
7725 ->Visit(cursor, parent);
7728 static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7729 CXClientData client_data) {
7730 return static_cast<AnnotateTokensWorker *>(client_data)
7731 ->postVisitChildren(cursor);
7734 namespace {
7736 /// Uses the macro expansions in the preprocessing record to find
7737 /// and mark tokens that are macro arguments. This info is used by the
7738 /// AnnotateTokensWorker.
7739 class MarkMacroArgTokensVisitor {
7740 SourceManager &SM;
7741 CXToken *Tokens;
7742 unsigned NumTokens;
7743 unsigned CurIdx;
7745 public:
7746 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7747 unsigned numTokens)
7748 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
7750 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7751 if (cursor.kind != CXCursor_MacroExpansion)
7752 return CXChildVisit_Continue;
7754 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
7755 if (macroRange.getBegin() == macroRange.getEnd())
7756 return CXChildVisit_Continue; // it's not a function macro.
7758 for (; CurIdx < NumTokens; ++CurIdx) {
7759 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7760 macroRange.getBegin()))
7761 break;
7764 if (CurIdx == NumTokens)
7765 return CXChildVisit_Break;
7767 for (; CurIdx < NumTokens; ++CurIdx) {
7768 SourceLocation tokLoc = getTokenLoc(CurIdx);
7769 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7770 break;
7772 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7775 if (CurIdx == NumTokens)
7776 return CXChildVisit_Break;
7778 return CXChildVisit_Continue;
7781 private:
7782 CXToken &getTok(unsigned Idx) {
7783 assert(Idx < NumTokens);
7784 return Tokens[Idx];
7786 const CXToken &getTok(unsigned Idx) const {
7787 assert(Idx < NumTokens);
7788 return Tokens[Idx];
7791 SourceLocation getTokenLoc(unsigned tokI) {
7792 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
7795 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7796 // The third field is reserved and currently not used. Use it here
7797 // to mark macro arg expanded tokens with their expanded locations.
7798 getTok(tokI).int_data[3] = loc.getRawEncoding();
7802 } // end anonymous namespace
7804 static CXChildVisitResult
7805 MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7806 CXClientData client_data) {
7807 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7808 ->visit(cursor, parent);
7811 /// Used by \c annotatePreprocessorTokens.
7812 /// \returns true if lexing was finished, false otherwise.
7813 static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7814 unsigned NumTokens) {
7815 if (NextIdx >= NumTokens)
7816 return true;
7818 ++NextIdx;
7819 Lex.LexFromRawLexer(Tok);
7820 return Tok.is(tok::eof);
7823 static void annotatePreprocessorTokens(CXTranslationUnit TU,
7824 SourceRange RegionOfInterest,
7825 CXCursor *Cursors, CXToken *Tokens,
7826 unsigned NumTokens) {
7827 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
7829 Preprocessor &PP = CXXUnit->getPreprocessor();
7830 SourceManager &SourceMgr = CXXUnit->getSourceManager();
7831 std::pair<FileID, unsigned> BeginLocInfo =
7832 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7833 std::pair<FileID, unsigned> EndLocInfo =
7834 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
7836 if (BeginLocInfo.first != EndLocInfo.first)
7837 return;
7839 StringRef Buffer;
7840 bool Invalid = false;
7841 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7842 if (Buffer.empty() || Invalid)
7843 return;
7845 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
7846 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7847 Buffer.data() + BeginLocInfo.second, Buffer.end());
7848 Lex.SetCommentRetentionState(true);
7850 unsigned NextIdx = 0;
7851 // Lex tokens in raw mode until we hit the end of the range, to avoid
7852 // entering #includes or expanding macros.
7853 while (true) {
7854 Token Tok;
7855 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7856 break;
7857 unsigned TokIdx = NextIdx - 1;
7858 assert(Tok.getLocation() ==
7859 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7861 reprocess:
7862 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
7863 // We have found a preprocessing directive. Annotate the tokens
7864 // appropriately.
7866 // FIXME: Some simple tests here could identify macro definitions and
7867 // #undefs, to provide specific cursor kinds for those.
7869 SourceLocation BeginLoc = Tok.getLocation();
7870 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7871 break;
7873 MacroInfo *MI = nullptr;
7874 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
7875 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7876 break;
7878 if (Tok.is(tok::raw_identifier)) {
7879 IdentifierInfo &II =
7880 PP.getIdentifierTable().get(Tok.getRawIdentifier());
7881 SourceLocation MappedTokLoc =
7882 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7883 MI = getMacroInfo(II, MappedTokLoc, TU);
7887 bool finished = false;
7888 do {
7889 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7890 finished = true;
7891 break;
7893 // If we are in a macro definition, check if the token was ever a
7894 // macro name and annotate it if that's the case.
7895 if (MI) {
7896 SourceLocation SaveLoc = Tok.getLocation();
7897 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
7898 MacroDefinitionRecord *MacroDef =
7899 checkForMacroInMacroDefinition(MI, Tok, TU);
7900 Tok.setLocation(SaveLoc);
7901 if (MacroDef)
7902 Cursors[NextIdx - 1] =
7903 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
7905 } while (!Tok.isAtStartOfLine());
7907 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
7908 assert(TokIdx <= LastIdx);
7909 SourceLocation EndLoc =
7910 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7911 CXCursor Cursor =
7912 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7914 for (; TokIdx <= LastIdx; ++TokIdx)
7915 updateCursorAnnotation(Cursors[TokIdx], Cursor);
7917 if (finished)
7918 break;
7919 goto reprocess;
7924 // This gets run a separate thread to avoid stack blowout.
7925 static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7926 CXToken *Tokens, unsigned NumTokens,
7927 CXCursor *Cursors) {
7928 CIndexer *CXXIdx = TU->CIdx;
7929 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7930 setThreadBackgroundPriority();
7932 // Determine the region of interest, which contains all of the tokens.
7933 SourceRange RegionOfInterest;
7934 RegionOfInterest.setBegin(
7935 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7936 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7937 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
7939 // Relex the tokens within the source range to look for preprocessing
7940 // directives.
7941 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
7943 // If begin location points inside a macro argument, set it to the expansion
7944 // location so we can have the full context when annotating semantically.
7946 SourceManager &SM = CXXUnit->getSourceManager();
7947 SourceLocation Loc =
7948 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7949 if (Loc.isMacroID())
7950 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7953 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7954 // Search and mark tokens that are macro argument expansions.
7955 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7956 NumTokens);
7957 CursorVisitor MacroArgMarker(
7958 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7959 /*VisitPreprocessorLast=*/true,
7960 /*VisitIncludedEntities=*/false, RegionOfInterest);
7961 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7964 // Annotate all of the source locations in the region of interest that map to
7965 // a specific cursor.
7966 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
7968 // FIXME: We use a ridiculous stack size here because the data-recursion
7969 // algorithm uses a large stack frame than the non-data recursive version,
7970 // and AnnotationTokensWorker currently transforms the data-recursion
7971 // algorithm back into a traditional recursion by explicitly calling
7972 // VisitChildren(). We will need to remove this explicit recursive call.
7973 W.AnnotateTokens();
7975 // If we ran into any entities that involve context-sensitive keywords,
7976 // take another pass through the tokens to mark them as such.
7977 if (W.hasContextSensitiveKeywords()) {
7978 for (unsigned I = 0; I != NumTokens; ++I) {
7979 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7980 continue;
7982 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7983 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7984 if (const ObjCPropertyDecl *Property =
7985 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
7986 if (Property->getPropertyAttributesAsWritten() != 0 &&
7987 llvm::StringSwitch<bool>(II->getName())
7988 .Case("readonly", true)
7989 .Case("assign", true)
7990 .Case("unsafe_unretained", true)
7991 .Case("readwrite", true)
7992 .Case("retain", true)
7993 .Case("copy", true)
7994 .Case("nonatomic", true)
7995 .Case("atomic", true)
7996 .Case("getter", true)
7997 .Case("setter", true)
7998 .Case("strong", true)
7999 .Case("weak", true)
8000 .Case("class", true)
8001 .Default(false))
8002 Tokens[I].int_data[0] = CXToken_Keyword;
8004 continue;
8007 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
8008 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
8009 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
8010 if (llvm::StringSwitch<bool>(II->getName())
8011 .Case("in", true)
8012 .Case("out", true)
8013 .Case("inout", true)
8014 .Case("oneway", true)
8015 .Case("bycopy", true)
8016 .Case("byref", true)
8017 .Default(false))
8018 Tokens[I].int_data[0] = CXToken_Keyword;
8019 continue;
8022 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
8023 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
8024 Tokens[I].int_data[0] = CXToken_Keyword;
8025 continue;
8031 void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
8032 unsigned NumTokens, CXCursor *Cursors) {
8033 if (isNotUsableTU(TU)) {
8034 LOG_BAD_TU(TU);
8035 return;
8037 if (NumTokens == 0 || !Tokens || !Cursors) {
8038 LOG_FUNC_SECTION { *Log << "<null input>"; }
8039 return;
8042 LOG_FUNC_SECTION {
8043 *Log << TU << ' ';
8044 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
8045 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
8046 *Log << clang_getRange(bloc, eloc);
8049 // Any token we don't specifically annotate will have a NULL cursor.
8050 CXCursor C = clang_getNullCursor();
8051 for (unsigned I = 0; I != NumTokens; ++I)
8052 Cursors[I] = C;
8054 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
8055 if (!CXXUnit)
8056 return;
8058 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
8060 auto AnnotateTokensImpl = [=]() {
8061 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
8063 llvm::CrashRecoveryContext CRC;
8064 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
8065 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
8069 //===----------------------------------------------------------------------===//
8070 // Operations for querying linkage of a cursor.
8071 //===----------------------------------------------------------------------===//
8073 CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
8074 if (!clang_isDeclaration(cursor.kind))
8075 return CXLinkage_Invalid;
8077 const Decl *D = cxcursor::getCursorDecl(cursor);
8078 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
8079 switch (ND->getLinkageInternal()) {
8080 case NoLinkage:
8081 case VisibleNoLinkage:
8082 return CXLinkage_NoLinkage;
8083 case ModuleInternalLinkage:
8084 case InternalLinkage:
8085 return CXLinkage_Internal;
8086 case UniqueExternalLinkage:
8087 return CXLinkage_UniqueExternal;
8088 case ModuleLinkage:
8089 case ExternalLinkage:
8090 return CXLinkage_External;
8093 return CXLinkage_Invalid;
8096 //===----------------------------------------------------------------------===//
8097 // Operations for querying visibility of a cursor.
8098 //===----------------------------------------------------------------------===//
8100 CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
8101 if (!clang_isDeclaration(cursor.kind))
8102 return CXVisibility_Invalid;
8104 const Decl *D = cxcursor::getCursorDecl(cursor);
8105 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
8106 switch (ND->getVisibility()) {
8107 case HiddenVisibility:
8108 return CXVisibility_Hidden;
8109 case ProtectedVisibility:
8110 return CXVisibility_Protected;
8111 case DefaultVisibility:
8112 return CXVisibility_Default;
8115 return CXVisibility_Invalid;
8118 //===----------------------------------------------------------------------===//
8119 // Operations for querying language of a cursor.
8120 //===----------------------------------------------------------------------===//
8122 static CXLanguageKind getDeclLanguage(const Decl *D) {
8123 if (!D)
8124 return CXLanguage_C;
8126 switch (D->getKind()) {
8127 default:
8128 break;
8129 case Decl::ImplicitParam:
8130 case Decl::ObjCAtDefsField:
8131 case Decl::ObjCCategory:
8132 case Decl::ObjCCategoryImpl:
8133 case Decl::ObjCCompatibleAlias:
8134 case Decl::ObjCImplementation:
8135 case Decl::ObjCInterface:
8136 case Decl::ObjCIvar:
8137 case Decl::ObjCMethod:
8138 case Decl::ObjCProperty:
8139 case Decl::ObjCPropertyImpl:
8140 case Decl::ObjCProtocol:
8141 case Decl::ObjCTypeParam:
8142 return CXLanguage_ObjC;
8143 case Decl::CXXConstructor:
8144 case Decl::CXXConversion:
8145 case Decl::CXXDestructor:
8146 case Decl::CXXMethod:
8147 case Decl::CXXRecord:
8148 case Decl::ClassTemplate:
8149 case Decl::ClassTemplatePartialSpecialization:
8150 case Decl::ClassTemplateSpecialization:
8151 case Decl::Friend:
8152 case Decl::FriendTemplate:
8153 case Decl::FunctionTemplate:
8154 case Decl::LinkageSpec:
8155 case Decl::Namespace:
8156 case Decl::NamespaceAlias:
8157 case Decl::NonTypeTemplateParm:
8158 case Decl::StaticAssert:
8159 case Decl::TemplateTemplateParm:
8160 case Decl::TemplateTypeParm:
8161 case Decl::UnresolvedUsingTypename:
8162 case Decl::UnresolvedUsingValue:
8163 case Decl::Using:
8164 case Decl::UsingDirective:
8165 case Decl::UsingShadow:
8166 return CXLanguage_CPlusPlus;
8169 return CXLanguage_C;
8172 static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
8173 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
8174 return CXAvailability_NotAvailable;
8176 switch (D->getAvailability()) {
8177 case AR_Available:
8178 case AR_NotYetIntroduced:
8179 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
8180 return getCursorAvailabilityForDecl(
8181 cast<Decl>(EnumConst->getDeclContext()));
8182 return CXAvailability_Available;
8184 case AR_Deprecated:
8185 return CXAvailability_Deprecated;
8187 case AR_Unavailable:
8188 return CXAvailability_NotAvailable;
8191 llvm_unreachable("Unknown availability kind!");
8194 enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
8195 if (clang_isDeclaration(cursor.kind))
8196 if (const Decl *D = cxcursor::getCursorDecl(cursor))
8197 return getCursorAvailabilityForDecl(D);
8199 return CXAvailability_Available;
8202 static CXVersion convertVersion(VersionTuple In) {
8203 CXVersion Out = {-1, -1, -1};
8204 if (In.empty())
8205 return Out;
8207 Out.Major = In.getMajor();
8209 Optional<unsigned> Minor = In.getMinor();
8210 if (Minor)
8211 Out.Minor = *Minor;
8212 else
8213 return Out;
8215 Optional<unsigned> Subminor = In.getSubminor();
8216 if (Subminor)
8217 Out.Subminor = *Subminor;
8219 return Out;
8222 static void getCursorPlatformAvailabilityForDecl(
8223 const Decl *D, int *always_deprecated, CXString *deprecated_message,
8224 int *always_unavailable, CXString *unavailable_message,
8225 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
8226 bool HadAvailAttr = false;
8227 for (auto A : D->attrs()) {
8228 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
8229 HadAvailAttr = true;
8230 if (always_deprecated)
8231 *always_deprecated = 1;
8232 if (deprecated_message) {
8233 clang_disposeString(*deprecated_message);
8234 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
8236 continue;
8239 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
8240 HadAvailAttr = true;
8241 if (always_unavailable)
8242 *always_unavailable = 1;
8243 if (unavailable_message) {
8244 clang_disposeString(*unavailable_message);
8245 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
8247 continue;
8250 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
8251 AvailabilityAttrs.push_back(Avail);
8252 HadAvailAttr = true;
8256 if (!HadAvailAttr)
8257 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
8258 return getCursorPlatformAvailabilityForDecl(
8259 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
8260 deprecated_message, always_unavailable, unavailable_message,
8261 AvailabilityAttrs);
8263 // If no availability attributes are found, inherit the attribute from the
8264 // containing decl or the class or category interface decl.
8265 if (AvailabilityAttrs.empty()) {
8266 const ObjCContainerDecl *CD = nullptr;
8267 const DeclContext *DC = D->getDeclContext();
8269 if (auto *IMD = dyn_cast<ObjCImplementationDecl>(D))
8270 CD = IMD->getClassInterface();
8271 else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D))
8272 CD = CatD->getClassInterface();
8273 else if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(D))
8274 CD = IMD->getCategoryDecl();
8275 else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(DC))
8276 CD = ID;
8277 else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(DC))
8278 CD = CatD;
8279 else if (auto *IMD = dyn_cast<ObjCImplementationDecl>(DC))
8280 CD = IMD->getClassInterface();
8281 else if (auto *IMD = dyn_cast<ObjCCategoryImplDecl>(DC))
8282 CD = IMD->getCategoryDecl();
8283 else if (auto *PD = dyn_cast<ObjCProtocolDecl>(DC))
8284 CD = PD;
8286 if (CD)
8287 getCursorPlatformAvailabilityForDecl(
8288 CD, always_deprecated, deprecated_message, always_unavailable,
8289 unavailable_message, AvailabilityAttrs);
8290 return;
8293 llvm::sort(
8294 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
8295 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
8297 ASTContext &Ctx = D->getASTContext();
8298 auto It = std::unique(
8299 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
8300 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
8301 if (LHS->getPlatform() != RHS->getPlatform())
8302 return false;
8304 if (LHS->getIntroduced() == RHS->getIntroduced() &&
8305 LHS->getDeprecated() == RHS->getDeprecated() &&
8306 LHS->getObsoleted() == RHS->getObsoleted() &&
8307 LHS->getMessage() == RHS->getMessage() &&
8308 LHS->getReplacement() == RHS->getReplacement())
8309 return true;
8311 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
8312 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
8313 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
8314 return false;
8316 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
8317 LHS->setIntroduced(Ctx, RHS->getIntroduced());
8319 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
8320 LHS->setDeprecated(Ctx, RHS->getDeprecated());
8321 if (LHS->getMessage().empty())
8322 LHS->setMessage(Ctx, RHS->getMessage());
8323 if (LHS->getReplacement().empty())
8324 LHS->setReplacement(Ctx, RHS->getReplacement());
8327 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
8328 LHS->setObsoleted(Ctx, RHS->getObsoleted());
8329 if (LHS->getMessage().empty())
8330 LHS->setMessage(Ctx, RHS->getMessage());
8331 if (LHS->getReplacement().empty())
8332 LHS->setReplacement(Ctx, RHS->getReplacement());
8335 return true;
8337 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
8340 int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
8341 CXString *deprecated_message,
8342 int *always_unavailable,
8343 CXString *unavailable_message,
8344 CXPlatformAvailability *availability,
8345 int availability_size) {
8346 if (always_deprecated)
8347 *always_deprecated = 0;
8348 if (deprecated_message)
8349 *deprecated_message = cxstring::createEmpty();
8350 if (always_unavailable)
8351 *always_unavailable = 0;
8352 if (unavailable_message)
8353 *unavailable_message = cxstring::createEmpty();
8355 if (!clang_isDeclaration(cursor.kind))
8356 return 0;
8358 const Decl *D = cxcursor::getCursorDecl(cursor);
8359 if (!D)
8360 return 0;
8362 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
8363 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8364 always_unavailable, unavailable_message,
8365 AvailabilityAttrs);
8366 for (const auto &Avail :
8367 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8368 .take_front(availability_size))) {
8369 availability[Avail.index()].Platform =
8370 cxstring::createDup(Avail.value()->getPlatform()->getName());
8371 availability[Avail.index()].Introduced =
8372 convertVersion(Avail.value()->getIntroduced());
8373 availability[Avail.index()].Deprecated =
8374 convertVersion(Avail.value()->getDeprecated());
8375 availability[Avail.index()].Obsoleted =
8376 convertVersion(Avail.value()->getObsoleted());
8377 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8378 availability[Avail.index()].Message =
8379 cxstring::createDup(Avail.value()->getMessage());
8382 return AvailabilityAttrs.size();
8385 void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8386 clang_disposeString(availability->Platform);
8387 clang_disposeString(availability->Message);
8390 CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8391 if (clang_isDeclaration(cursor.kind))
8392 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8394 return CXLanguage_Invalid;
8397 CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8398 const Decl *D = cxcursor::getCursorDecl(cursor);
8399 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8400 switch (VD->getTLSKind()) {
8401 case VarDecl::TLS_None:
8402 return CXTLS_None;
8403 case VarDecl::TLS_Dynamic:
8404 return CXTLS_Dynamic;
8405 case VarDecl::TLS_Static:
8406 return CXTLS_Static;
8410 return CXTLS_None;
8413 /// If the given cursor is the "templated" declaration
8414 /// describing a class or function template, return the class or
8415 /// function template.
8416 static const Decl *maybeGetTemplateCursor(const Decl *D) {
8417 if (!D)
8418 return nullptr;
8420 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8421 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8422 return FunTmpl;
8424 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
8425 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8426 return ClassTmpl;
8428 return D;
8431 enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8432 StorageClass sc = SC_None;
8433 const Decl *D = getCursorDecl(C);
8434 if (D) {
8435 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8436 sc = FD->getStorageClass();
8437 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8438 sc = VD->getStorageClass();
8439 } else {
8440 return CX_SC_Invalid;
8442 } else {
8443 return CX_SC_Invalid;
8445 switch (sc) {
8446 case SC_None:
8447 return CX_SC_None;
8448 case SC_Extern:
8449 return CX_SC_Extern;
8450 case SC_Static:
8451 return CX_SC_Static;
8452 case SC_PrivateExtern:
8453 return CX_SC_PrivateExtern;
8454 case SC_Auto:
8455 return CX_SC_Auto;
8456 case SC_Register:
8457 return CX_SC_Register;
8459 llvm_unreachable("Unhandled storage class!");
8462 CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8463 if (clang_isDeclaration(cursor.kind)) {
8464 if (const Decl *D = getCursorDecl(cursor)) {
8465 const DeclContext *DC = D->getDeclContext();
8466 if (!DC)
8467 return clang_getNullCursor();
8469 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
8470 getCursorTU(cursor));
8474 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
8475 if (const Decl *D = getCursorDecl(cursor))
8476 return MakeCXCursor(D, getCursorTU(cursor));
8479 return clang_getNullCursor();
8482 CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8483 if (clang_isDeclaration(cursor.kind)) {
8484 if (const Decl *D = getCursorDecl(cursor)) {
8485 const DeclContext *DC = D->getLexicalDeclContext();
8486 if (!DC)
8487 return clang_getNullCursor();
8489 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
8490 getCursorTU(cursor));
8494 // FIXME: Note that we can't easily compute the lexical context of a
8495 // statement or expression, so we return nothing.
8496 return clang_getNullCursor();
8499 CXFile clang_getIncludedFile(CXCursor cursor) {
8500 if (cursor.kind != CXCursor_InclusionDirective)
8501 return nullptr;
8503 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
8504 Optional<FileEntryRef> File = ID->getFile();
8505 return const_cast<FileEntry *>(File ? &File->getFileEntry() : nullptr);
8508 unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8509 if (C.kind != CXCursor_ObjCPropertyDecl)
8510 return CXObjCPropertyAttr_noattr;
8512 unsigned Result = CXObjCPropertyAttr_noattr;
8513 const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));
8514 ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
8516 #define SET_CXOBJCPROP_ATTR(A) \
8517 if (Attr & ObjCPropertyAttribute::kind_##A) \
8518 Result |= CXObjCPropertyAttr_##A
8519 SET_CXOBJCPROP_ATTR(readonly);
8520 SET_CXOBJCPROP_ATTR(getter);
8521 SET_CXOBJCPROP_ATTR(assign);
8522 SET_CXOBJCPROP_ATTR(readwrite);
8523 SET_CXOBJCPROP_ATTR(retain);
8524 SET_CXOBJCPROP_ATTR(copy);
8525 SET_CXOBJCPROP_ATTR(nonatomic);
8526 SET_CXOBJCPROP_ATTR(setter);
8527 SET_CXOBJCPROP_ATTR(atomic);
8528 SET_CXOBJCPROP_ATTR(weak);
8529 SET_CXOBJCPROP_ATTR(strong);
8530 SET_CXOBJCPROP_ATTR(unsafe_unretained);
8531 SET_CXOBJCPROP_ATTR(class);
8532 #undef SET_CXOBJCPROP_ATTR
8534 return Result;
8537 CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8538 if (C.kind != CXCursor_ObjCPropertyDecl)
8539 return cxstring::createNull();
8541 const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));
8542 Selector sel = PD->getGetterName();
8543 if (sel.isNull())
8544 return cxstring::createNull();
8546 return cxstring::createDup(sel.getAsString());
8549 CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8550 if (C.kind != CXCursor_ObjCPropertyDecl)
8551 return cxstring::createNull();
8553 const auto *PD = cast<ObjCPropertyDecl>(getCursorDecl(C));
8554 Selector sel = PD->getSetterName();
8555 if (sel.isNull())
8556 return cxstring::createNull();
8558 return cxstring::createDup(sel.getAsString());
8561 unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8562 if (!clang_isDeclaration(C.kind))
8563 return CXObjCDeclQualifier_None;
8565 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8566 const Decl *D = getCursorDecl(C);
8567 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8568 QT = MD->getObjCDeclQualifier();
8569 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8570 QT = PD->getObjCDeclQualifier();
8571 if (QT == Decl::OBJC_TQ_None)
8572 return CXObjCDeclQualifier_None;
8574 unsigned Result = CXObjCDeclQualifier_None;
8575 if (QT & Decl::OBJC_TQ_In)
8576 Result |= CXObjCDeclQualifier_In;
8577 if (QT & Decl::OBJC_TQ_Inout)
8578 Result |= CXObjCDeclQualifier_Inout;
8579 if (QT & Decl::OBJC_TQ_Out)
8580 Result |= CXObjCDeclQualifier_Out;
8581 if (QT & Decl::OBJC_TQ_Bycopy)
8582 Result |= CXObjCDeclQualifier_Bycopy;
8583 if (QT & Decl::OBJC_TQ_Byref)
8584 Result |= CXObjCDeclQualifier_Byref;
8585 if (QT & Decl::OBJC_TQ_Oneway)
8586 Result |= CXObjCDeclQualifier_Oneway;
8588 return Result;
8591 unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8592 if (!clang_isDeclaration(C.kind))
8593 return 0;
8595 const Decl *D = getCursorDecl(C);
8596 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8597 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8598 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8599 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8601 return 0;
8604 unsigned clang_Cursor_isVariadic(CXCursor C) {
8605 if (!clang_isDeclaration(C.kind))
8606 return 0;
8608 const Decl *D = getCursorDecl(C);
8609 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8610 return FD->isVariadic();
8611 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8612 return MD->isVariadic();
8614 return 0;
8617 unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8618 CXString *definedIn,
8619 unsigned *isGenerated) {
8620 if (!clang_isDeclaration(C.kind))
8621 return 0;
8623 const Decl *D = getCursorDecl(C);
8625 if (auto *attr = D->getExternalSourceSymbolAttr()) {
8626 if (language)
8627 *language = cxstring::createDup(attr->getLanguage());
8628 if (definedIn)
8629 *definedIn = cxstring::createDup(attr->getDefinedIn());
8630 if (isGenerated)
8631 *isGenerated = attr->getGeneratedDeclaration();
8632 return 1;
8634 return 0;
8637 CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8638 if (!clang_isDeclaration(C.kind))
8639 return clang_getNullRange();
8641 const Decl *D = getCursorDecl(C);
8642 ASTContext &Context = getCursorContext(C);
8643 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8644 if (!RC)
8645 return clang_getNullRange();
8647 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8650 CXString clang_Cursor_getRawCommentText(CXCursor C) {
8651 if (!clang_isDeclaration(C.kind))
8652 return cxstring::createNull();
8654 const Decl *D = getCursorDecl(C);
8655 ASTContext &Context = getCursorContext(C);
8656 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8657 StringRef RawText =
8658 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
8660 // Don't duplicate the string because RawText points directly into source
8661 // code.
8662 return cxstring::createRef(RawText);
8665 CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8666 if (!clang_isDeclaration(C.kind))
8667 return cxstring::createNull();
8669 const Decl *D = getCursorDecl(C);
8670 const ASTContext &Context = getCursorContext(C);
8671 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8673 if (RC) {
8674 StringRef BriefText = RC->getBriefText(Context);
8676 // Don't duplicate the string because RawComment ensures that this memory
8677 // will not go away.
8678 return cxstring::createRef(BriefText);
8681 return cxstring::createNull();
8684 CXModule clang_Cursor_getModule(CXCursor C) {
8685 if (C.kind == CXCursor_ModuleImportDecl) {
8686 if (const ImportDecl *ImportD =
8687 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
8688 return ImportD->getImportedModule();
8691 return nullptr;
8694 CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8695 if (isNotUsableTU(TU)) {
8696 LOG_BAD_TU(TU);
8697 return nullptr;
8699 if (!File)
8700 return nullptr;
8701 FileEntry *FE = static_cast<FileEntry *>(File);
8703 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8704 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8705 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
8707 return Header.getModule();
8710 CXFile clang_Module_getASTFile(CXModule CXMod) {
8711 if (!CXMod)
8712 return nullptr;
8713 Module *Mod = static_cast<Module *>(CXMod);
8714 if (auto File = Mod->getASTFile())
8715 return const_cast<FileEntry *>(&File->getFileEntry());
8716 return nullptr;
8719 CXModule clang_Module_getParent(CXModule CXMod) {
8720 if (!CXMod)
8721 return nullptr;
8722 Module *Mod = static_cast<Module *>(CXMod);
8723 return Mod->Parent;
8726 CXString clang_Module_getName(CXModule CXMod) {
8727 if (!CXMod)
8728 return cxstring::createEmpty();
8729 Module *Mod = static_cast<Module *>(CXMod);
8730 return cxstring::createDup(Mod->Name);
8733 CXString clang_Module_getFullName(CXModule CXMod) {
8734 if (!CXMod)
8735 return cxstring::createEmpty();
8736 Module *Mod = static_cast<Module *>(CXMod);
8737 return cxstring::createDup(Mod->getFullModuleName());
8740 int clang_Module_isSystem(CXModule CXMod) {
8741 if (!CXMod)
8742 return 0;
8743 Module *Mod = static_cast<Module *>(CXMod);
8744 return Mod->IsSystem;
8747 unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8748 CXModule CXMod) {
8749 if (isNotUsableTU(TU)) {
8750 LOG_BAD_TU(TU);
8751 return 0;
8753 if (!CXMod)
8754 return 0;
8755 Module *Mod = static_cast<Module *>(CXMod);
8756 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8757 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8758 return TopHeaders.size();
8761 CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8762 unsigned Index) {
8763 if (isNotUsableTU(TU)) {
8764 LOG_BAD_TU(TU);
8765 return nullptr;
8767 if (!CXMod)
8768 return nullptr;
8769 Module *Mod = static_cast<Module *>(CXMod);
8770 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8772 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8773 if (Index < TopHeaders.size())
8774 return const_cast<FileEntry *>(TopHeaders[Index]);
8776 return nullptr;
8779 //===----------------------------------------------------------------------===//
8780 // C++ AST instrospection.
8781 //===----------------------------------------------------------------------===//
8783 unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8784 if (!clang_isDeclaration(C.kind))
8785 return 0;
8787 const Decl *D = cxcursor::getCursorDecl(C);
8788 const CXXConstructorDecl *Constructor =
8789 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8790 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8793 unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8794 if (!clang_isDeclaration(C.kind))
8795 return 0;
8797 const Decl *D = cxcursor::getCursorDecl(C);
8798 const CXXConstructorDecl *Constructor =
8799 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8800 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8803 unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8804 if (!clang_isDeclaration(C.kind))
8805 return 0;
8807 const Decl *D = cxcursor::getCursorDecl(C);
8808 const CXXConstructorDecl *Constructor =
8809 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8810 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8813 unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8814 if (!clang_isDeclaration(C.kind))
8815 return 0;
8817 const Decl *D = cxcursor::getCursorDecl(C);
8818 const CXXConstructorDecl *Constructor =
8819 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8820 // Passing 'false' excludes constructors marked 'explicit'.
8821 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8824 unsigned clang_CXXField_isMutable(CXCursor C) {
8825 if (!clang_isDeclaration(C.kind))
8826 return 0;
8828 if (const auto D = cxcursor::getCursorDecl(C))
8829 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8830 return FD->isMutable() ? 1 : 0;
8831 return 0;
8834 unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8835 if (!clang_isDeclaration(C.kind))
8836 return 0;
8838 const Decl *D = cxcursor::getCursorDecl(C);
8839 const CXXMethodDecl *Method =
8840 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8841 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8844 unsigned clang_CXXMethod_isConst(CXCursor C) {
8845 if (!clang_isDeclaration(C.kind))
8846 return 0;
8848 const Decl *D = cxcursor::getCursorDecl(C);
8849 const CXXMethodDecl *Method =
8850 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8851 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
8854 unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8855 if (!clang_isDeclaration(C.kind))
8856 return 0;
8858 const Decl *D = cxcursor::getCursorDecl(C);
8859 const CXXMethodDecl *Method =
8860 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8861 return (Method && Method->isDefaulted()) ? 1 : 0;
8864 unsigned clang_CXXMethod_isStatic(CXCursor C) {
8865 if (!clang_isDeclaration(C.kind))
8866 return 0;
8868 const Decl *D = cxcursor::getCursorDecl(C);
8869 const CXXMethodDecl *Method =
8870 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8871 return (Method && Method->isStatic()) ? 1 : 0;
8874 unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8875 if (!clang_isDeclaration(C.kind))
8876 return 0;
8878 const Decl *D = cxcursor::getCursorDecl(C);
8879 const CXXMethodDecl *Method =
8880 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8881 return (Method && Method->isVirtual()) ? 1 : 0;
8884 unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8885 if (!clang_isDeclaration(C.kind))
8886 return 0;
8888 const auto *D = cxcursor::getCursorDecl(C);
8889 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8890 if (RD)
8891 RD = RD->getDefinition();
8892 return (RD && RD->isAbstract()) ? 1 : 0;
8895 unsigned clang_EnumDecl_isScoped(CXCursor C) {
8896 if (!clang_isDeclaration(C.kind))
8897 return 0;
8899 const Decl *D = cxcursor::getCursorDecl(C);
8900 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8901 return (Enum && Enum->isScoped()) ? 1 : 0;
8904 //===----------------------------------------------------------------------===//
8905 // Attribute introspection.
8906 //===----------------------------------------------------------------------===//
8908 CXType clang_getIBOutletCollectionType(CXCursor C) {
8909 if (C.kind != CXCursor_IBOutletCollectionAttr)
8910 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
8912 const IBOutletCollectionAttr *A =
8913 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8915 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
8918 //===----------------------------------------------------------------------===//
8919 // Inspecting memory usage.
8920 //===----------------------------------------------------------------------===//
8922 typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8924 static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
8925 enum CXTUResourceUsageKind k,
8926 unsigned long amount) {
8927 CXTUResourceUsageEntry entry = {k, amount};
8928 entries.push_back(entry);
8931 const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8932 const char *str = "";
8933 switch (kind) {
8934 case CXTUResourceUsage_AST:
8935 str = "ASTContext: expressions, declarations, and types";
8936 break;
8937 case CXTUResourceUsage_Identifiers:
8938 str = "ASTContext: identifiers";
8939 break;
8940 case CXTUResourceUsage_Selectors:
8941 str = "ASTContext: selectors";
8942 break;
8943 case CXTUResourceUsage_GlobalCompletionResults:
8944 str = "Code completion: cached global results";
8945 break;
8946 case CXTUResourceUsage_SourceManagerContentCache:
8947 str = "SourceManager: content cache allocator";
8948 break;
8949 case CXTUResourceUsage_AST_SideTables:
8950 str = "ASTContext: side tables";
8951 break;
8952 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8953 str = "SourceManager: malloc'ed memory buffers";
8954 break;
8955 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8956 str = "SourceManager: mmap'ed memory buffers";
8957 break;
8958 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8959 str = "ExternalASTSource: malloc'ed memory buffers";
8960 break;
8961 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8962 str = "ExternalASTSource: mmap'ed memory buffers";
8963 break;
8964 case CXTUResourceUsage_Preprocessor:
8965 str = "Preprocessor: malloc'ed memory";
8966 break;
8967 case CXTUResourceUsage_PreprocessingRecord:
8968 str = "Preprocessor: PreprocessingRecord";
8969 break;
8970 case CXTUResourceUsage_SourceManager_DataStructures:
8971 str = "SourceManager: data structures and tables";
8972 break;
8973 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8974 str = "Preprocessor: header search tables";
8975 break;
8977 return str;
8980 CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
8981 if (isNotUsableTU(TU)) {
8982 LOG_BAD_TU(TU);
8983 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
8984 return usage;
8987 ASTUnit *astUnit = cxtu::getASTUnit(TU);
8988 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
8989 ASTContext &astContext = astUnit->getASTContext();
8991 // How much memory is used by AST nodes and types?
8992 createCXTUResourceUsageEntry(
8993 *entries, CXTUResourceUsage_AST,
8994 (unsigned long)astContext.getASTAllocatedMemory());
8996 // How much memory is used by identifiers?
8997 createCXTUResourceUsageEntry(
8998 *entries, CXTUResourceUsage_Identifiers,
8999 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
9001 // How much memory is used for selectors?
9002 createCXTUResourceUsageEntry(
9003 *entries, CXTUResourceUsage_Selectors,
9004 (unsigned long)astContext.Selectors.getTotalMemory());
9006 // How much memory is used by ASTContext's side tables?
9007 createCXTUResourceUsageEntry(
9008 *entries, CXTUResourceUsage_AST_SideTables,
9009 (unsigned long)astContext.getSideTableAllocatedMemory());
9011 // How much memory is used for caching global code completion results?
9012 unsigned long completionBytes = 0;
9013 if (GlobalCodeCompletionAllocator *completionAllocator =
9014 astUnit->getCachedCompletionAllocator().get()) {
9015 completionBytes = completionAllocator->getTotalMemory();
9017 createCXTUResourceUsageEntry(
9018 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
9020 // How much memory is being used by SourceManager's content cache?
9021 createCXTUResourceUsageEntry(
9022 *entries, CXTUResourceUsage_SourceManagerContentCache,
9023 (unsigned long)astContext.getSourceManager().getContentCacheSize());
9025 // How much memory is being used by the MemoryBuffer's in SourceManager?
9026 const SourceManager::MemoryBufferSizes &srcBufs =
9027 astUnit->getSourceManager().getMemoryBufferSizes();
9029 createCXTUResourceUsageEntry(*entries,
9030 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
9031 (unsigned long)srcBufs.malloc_bytes);
9032 createCXTUResourceUsageEntry(*entries,
9033 CXTUResourceUsage_SourceManager_Membuffer_MMap,
9034 (unsigned long)srcBufs.mmap_bytes);
9035 createCXTUResourceUsageEntry(
9036 *entries, CXTUResourceUsage_SourceManager_DataStructures,
9037 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
9039 // How much memory is being used by the ExternalASTSource?
9040 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
9041 const ExternalASTSource::MemoryBufferSizes &sizes =
9042 esrc->getMemoryBufferSizes();
9044 createCXTUResourceUsageEntry(
9045 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
9046 (unsigned long)sizes.malloc_bytes);
9047 createCXTUResourceUsageEntry(
9048 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
9049 (unsigned long)sizes.mmap_bytes);
9052 // How much memory is being used by the Preprocessor?
9053 Preprocessor &pp = astUnit->getPreprocessor();
9054 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
9055 pp.getTotalMemory());
9057 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
9058 createCXTUResourceUsageEntry(*entries,
9059 CXTUResourceUsage_PreprocessingRecord,
9060 pRec->getTotalMemory());
9063 createCXTUResourceUsageEntry(*entries,
9064 CXTUResourceUsage_Preprocessor_HeaderSearch,
9065 pp.getHeaderSearchInfo().getTotalMemory());
9067 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
9068 !entries->empty() ? &(*entries)[0] : nullptr};
9069 (void)entries.release();
9070 return usage;
9073 void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
9074 if (usage.data)
9075 delete (MemUsageEntries *)usage.data;
9078 CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
9079 CXSourceRangeList *skipped = new CXSourceRangeList;
9080 skipped->count = 0;
9081 skipped->ranges = nullptr;
9083 if (isNotUsableTU(TU)) {
9084 LOG_BAD_TU(TU);
9085 return skipped;
9088 if (!file)
9089 return skipped;
9091 ASTUnit *astUnit = cxtu::getASTUnit(TU);
9092 PreprocessingRecord *ppRec =
9093 astUnit->getPreprocessor().getPreprocessingRecord();
9094 if (!ppRec)
9095 return skipped;
9097 ASTContext &Ctx = astUnit->getASTContext();
9098 SourceManager &sm = Ctx.getSourceManager();
9099 FileEntry *fileEntry = static_cast<FileEntry *>(file);
9100 FileID wantedFileID = sm.translateFile(fileEntry);
9101 bool isMainFile = wantedFileID == sm.getMainFileID();
9103 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
9104 std::vector<SourceRange> wantedRanges;
9105 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
9106 ei = SkippedRanges.end();
9107 i != ei; ++i) {
9108 if (sm.getFileID(i->getBegin()) == wantedFileID ||
9109 sm.getFileID(i->getEnd()) == wantedFileID)
9110 wantedRanges.push_back(*i);
9111 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
9112 astUnit->isInPreambleFileID(i->getEnd())))
9113 wantedRanges.push_back(*i);
9116 skipped->count = wantedRanges.size();
9117 skipped->ranges = new CXSourceRange[skipped->count];
9118 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
9119 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
9121 return skipped;
9124 CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
9125 CXSourceRangeList *skipped = new CXSourceRangeList;
9126 skipped->count = 0;
9127 skipped->ranges = nullptr;
9129 if (isNotUsableTU(TU)) {
9130 LOG_BAD_TU(TU);
9131 return skipped;
9134 ASTUnit *astUnit = cxtu::getASTUnit(TU);
9135 PreprocessingRecord *ppRec =
9136 astUnit->getPreprocessor().getPreprocessingRecord();
9137 if (!ppRec)
9138 return skipped;
9140 ASTContext &Ctx = astUnit->getASTContext();
9142 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
9144 skipped->count = SkippedRanges.size();
9145 skipped->ranges = new CXSourceRange[skipped->count];
9146 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
9147 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
9149 return skipped;
9152 void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
9153 if (ranges) {
9154 delete[] ranges->ranges;
9155 delete ranges;
9159 void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
9160 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
9161 for (unsigned I = 0; I != Usage.numEntries; ++I)
9162 fprintf(stderr, " %s: %lu\n",
9163 clang_getTUResourceUsageName(Usage.entries[I].kind),
9164 Usage.entries[I].amount);
9166 clang_disposeCXTUResourceUsage(Usage);
9169 CXCursor clang_Cursor_getVarDeclInitializer(CXCursor cursor) {
9170 const Decl *const D = getCursorDecl(cursor);
9171 if (!D)
9172 return clang_getNullCursor();
9173 const auto *const VD = dyn_cast<VarDecl>(D);
9174 if (!VD)
9175 return clang_getNullCursor();
9176 const Expr *const Init = VD->getInit();
9177 if (!Init)
9178 return clang_getNullCursor();
9180 return cxcursor::MakeCXCursor(Init, VD, cxcursor::getCursorTU(cursor));
9183 int clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor) {
9184 const Decl *const D = getCursorDecl(cursor);
9185 if (!D)
9186 return -1;
9187 const auto *const VD = dyn_cast<VarDecl>(D);
9188 if (!VD)
9189 return -1;
9191 return VD->hasGlobalStorage();
9194 int clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor) {
9195 const Decl *const D = getCursorDecl(cursor);
9196 if (!D)
9197 return -1;
9198 const auto *const VD = dyn_cast<VarDecl>(D);
9199 if (!VD)
9200 return -1;
9202 return VD->hasExternalStorage();
9205 //===----------------------------------------------------------------------===//
9206 // Misc. utility functions.
9207 //===----------------------------------------------------------------------===//
9209 /// Default to using our desired 8 MB stack size on "safety" threads.
9210 static unsigned SafetyStackThreadSize = DesiredStackSize;
9212 namespace clang {
9214 bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
9215 unsigned Size) {
9216 if (!Size)
9217 Size = GetSafetyThreadStackSize();
9218 if (Size && !getenv("LIBCLANG_NOTHREADS"))
9219 return CRC.RunSafelyOnThread(Fn, Size);
9220 return CRC.RunSafely(Fn);
9223 unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
9225 void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
9227 } // namespace clang
9229 void clang::setThreadBackgroundPriority() {
9230 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
9231 return;
9233 #if LLVM_ENABLE_THREADS
9234 // The function name setThreadBackgroundPriority is for historical reasons;
9235 // Low is more appropriate.
9236 llvm::set_thread_priority(llvm::ThreadPriority::Low);
9237 #endif
9240 void cxindex::printDiagsToStderr(ASTUnit *Unit) {
9241 if (!Unit)
9242 return;
9244 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
9245 DEnd = Unit->stored_diag_end();
9246 D != DEnd; ++D) {
9247 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
9248 CXString Msg =
9249 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
9250 fprintf(stderr, "%s\n", clang_getCString(Msg));
9251 clang_disposeString(Msg);
9253 #ifdef _WIN32
9254 // On Windows, force a flush, since there may be multiple copies of
9255 // stderr and stdout in the file system, all with different buffers
9256 // but writing to the same device.
9257 fflush(stderr);
9258 #endif
9261 MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
9262 SourceLocation MacroDefLoc,
9263 CXTranslationUnit TU) {
9264 if (MacroDefLoc.isInvalid() || !TU)
9265 return nullptr;
9266 if (!II.hadMacroDefinition())
9267 return nullptr;
9269 ASTUnit *Unit = cxtu::getASTUnit(TU);
9270 Preprocessor &PP = Unit->getPreprocessor();
9271 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
9272 if (MD) {
9273 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
9274 Def = Def.getPreviousDefinition()) {
9275 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
9276 return Def.getMacroInfo();
9280 return nullptr;
9283 const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
9284 CXTranslationUnit TU) {
9285 if (!MacroDef || !TU)
9286 return nullptr;
9287 const IdentifierInfo *II = MacroDef->getName();
9288 if (!II)
9289 return nullptr;
9291 return getMacroInfo(*II, MacroDef->getLocation(), TU);
9294 MacroDefinitionRecord *
9295 cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
9296 CXTranslationUnit TU) {
9297 if (!MI || !TU)
9298 return nullptr;
9299 if (Tok.isNot(tok::raw_identifier))
9300 return nullptr;
9302 if (MI->getNumTokens() == 0)
9303 return nullptr;
9304 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
9305 MI->getDefinitionEndLoc());
9306 ASTUnit *Unit = cxtu::getASTUnit(TU);
9308 // Check that the token is inside the definition and not its argument list.
9309 SourceManager &SM = Unit->getSourceManager();
9310 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
9311 return nullptr;
9312 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
9313 return nullptr;
9315 Preprocessor &PP = Unit->getPreprocessor();
9316 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
9317 if (!PPRec)
9318 return nullptr;
9320 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
9321 if (!II.hadMacroDefinition())
9322 return nullptr;
9324 // Check that the identifier is not one of the macro arguments.
9325 if (llvm::is_contained(MI->params(), &II))
9326 return nullptr;
9328 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
9329 if (!InnerMD)
9330 return nullptr;
9332 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
9335 MacroDefinitionRecord *
9336 cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
9337 CXTranslationUnit TU) {
9338 if (Loc.isInvalid() || !MI || !TU)
9339 return nullptr;
9341 if (MI->getNumTokens() == 0)
9342 return nullptr;
9343 ASTUnit *Unit = cxtu::getASTUnit(TU);
9344 Preprocessor &PP = Unit->getPreprocessor();
9345 if (!PP.getPreprocessingRecord())
9346 return nullptr;
9347 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
9348 Token Tok;
9349 if (PP.getRawToken(Loc, Tok))
9350 return nullptr;
9352 return checkForMacroInMacroDefinition(MI, Tok, TU);
9355 CXString clang_getClangVersion() {
9356 return cxstring::createDup(getClangFullVersion());
9359 Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
9360 if (TU) {
9361 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
9362 LogOS << '<' << Unit->getMainFileName() << '>';
9363 if (Unit->isMainFileAST())
9364 LogOS << " (" << Unit->getASTFileName() << ')';
9365 return *this;
9367 } else {
9368 LogOS << "<NULL TU>";
9370 return *this;
9373 Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
9374 *this << FE->getName();
9375 return *this;
9378 Logger &cxindex::Logger::operator<<(CXCursor cursor) {
9379 CXString cursorName = clang_getCursorDisplayName(cursor);
9380 *this << cursorName << "@" << clang_getCursorLocation(cursor);
9381 clang_disposeString(cursorName);
9382 return *this;
9385 Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
9386 CXFile File;
9387 unsigned Line, Column;
9388 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
9389 CXString FileName = clang_getFileName(File);
9390 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
9391 clang_disposeString(FileName);
9392 return *this;
9395 Logger &cxindex::Logger::operator<<(CXSourceRange range) {
9396 CXSourceLocation BLoc = clang_getRangeStart(range);
9397 CXSourceLocation ELoc = clang_getRangeEnd(range);
9399 CXFile BFile;
9400 unsigned BLine, BColumn;
9401 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
9403 CXFile EFile;
9404 unsigned ELine, EColumn;
9405 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
9407 CXString BFileName = clang_getFileName(BFile);
9408 if (BFile == EFile) {
9409 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
9410 BLine, BColumn, ELine, EColumn);
9411 } else {
9412 CXString EFileName = clang_getFileName(EFile);
9413 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9414 BColumn)
9415 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9416 EColumn);
9417 clang_disposeString(EFileName);
9419 clang_disposeString(BFileName);
9420 return *this;
9423 Logger &cxindex::Logger::operator<<(CXString Str) {
9424 *this << clang_getCString(Str);
9425 return *this;
9428 Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9429 LogOS << Fmt;
9430 return *this;
9433 static llvm::ManagedStatic<std::mutex> LoggingMutex;
9435 cxindex::Logger::~Logger() {
9436 std::lock_guard<std::mutex> L(*LoggingMutex);
9438 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9440 raw_ostream &OS = llvm::errs();
9441 OS << "[libclang:" << Name << ':';
9443 #ifdef USE_DARWIN_THREADS
9444 // TODO: Portability.
9445 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9446 OS << tid << ':';
9447 #endif
9449 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9450 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
9451 OS << Msg << '\n';
9453 if (Trace) {
9454 llvm::sys::PrintStackTrace(OS);
9455 OS << "--------------------------------------------------\n";