1 //===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the main API hooks in the Clang-C Source Indexing
12 //===----------------------------------------------------------------------===//
14 #include "CIndexDiagnostic.h"
19 #include "CXSourceLocation.h"
21 #include "CXTranslationUnit.h"
23 #include "CursorVisitor.h"
24 #include "clang-c/FatalErrorHandler.h"
25 #include "clang/AST/Attr.h"
26 #include "clang/AST/AttrVisitor.h"
27 #include "clang/AST/DeclObjCCommon.h"
28 #include "clang/AST/Expr.h"
29 #include "clang/AST/ExprCXX.h"
30 #include "clang/AST/Mangle.h"
31 #include "clang/AST/OpenACCClause.h"
32 #include "clang/AST/OpenMPClause.h"
33 #include "clang/AST/OperationKinds.h"
34 #include "clang/AST/StmtVisitor.h"
35 #include "clang/Basic/Diagnostic.h"
36 #include "clang/Basic/DiagnosticCategories.h"
37 #include "clang/Basic/DiagnosticIDs.h"
38 #include "clang/Basic/Stack.h"
39 #include "clang/Basic/TargetInfo.h"
40 #include "clang/Basic/Version.h"
41 #include "clang/Frontend/ASTUnit.h"
42 #include "clang/Frontend/CompilerInstance.h"
43 #include "clang/Index/CommentToXML.h"
44 #include "clang/Lex/HeaderSearch.h"
45 #include "clang/Lex/Lexer.h"
46 #include "clang/Lex/PreprocessingRecord.h"
47 #include "clang/Lex/Preprocessor.h"
48 #include "llvm/ADT/STLExtras.h"
49 #include "llvm/ADT/StringSwitch.h"
50 #include "llvm/Config/llvm-config.h"
51 #include "llvm/Support/Compiler.h"
52 #include "llvm/Support/CrashRecoveryContext.h"
53 #include "llvm/Support/Format.h"
54 #include "llvm/Support/ManagedStatic.h"
55 #include "llvm/Support/MemoryBuffer.h"
56 #include "llvm/Support/Program.h"
57 #include "llvm/Support/SaveAndRestore.h"
58 #include "llvm/Support/Signals.h"
59 #include "llvm/Support/TargetSelect.h"
60 #include "llvm/Support/Threading.h"
61 #include "llvm/Support/Timer.h"
62 #include "llvm/Support/raw_ostream.h"
63 #include "llvm/Support/thread.h"
67 #if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
68 #define USE_DARWIN_THREADS
71 #ifdef USE_DARWIN_THREADS
75 using namespace clang
;
76 using namespace clang::cxcursor
;
77 using namespace clang::cxtu
;
78 using namespace clang::cxindex
;
80 CXTranslationUnit
cxtu::MakeCXTranslationUnit(CIndexer
*CIdx
,
81 std::unique_ptr
<ASTUnit
> AU
) {
85 CXTranslationUnit D
= new CXTranslationUnitImpl();
87 D
->TheASTUnit
= AU
.release();
88 D
->StringPool
= new cxstring::CXStringPool();
89 D
->Diagnostics
= nullptr;
90 D
->OverridenCursorsPool
= createOverridenCXCursorsPool();
91 D
->CommentToXML
= nullptr;
92 D
->ParsingOptions
= 0;
97 bool cxtu::isASTReadError(ASTUnit
*AU
) {
98 for (ASTUnit::stored_diag_iterator D
= AU
->stored_diag_begin(),
99 DEnd
= AU
->stored_diag_end();
101 if (D
->getLevel() >= DiagnosticsEngine::Error
&&
102 DiagnosticIDs::getCategoryNumberForDiag(D
->getID()) ==
103 diag::DiagCat_AST_Deserialization_Issue
)
109 cxtu::CXTUOwner::~CXTUOwner() {
111 clang_disposeTranslationUnit(TU
);
114 /// Compare two source ranges to determine their relative position in
115 /// the translation unit.
116 static RangeComparisonResult
RangeCompare(SourceManager
&SM
, SourceRange R1
,
118 assert(R1
.isValid() && "First range is invalid?");
119 assert(R2
.isValid() && "Second range is invalid?");
120 if (R1
.getEnd() != R2
.getBegin() &&
121 SM
.isBeforeInTranslationUnit(R1
.getEnd(), R2
.getBegin()))
123 if (R2
.getEnd() != R1
.getBegin() &&
124 SM
.isBeforeInTranslationUnit(R2
.getEnd(), R1
.getBegin()))
129 /// Determine if a source location falls within, before, or after a
130 /// a given source range.
131 static RangeComparisonResult
LocationCompare(SourceManager
&SM
,
132 SourceLocation L
, SourceRange R
) {
133 assert(R
.isValid() && "First range is invalid?");
134 assert(L
.isValid() && "Second range is invalid?");
135 if (L
== R
.getBegin() || L
== R
.getEnd())
137 if (SM
.isBeforeInTranslationUnit(L
, R
.getBegin()))
139 if (SM
.isBeforeInTranslationUnit(R
.getEnd(), L
))
144 /// Translate a Clang source range into a CIndex source range.
146 /// Clang internally represents ranges where the end location points to the
147 /// start of the token at the end. However, for external clients it is more
148 /// useful to have a CXSourceRange be a proper half-open interval. This routine
149 /// does the appropriate translation.
150 CXSourceRange
cxloc::translateSourceRange(const SourceManager
&SM
,
151 const LangOptions
&LangOpts
,
152 const CharSourceRange
&R
) {
153 // We want the last character in this location, so we will adjust the
154 // location accordingly.
155 SourceLocation EndLoc
= R
.getEnd();
156 bool IsTokenRange
= R
.isTokenRange();
157 if (EndLoc
.isValid() && EndLoc
.isMacroID() &&
158 !SM
.isMacroArgExpansion(EndLoc
)) {
159 CharSourceRange Expansion
= SM
.getExpansionRange(EndLoc
);
160 EndLoc
= Expansion
.getEnd();
161 IsTokenRange
= Expansion
.isTokenRange();
163 if (IsTokenRange
&& EndLoc
.isValid()) {
165 Lexer::MeasureTokenLength(SM
.getSpellingLoc(EndLoc
), SM
, LangOpts
);
166 EndLoc
= EndLoc
.getLocWithOffset(Length
);
169 CXSourceRange Result
= {
170 {&SM
, &LangOpts
}, R
.getBegin().getRawEncoding(), EndLoc
.getRawEncoding()};
174 CharSourceRange
cxloc::translateCXRangeToCharRange(CXSourceRange R
) {
175 return CharSourceRange::getCharRange(
176 SourceLocation::getFromRawEncoding(R
.begin_int_data
),
177 SourceLocation::getFromRawEncoding(R
.end_int_data
));
180 //===----------------------------------------------------------------------===//
182 //===----------------------------------------------------------------------===//
184 static SourceRange
getRawCursorExtent(CXCursor C
);
185 static SourceRange
getFullCursorExtent(CXCursor C
, SourceManager
&SrcMgr
);
187 RangeComparisonResult
CursorVisitor::CompareRegionOfInterest(SourceRange R
) {
188 return RangeCompare(AU
->getSourceManager(), R
, RegionOfInterest
);
191 /// Visit the given cursor and, if requested by the visitor,
194 /// \param Cursor the cursor to visit.
196 /// \param CheckedRegionOfInterest if true, then the caller already checked
197 /// that this cursor is within the region of interest.
199 /// \returns true if the visitation should be aborted, false if it
201 bool CursorVisitor::Visit(CXCursor Cursor
, bool CheckedRegionOfInterest
) {
202 if (clang_isInvalid(Cursor
.kind
))
205 if (clang_isDeclaration(Cursor
.kind
)) {
206 const Decl
*D
= getCursorDecl(Cursor
);
208 assert(0 && "Invalid declaration cursor");
209 return true; // abort.
212 // Ignore implicit declarations, unless it's an objc method because
213 // currently we should report implicit methods for properties when indexing.
214 if (D
->isImplicit() && !isa
<ObjCMethodDecl
>(D
))
218 // If we have a range of interest, and this cursor doesn't intersect with it,
220 if (RegionOfInterest
.isValid() && !CheckedRegionOfInterest
) {
221 SourceRange Range
= getRawCursorExtent(Cursor
);
222 if (Range
.isInvalid() || CompareRegionOfInterest(Range
))
226 switch (Visitor(Cursor
, Parent
, ClientData
)) {
227 case CXChildVisit_Break
:
230 case CXChildVisit_Continue
:
233 case CXChildVisit_Recurse
: {
234 bool ret
= VisitChildren(Cursor
);
235 if (PostChildrenVisitor
)
236 if (PostChildrenVisitor(Cursor
, ClientData
))
242 llvm_unreachable("Invalid CXChildVisitResult!");
245 static bool visitPreprocessedEntitiesInRange(SourceRange R
,
246 PreprocessingRecord
&PPRec
,
247 CursorVisitor
&Visitor
) {
248 SourceManager
&SM
= Visitor
.getASTUnit()->getSourceManager();
251 if (!Visitor
.shouldVisitIncludedEntities()) {
252 // If the begin/end of the range lie in the same FileID, do the optimization
253 // where we skip preprocessed entities that do not come from the same
255 FID
= SM
.getFileID(SM
.getFileLoc(R
.getBegin()));
256 if (FID
!= SM
.getFileID(SM
.getFileLoc(R
.getEnd())))
260 const auto &Entities
= PPRec
.getPreprocessedEntitiesInRange(R
);
261 return Visitor
.visitPreprocessedEntities(Entities
.begin(), Entities
.end(),
265 bool CursorVisitor::visitFileRegion() {
266 if (RegionOfInterest
.isInvalid())
269 ASTUnit
*Unit
= cxtu::getASTUnit(TU
);
270 SourceManager
&SM
= Unit
->getSourceManager();
272 std::pair
<FileID
, unsigned> Begin
= SM
.getDecomposedLoc(
273 SM
.getFileLoc(RegionOfInterest
.getBegin())),
274 End
= SM
.getDecomposedLoc(
275 SM
.getFileLoc(RegionOfInterest
.getEnd()));
277 if (End
.first
!= Begin
.first
) {
278 // If the end does not reside in the same file, try to recover by
279 // picking the end of the file of begin location.
280 End
.first
= Begin
.first
;
281 End
.second
= SM
.getFileIDSize(Begin
.first
);
284 assert(Begin
.first
== End
.first
);
285 if (Begin
.second
> End
.second
)
288 FileID File
= Begin
.first
;
289 unsigned Offset
= Begin
.second
;
290 unsigned Length
= End
.second
- Begin
.second
;
292 if (!VisitDeclsOnly
&& !VisitPreprocessorLast
)
293 if (visitPreprocessedEntitiesInRegion())
294 return true; // visitation break.
296 if (visitDeclsFromFileRegion(File
, Offset
, Length
))
297 return true; // visitation break.
299 if (!VisitDeclsOnly
&& VisitPreprocessorLast
)
300 return visitPreprocessedEntitiesInRegion();
305 static bool isInLexicalContext(Decl
*D
, DeclContext
*DC
) {
309 for (DeclContext
*DeclDC
= D
->getLexicalDeclContext(); DeclDC
;
310 DeclDC
= DeclDC
->getLexicalParent()) {
317 bool CursorVisitor::visitDeclsFromFileRegion(FileID File
, unsigned Offset
,
319 ASTUnit
*Unit
= cxtu::getASTUnit(TU
);
320 SourceManager
&SM
= Unit
->getSourceManager();
321 SourceRange Range
= RegionOfInterest
;
323 SmallVector
<Decl
*, 16> Decls
;
324 Unit
->findFileRegionDecls(File
, Offset
, Length
, Decls
);
326 // If we didn't find any file level decls for the file, try looking at the
327 // file that it was included from.
328 while (Decls
.empty() || Decls
.front()->isTopLevelDeclInObjCContainer()) {
329 bool Invalid
= false;
330 const SrcMgr::SLocEntry
&SLEntry
= SM
.getSLocEntry(File
, &Invalid
);
334 SourceLocation Outer
;
335 if (SLEntry
.isFile())
336 Outer
= SLEntry
.getFile().getIncludeLoc();
338 Outer
= SLEntry
.getExpansion().getExpansionLocStart();
339 if (Outer
.isInvalid())
342 std::tie(File
, Offset
) = SM
.getDecomposedExpansionLoc(Outer
);
344 Unit
->findFileRegionDecls(File
, Offset
, Length
, Decls
);
347 assert(!Decls
.empty());
349 bool VisitedAtLeastOnce
= false;
350 DeclContext
*CurDC
= nullptr;
351 SmallVectorImpl
<Decl
*>::iterator DIt
= Decls
.begin();
352 for (SmallVectorImpl
<Decl
*>::iterator DE
= Decls
.end(); DIt
!= DE
; ++DIt
) {
354 if (D
->getSourceRange().isInvalid())
357 if (isInLexicalContext(D
, CurDC
))
360 CurDC
= dyn_cast
<DeclContext
>(D
);
362 if (TagDecl
*TD
= dyn_cast
<TagDecl
>(D
))
363 if (!TD
->isFreeStanding())
366 RangeComparisonResult CompRes
=
367 RangeCompare(SM
, D
->getSourceRange(), Range
);
368 if (CompRes
== RangeBefore
)
370 if (CompRes
== RangeAfter
)
373 assert(CompRes
== RangeOverlap
);
374 VisitedAtLeastOnce
= true;
376 if (isa
<ObjCContainerDecl
>(D
)) {
377 FileDI_current
= &DIt
;
380 FileDI_current
= nullptr;
383 if (Visit(MakeCXCursor(D
, TU
, Range
), /*CheckedRegionOfInterest=*/true))
384 return true; // visitation break.
387 if (VisitedAtLeastOnce
)
390 // No Decls overlapped with the range. Move up the lexical context until there
391 // is a context that contains the range or we reach the translation unit
393 DeclContext
*DC
= DIt
== Decls
.begin()
394 ? (*DIt
)->getLexicalDeclContext()
395 : (*(DIt
- 1))->getLexicalDeclContext();
397 while (DC
&& !DC
->isTranslationUnit()) {
398 Decl
*D
= cast
<Decl
>(DC
);
399 SourceRange CurDeclRange
= D
->getSourceRange();
400 if (CurDeclRange
.isInvalid())
403 if (RangeCompare(SM
, CurDeclRange
, Range
) == RangeOverlap
) {
404 if (Visit(MakeCXCursor(D
, TU
, Range
), /*CheckedRegionOfInterest=*/true))
405 return true; // visitation break.
408 DC
= D
->getLexicalDeclContext();
414 bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
415 if (!AU
->getPreprocessor().getPreprocessingRecord())
418 PreprocessingRecord
&PPRec
= *AU
->getPreprocessor().getPreprocessingRecord();
419 SourceManager
&SM
= AU
->getSourceManager();
421 if (RegionOfInterest
.isValid()) {
422 SourceRange MappedRange
= AU
->mapRangeToPreamble(RegionOfInterest
);
423 SourceLocation B
= MappedRange
.getBegin();
424 SourceLocation E
= MappedRange
.getEnd();
426 if (AU
->isInPreambleFileID(B
)) {
427 if (SM
.isLoadedSourceLocation(E
))
428 return visitPreprocessedEntitiesInRange(SourceRange(B
, E
), PPRec
,
431 // Beginning of range lies in the preamble but it also extends beyond
432 // it into the main file. Split the range into 2 parts, one covering
433 // the preamble and another covering the main file. This allows subsequent
434 // calls to visitPreprocessedEntitiesInRange to accept a source range that
435 // lies in the same FileID, allowing it to skip preprocessed entities that
436 // do not come from the same FileID.
437 bool breaked
= visitPreprocessedEntitiesInRange(
438 SourceRange(B
, AU
->getEndOfPreambleFileID()), PPRec
, *this);
441 return visitPreprocessedEntitiesInRange(
442 SourceRange(AU
->getStartOfMainFileID(), E
), PPRec
, *this);
445 return visitPreprocessedEntitiesInRange(SourceRange(B
, E
), PPRec
, *this);
448 bool OnlyLocalDecls
= !AU
->isMainFileAST() && AU
->getOnlyLocalDecls();
451 return visitPreprocessedEntities(PPRec
.local_begin(), PPRec
.local_end(),
454 return visitPreprocessedEntities(PPRec
.begin(), PPRec
.end(), PPRec
);
457 template <typename InputIterator
>
458 bool CursorVisitor::visitPreprocessedEntities(InputIterator First
,
460 PreprocessingRecord
&PPRec
,
462 for (; First
!= Last
; ++First
) {
463 if (!FID
.isInvalid() && !PPRec
.isEntityInFileID(First
, FID
))
466 PreprocessedEntity
*PPE
= *First
;
470 if (MacroExpansion
*ME
= dyn_cast
<MacroExpansion
>(PPE
)) {
471 if (Visit(MakeMacroExpansionCursor(ME
, TU
)))
477 if (MacroDefinitionRecord
*MD
= dyn_cast
<MacroDefinitionRecord
>(PPE
)) {
478 if (Visit(MakeMacroDefinitionCursor(MD
, TU
)))
484 if (InclusionDirective
*ID
= dyn_cast
<InclusionDirective
>(PPE
)) {
485 if (Visit(MakeInclusionDirectiveCursor(ID
, TU
)))
495 /// Visit the children of the given cursor.
497 /// \returns true if the visitation should be aborted, false if it
499 bool CursorVisitor::VisitChildren(CXCursor Cursor
) {
500 if (clang_isReference(Cursor
.kind
) &&
501 Cursor
.kind
!= CXCursor_CXXBaseSpecifier
) {
502 // By definition, references have no children.
506 // Set the Parent field to Cursor, then back to its old value once we're
508 SetParentRAII
SetParent(Parent
, StmtParent
, Cursor
);
510 if (clang_isDeclaration(Cursor
.kind
)) {
511 Decl
*D
= const_cast<Decl
*>(getCursorDecl(Cursor
));
515 return VisitAttributes(D
) || Visit(D
);
518 if (clang_isStatement(Cursor
.kind
)) {
519 if (const Stmt
*S
= getCursorStmt(Cursor
))
525 if (clang_isExpression(Cursor
.kind
)) {
526 if (const Expr
*E
= getCursorExpr(Cursor
))
532 if (clang_isTranslationUnit(Cursor
.kind
)) {
533 CXTranslationUnit TU
= getCursorTU(Cursor
);
534 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
536 int VisitOrder
[2] = {VisitPreprocessorLast
, !VisitPreprocessorLast
};
537 for (unsigned I
= 0; I
!= 2; ++I
) {
539 if (!CXXUnit
->isMainFileAST() && CXXUnit
->getOnlyLocalDecls() &&
540 RegionOfInterest
.isInvalid()) {
541 for (ASTUnit::top_level_iterator TL
= CXXUnit
->top_level_begin(),
542 TLEnd
= CXXUnit
->top_level_end();
544 const std::optional
<bool> V
= handleDeclForVisitation(*TL
);
549 } else if (VisitDeclContext(
550 CXXUnit
->getASTContext().getTranslationUnitDecl()))
555 // Walk the preprocessing record.
556 if (CXXUnit
->getPreprocessor().getPreprocessingRecord())
557 visitPreprocessedEntitiesInRegion();
563 if (Cursor
.kind
== CXCursor_CXXBaseSpecifier
) {
564 if (const CXXBaseSpecifier
*Base
= getCursorCXXBaseSpecifier(Cursor
)) {
565 if (TypeSourceInfo
*BaseTSInfo
= Base
->getTypeSourceInfo()) {
566 return Visit(BaseTSInfo
->getTypeLoc());
571 if (Cursor
.kind
== CXCursor_IBOutletCollectionAttr
) {
572 const IBOutletCollectionAttr
*A
=
573 cast
<IBOutletCollectionAttr
>(cxcursor::getCursorAttr(Cursor
));
574 if (const ObjCObjectType
*ObjT
= A
->getInterface()->getAs
<ObjCObjectType
>())
575 return Visit(cxcursor::MakeCursorObjCClassRef(
576 ObjT
->getInterface(),
577 A
->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU
));
580 if (clang_isAttribute(Cursor
.kind
)) {
581 if (const Attr
*A
= getCursorAttr(Cursor
))
587 // If pointing inside a macro definition, check if the token is an identifier
588 // that was ever defined as a macro. In such a case, create a "pseudo" macro
589 // expansion cursor for that token.
590 SourceLocation BeginLoc
= RegionOfInterest
.getBegin();
591 if (Cursor
.kind
== CXCursor_MacroDefinition
&&
592 BeginLoc
== RegionOfInterest
.getEnd()) {
593 SourceLocation Loc
= AU
->mapLocationToPreamble(BeginLoc
);
594 const MacroInfo
*MI
=
595 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor
), TU
);
596 if (MacroDefinitionRecord
*MacroDef
=
597 checkForMacroInMacroDefinition(MI
, Loc
, TU
))
598 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef
, BeginLoc
, TU
));
601 // Nothing to visit at the moment.
605 bool CursorVisitor::VisitBlockDecl(BlockDecl
*B
) {
606 if (TypeSourceInfo
*TSInfo
= B
->getSignatureAsWritten())
607 if (Visit(TSInfo
->getTypeLoc()))
610 if (Stmt
*Body
= B
->getBody())
611 return Visit(MakeCXCursor(Body
, StmtParent
, TU
, RegionOfInterest
));
616 std::optional
<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor
) {
617 if (RegionOfInterest
.isValid()) {
618 SourceRange Range
= getFullCursorExtent(Cursor
, AU
->getSourceManager());
619 if (Range
.isInvalid())
622 switch (CompareRegionOfInterest(Range
)) {
624 // This declaration comes before the region of interest; skip it.
628 // This declaration comes after the region of interest; we're done.
632 // This declaration overlaps the region of interest; visit it.
639 bool CursorVisitor::VisitDeclContext(DeclContext
*DC
) {
640 DeclContext::decl_iterator I
= DC
->decls_begin(), E
= DC
->decls_end();
642 // FIXME: Eventually remove. This part of a hack to support proper
643 // iteration over all Decls contained lexically within an ObjC container.
644 SaveAndRestore
DI_saved(DI_current
, &I
);
645 SaveAndRestore
DE_saved(DE_current
, E
);
647 for (; I
!= E
; ++I
) {
649 if (D
->getLexicalDeclContext() != DC
)
651 // Filter out synthesized property accessor redeclarations.
652 if (isa
<ObjCImplDecl
>(DC
))
653 if (auto *OMD
= dyn_cast
<ObjCMethodDecl
>(D
))
654 if (OMD
->isSynthesizedAccessorStub())
656 const std::optional
<bool> V
= handleDeclForVisitation(D
);
664 std::optional
<bool> CursorVisitor::handleDeclForVisitation(const Decl
*D
) {
665 CXCursor Cursor
= MakeCXCursor(D
, TU
, RegionOfInterest
);
667 // Ignore synthesized ivars here, otherwise if we have something like:
668 // @synthesize prop = _prop;
669 // and '_prop' is not declared, we will encounter a '_prop' ivar before
670 // encountering the 'prop' synthesize declaration and we will think that
671 // we passed the region-of-interest.
672 if (auto *ivarD
= dyn_cast
<ObjCIvarDecl
>(D
)) {
673 if (ivarD
->getSynthesize())
677 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
678 // declarations is a mismatch with the compiler semantics.
679 if (Cursor
.kind
== CXCursor_ObjCInterfaceDecl
) {
680 auto *ID
= cast
<ObjCInterfaceDecl
>(D
);
681 if (!ID
->isThisDeclarationADefinition())
682 Cursor
= MakeCursorObjCClassRef(ID
, ID
->getLocation(), TU
);
684 } else if (Cursor
.kind
== CXCursor_ObjCProtocolDecl
) {
685 auto *PD
= cast
<ObjCProtocolDecl
>(D
);
686 if (!PD
->isThisDeclarationADefinition())
687 Cursor
= MakeCursorObjCProtocolRef(PD
, PD
->getLocation(), TU
);
690 const std::optional
<bool> V
= shouldVisitCursor(Cursor
);
695 if (Visit(Cursor
, true))
700 bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl
*D
) {
701 llvm_unreachable("Translation units are visited directly by Visit()");
704 bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl
*D
) {
705 if (VisitTemplateParameters(D
->getTemplateParameters()))
708 return Visit(MakeCXCursor(D
->getTemplatedDecl(), TU
, RegionOfInterest
));
711 bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl
*D
) {
712 if (TypeSourceInfo
*TSInfo
= D
->getTypeSourceInfo())
713 return Visit(TSInfo
->getTypeLoc());
718 bool CursorVisitor::VisitTypedefDecl(TypedefDecl
*D
) {
719 if (TypeSourceInfo
*TSInfo
= D
->getTypeSourceInfo())
720 return Visit(TSInfo
->getTypeLoc());
725 bool CursorVisitor::VisitTagDecl(TagDecl
*D
) { return VisitDeclContext(D
); }
727 bool CursorVisitor::VisitClassTemplateSpecializationDecl(
728 ClassTemplateSpecializationDecl
*D
) {
729 bool ShouldVisitBody
= false;
730 switch (D
->getSpecializationKind()) {
732 case TSK_ImplicitInstantiation
:
736 case TSK_ExplicitInstantiationDeclaration
:
737 case TSK_ExplicitInstantiationDefinition
:
740 case TSK_ExplicitSpecialization
:
741 ShouldVisitBody
= true;
745 // Visit the template arguments used in the specialization.
746 if (const auto *ArgsWritten
= D
->getTemplateArgsAsWritten()) {
747 for (const TemplateArgumentLoc
&Arg
: ArgsWritten
->arguments())
748 if (VisitTemplateArgumentLoc(Arg
))
752 return ShouldVisitBody
&& VisitCXXRecordDecl(D
);
755 bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
756 ClassTemplatePartialSpecializationDecl
*D
) {
757 // FIXME: Visit the "outer" template parameter lists on the TagDecl
758 // before visiting these template parameters.
759 if (VisitTemplateParameters(D
->getTemplateParameters()))
762 // Visit the partial specialization arguments.
763 const ASTTemplateArgumentListInfo
*Info
= D
->getTemplateArgsAsWritten();
764 const TemplateArgumentLoc
*TemplateArgs
= Info
->getTemplateArgs();
765 for (unsigned I
= 0, N
= Info
->NumTemplateArgs
; I
!= N
; ++I
)
766 if (VisitTemplateArgumentLoc(TemplateArgs
[I
]))
769 return VisitCXXRecordDecl(D
);
772 bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl
*D
) {
773 if (const auto *TC
= D
->getTypeConstraint()) {
774 if (VisitTypeConstraint(*TC
))
778 // Visit the default argument.
779 if (D
->hasDefaultArgument() && !D
->defaultArgumentWasInherited() &&
780 VisitTemplateArgumentLoc(D
->getDefaultArgument()))
786 bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl
*D
) {
787 if (Expr
*Init
= D
->getInitExpr())
788 return Visit(MakeCXCursor(Init
, StmtParent
, TU
, RegionOfInterest
));
792 bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl
*DD
) {
793 unsigned NumParamList
= DD
->getNumTemplateParameterLists();
794 for (unsigned i
= 0; i
< NumParamList
; i
++) {
795 TemplateParameterList
*Params
= DD
->getTemplateParameterList(i
);
796 if (VisitTemplateParameters(Params
))
800 if (TypeSourceInfo
*TSInfo
= DD
->getTypeSourceInfo())
801 if (Visit(TSInfo
->getTypeLoc()))
804 // Visit the nested-name-specifier, if present.
805 if (NestedNameSpecifierLoc QualifierLoc
= DD
->getQualifierLoc())
806 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
812 static bool HasTrailingReturnType(FunctionDecl
*ND
) {
813 const QualType Ty
= ND
->getType();
814 if (const FunctionType
*AFT
= Ty
->getAs
<FunctionType
>()) {
815 if (const FunctionProtoType
*FT
= dyn_cast
<FunctionProtoType
>(AFT
))
816 return FT
->hasTrailingReturn();
822 /// Compare two base or member initializers based on their source order.
823 static int CompareCXXCtorInitializers(CXXCtorInitializer
*const *X
,
824 CXXCtorInitializer
*const *Y
) {
825 return (*X
)->getSourceOrder() - (*Y
)->getSourceOrder();
828 bool CursorVisitor::VisitFunctionDecl(FunctionDecl
*ND
) {
829 unsigned NumParamList
= ND
->getNumTemplateParameterLists();
830 for (unsigned i
= 0; i
< NumParamList
; i
++) {
831 TemplateParameterList
*Params
= ND
->getTemplateParameterList(i
);
832 if (VisitTemplateParameters(Params
))
836 if (TypeSourceInfo
*TSInfo
= ND
->getTypeSourceInfo()) {
837 // Visit the function declaration's syntactic components in the order
838 // written. This requires a bit of work.
839 TypeLoc TL
= TSInfo
->getTypeLoc().IgnoreParens();
840 FunctionTypeLoc FTL
= TL
.getAs
<FunctionTypeLoc
>();
841 const bool HasTrailingRT
= HasTrailingReturnType(ND
);
843 // If we have a function declared directly (without the use of a typedef),
844 // visit just the return type. Otherwise, just visit the function's type
846 if ((FTL
&& !isa
<CXXConversionDecl
>(ND
) && !HasTrailingRT
&&
847 Visit(FTL
.getReturnLoc())) ||
851 // Visit the nested-name-specifier, if present.
852 if (NestedNameSpecifierLoc QualifierLoc
= ND
->getQualifierLoc())
853 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
856 // Visit the declaration name.
857 if (!isa
<CXXDestructorDecl
>(ND
))
858 if (VisitDeclarationNameInfo(ND
->getNameInfo()))
861 // FIXME: Visit explicitly-specified template arguments!
863 // Visit the function parameters, if we have a function type.
864 if (FTL
&& VisitFunctionTypeLoc(FTL
, true))
867 // Visit the function's trailing return type.
868 if (FTL
&& HasTrailingRT
&& Visit(FTL
.getReturnLoc()))
871 // FIXME: Attributes?
874 if (auto *E
= ND
->getTrailingRequiresClause()) {
879 if (ND
->doesThisDeclarationHaveABody() && !ND
->isLateTemplateParsed()) {
880 if (CXXConstructorDecl
*Constructor
= dyn_cast
<CXXConstructorDecl
>(ND
)) {
881 // Find the initializers that were written in the source.
882 SmallVector
<CXXCtorInitializer
*, 4> WrittenInits
;
883 for (auto *I
: Constructor
->inits()) {
887 WrittenInits
.push_back(I
);
890 // Sort the initializers in source order
891 llvm::array_pod_sort(WrittenInits
.begin(), WrittenInits
.end(),
892 &CompareCXXCtorInitializers
);
894 // Visit the initializers in source order
895 for (unsigned I
= 0, N
= WrittenInits
.size(); I
!= N
; ++I
) {
896 CXXCtorInitializer
*Init
= WrittenInits
[I
];
897 if (Init
->isAnyMemberInitializer()) {
898 if (Visit(MakeCursorMemberRef(Init
->getAnyMember(),
899 Init
->getMemberLocation(), TU
)))
901 } else if (TypeSourceInfo
*TInfo
= Init
->getTypeSourceInfo()) {
902 if (Visit(TInfo
->getTypeLoc()))
906 // Visit the initializer value.
907 if (Expr
*Initializer
= Init
->getInit())
908 if (Visit(MakeCXCursor(Initializer
, ND
, TU
, RegionOfInterest
)))
913 if (Visit(MakeCXCursor(ND
->getBody(), StmtParent
, TU
, RegionOfInterest
)))
920 bool CursorVisitor::VisitFieldDecl(FieldDecl
*D
) {
921 if (VisitDeclaratorDecl(D
))
924 if (Expr
*BitWidth
= D
->getBitWidth())
925 return Visit(MakeCXCursor(BitWidth
, StmtParent
, TU
, RegionOfInterest
));
927 if (Expr
*Init
= D
->getInClassInitializer())
928 return Visit(MakeCXCursor(Init
, StmtParent
, TU
, RegionOfInterest
));
933 bool CursorVisitor::VisitVarDecl(VarDecl
*D
) {
934 if (VisitDeclaratorDecl(D
))
937 if (Expr
*Init
= D
->getInit())
938 return Visit(MakeCXCursor(Init
, StmtParent
, TU
, RegionOfInterest
));
943 bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl
*D
) {
944 if (VisitDeclaratorDecl(D
))
947 if (D
->hasDefaultArgument() && !D
->defaultArgumentWasInherited())
948 if (D
->hasDefaultArgument() &&
949 VisitTemplateArgumentLoc(D
->getDefaultArgument()))
955 bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl
*D
) {
956 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
957 // before visiting these template parameters.
958 if (VisitTemplateParameters(D
->getTemplateParameters()))
961 auto *FD
= D
->getTemplatedDecl();
962 return VisitAttributes(FD
) || VisitFunctionDecl(FD
);
965 bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl
*D
) {
966 // FIXME: Visit the "outer" template parameter lists on the TagDecl
967 // before visiting these template parameters.
968 if (VisitTemplateParameters(D
->getTemplateParameters()))
971 auto *CD
= D
->getTemplatedDecl();
972 return VisitAttributes(CD
) || VisitCXXRecordDecl(CD
);
975 bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl
*D
) {
976 if (VisitTemplateParameters(D
->getTemplateParameters()))
979 if (D
->hasDefaultArgument() && !D
->defaultArgumentWasInherited() &&
980 VisitTemplateArgumentLoc(D
->getDefaultArgument()))
986 bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl
*D
) {
987 // Visit the bound, if it's explicit.
988 if (D
->hasExplicitBound()) {
989 if (auto TInfo
= D
->getTypeSourceInfo()) {
990 if (Visit(TInfo
->getTypeLoc()))
998 bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl
*ND
) {
999 if (TypeSourceInfo
*TSInfo
= ND
->getReturnTypeSourceInfo())
1000 if (Visit(TSInfo
->getTypeLoc()))
1003 for (const auto *P
: ND
->parameters()) {
1004 if (Visit(MakeCXCursor(P
, TU
, RegionOfInterest
)))
1008 return ND
->isThisDeclarationADefinition() &&
1009 Visit(MakeCXCursor(ND
->getBody(), StmtParent
, TU
, RegionOfInterest
));
1012 template <typename DeclIt
>
1013 static void addRangedDeclsInContainer(DeclIt
*DI_current
, DeclIt DE_current
,
1014 SourceManager
&SM
, SourceLocation EndLoc
,
1015 SmallVectorImpl
<Decl
*> &Decls
) {
1016 DeclIt next
= *DI_current
;
1017 while (++next
!= DE_current
) {
1018 Decl
*D_next
= *next
;
1021 SourceLocation L
= D_next
->getBeginLoc();
1024 if (SM
.isBeforeInTranslationUnit(L
, EndLoc
)) {
1026 Decls
.push_back(D_next
);
1033 bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl
*D
) {
1034 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
1035 // an @implementation can lexically contain Decls that are not properly
1036 // nested in the AST. When we identify such cases, we need to retrofit
1037 // this nesting here.
1038 if (!DI_current
&& !FileDI_current
)
1039 return VisitDeclContext(D
);
1041 // Scan the Decls that immediately come after the container
1042 // in the current DeclContext. If any fall within the
1043 // container's lexical region, stash them into a vector
1044 // for later processing.
1045 SmallVector
<Decl
*, 24> DeclsInContainer
;
1046 SourceLocation EndLoc
= D
->getSourceRange().getEnd();
1047 SourceManager
&SM
= AU
->getSourceManager();
1048 if (EndLoc
.isValid()) {
1050 addRangedDeclsInContainer(DI_current
, DE_current
, SM
, EndLoc
,
1053 addRangedDeclsInContainer(FileDI_current
, FileDE_current
, SM
, EndLoc
,
1059 if (DeclsInContainer
.empty())
1060 return VisitDeclContext(D
);
1062 // Get all the Decls in the DeclContext, and sort them with the
1063 // additional ones we've collected. Then visit them.
1064 for (auto *SubDecl
: D
->decls()) {
1065 if (!SubDecl
|| SubDecl
->getLexicalDeclContext() != D
||
1066 SubDecl
->getBeginLoc().isInvalid())
1068 DeclsInContainer
.push_back(SubDecl
);
1071 // Now sort the Decls so that they appear in lexical order.
1072 llvm::sort(DeclsInContainer
, [&SM
](Decl
*A
, Decl
*B
) {
1073 SourceLocation L_A
= A
->getBeginLoc();
1074 SourceLocation L_B
= B
->getBeginLoc();
1076 ? SM
.isBeforeInTranslationUnit(L_A
, L_B
)
1077 : SM
.isBeforeInTranslationUnit(A
->getEndLoc(), B
->getEndLoc());
1080 // Now visit the decls.
1081 for (SmallVectorImpl
<Decl
*>::iterator I
= DeclsInContainer
.begin(),
1082 E
= DeclsInContainer
.end();
1084 CXCursor Cursor
= MakeCXCursor(*I
, TU
, RegionOfInterest
);
1085 const std::optional
<bool> &V
= shouldVisitCursor(Cursor
);
1090 if (Visit(Cursor
, true))
1096 bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl
*ND
) {
1097 if (Visit(MakeCursorObjCClassRef(ND
->getClassInterface(), ND
->getLocation(),
1101 if (VisitObjCTypeParamList(ND
->getTypeParamList()))
1104 ObjCCategoryDecl::protocol_loc_iterator PL
= ND
->protocol_loc_begin();
1105 for (ObjCCategoryDecl::protocol_iterator I
= ND
->protocol_begin(),
1106 E
= ND
->protocol_end();
1108 if (Visit(MakeCursorObjCProtocolRef(*I
, *PL
, TU
)))
1111 return VisitObjCContainerDecl(ND
);
1114 bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl
*PID
) {
1115 if (!PID
->isThisDeclarationADefinition())
1116 return Visit(MakeCursorObjCProtocolRef(PID
, PID
->getLocation(), TU
));
1118 ObjCProtocolDecl::protocol_loc_iterator PL
= PID
->protocol_loc_begin();
1119 for (ObjCProtocolDecl::protocol_iterator I
= PID
->protocol_begin(),
1120 E
= PID
->protocol_end();
1122 if (Visit(MakeCursorObjCProtocolRef(*I
, *PL
, TU
)))
1125 return VisitObjCContainerDecl(PID
);
1128 bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl
*PD
) {
1129 if (PD
->getTypeSourceInfo() && Visit(PD
->getTypeSourceInfo()->getTypeLoc()))
1132 // FIXME: This implements a workaround with @property declarations also being
1133 // installed in the DeclContext for the @interface. Eventually this code
1134 // should be removed.
1135 ObjCCategoryDecl
*CDecl
= dyn_cast
<ObjCCategoryDecl
>(PD
->getDeclContext());
1136 if (!CDecl
|| !CDecl
->IsClassExtension())
1139 ObjCInterfaceDecl
*ID
= CDecl
->getClassInterface();
1143 IdentifierInfo
*PropertyId
= PD
->getIdentifier();
1144 ObjCPropertyDecl
*prevDecl
= ObjCPropertyDecl::findPropertyDecl(
1145 cast
<DeclContext
>(ID
), PropertyId
, PD
->getQueryKind());
1150 // Visit synthesized methods since they will be skipped when visiting
1152 if (ObjCMethodDecl
*MD
= prevDecl
->getGetterMethodDecl())
1153 if (MD
->isPropertyAccessor() && MD
->getLexicalDeclContext() == CDecl
)
1154 if (Visit(MakeCXCursor(MD
, TU
, RegionOfInterest
)))
1157 if (ObjCMethodDecl
*MD
= prevDecl
->getSetterMethodDecl())
1158 if (MD
->isPropertyAccessor() && MD
->getLexicalDeclContext() == CDecl
)
1159 if (Visit(MakeCXCursor(MD
, TU
, RegionOfInterest
)))
1165 bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList
*typeParamList
) {
1169 for (auto *typeParam
: *typeParamList
) {
1170 // Visit the type parameter.
1171 if (Visit(MakeCXCursor(typeParam
, TU
, RegionOfInterest
)))
1178 bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl
*D
) {
1179 if (!D
->isThisDeclarationADefinition()) {
1180 // Forward declaration is treated like a reference.
1181 return Visit(MakeCursorObjCClassRef(D
, D
->getLocation(), TU
));
1184 // Objective-C type parameters.
1185 if (VisitObjCTypeParamList(D
->getTypeParamListAsWritten()))
1188 // Issue callbacks for super class.
1189 if (D
->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
1190 D
->getSuperClass(), D
->getSuperClassLoc(), TU
)))
1193 if (TypeSourceInfo
*SuperClassTInfo
= D
->getSuperClassTInfo())
1194 if (Visit(SuperClassTInfo
->getTypeLoc()))
1197 ObjCInterfaceDecl::protocol_loc_iterator PL
= D
->protocol_loc_begin();
1198 for (ObjCInterfaceDecl::protocol_iterator I
= D
->protocol_begin(),
1199 E
= D
->protocol_end();
1201 if (Visit(MakeCursorObjCProtocolRef(*I
, *PL
, TU
)))
1204 return VisitObjCContainerDecl(D
);
1207 bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl
*D
) {
1208 return VisitObjCContainerDecl(D
);
1211 bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl
*D
) {
1212 // 'ID' could be null when dealing with invalid code.
1213 if (ObjCInterfaceDecl
*ID
= D
->getClassInterface())
1214 if (Visit(MakeCursorObjCClassRef(ID
, D
->getLocation(), TU
)))
1217 return VisitObjCImplDecl(D
);
1220 bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl
*D
) {
1222 // Issue callbacks for super class.
1223 // FIXME: No source location information!
1224 if (D
->getSuperClass() &&
1225 Visit(MakeCursorObjCSuperClassRef(D
->getSuperClass(),
1226 D
->getSuperClassLoc(),
1231 return VisitObjCImplDecl(D
);
1234 bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl
*PD
) {
1235 if (ObjCIvarDecl
*Ivar
= PD
->getPropertyIvarDecl())
1236 if (PD
->isIvarNameSpecified())
1237 return Visit(MakeCursorMemberRef(Ivar
, PD
->getPropertyIvarDeclLoc(), TU
));
1242 bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl
*D
) {
1243 return VisitDeclContext(D
);
1246 bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl
*D
) {
1247 // Visit nested-name-specifier.
1248 if (NestedNameSpecifierLoc QualifierLoc
= D
->getQualifierLoc())
1249 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
1252 return Visit(MakeCursorNamespaceRef(D
->getAliasedNamespace(),
1253 D
->getTargetNameLoc(), TU
));
1256 bool CursorVisitor::VisitUsingDecl(UsingDecl
*D
) {
1257 // Visit nested-name-specifier.
1258 if (NestedNameSpecifierLoc QualifierLoc
= D
->getQualifierLoc()) {
1259 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
1263 if (Visit(MakeCursorOverloadedDeclRef(D
, D
->getLocation(), TU
)))
1266 return VisitDeclarationNameInfo(D
->getNameInfo());
1269 bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl
*D
) {
1270 // Visit nested-name-specifier.
1271 if (NestedNameSpecifierLoc QualifierLoc
= D
->getQualifierLoc())
1272 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
1275 return Visit(MakeCursorNamespaceRef(D
->getNominatedNamespaceAsWritten(),
1276 D
->getIdentLocation(), TU
));
1279 bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl
*D
) {
1280 // Visit nested-name-specifier.
1281 if (NestedNameSpecifierLoc QualifierLoc
= D
->getQualifierLoc()) {
1282 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
1286 return VisitDeclarationNameInfo(D
->getNameInfo());
1289 bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1290 UnresolvedUsingTypenameDecl
*D
) {
1291 // Visit nested-name-specifier.
1292 if (NestedNameSpecifierLoc QualifierLoc
= D
->getQualifierLoc())
1293 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
1299 bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl
*D
) {
1300 if (Visit(MakeCXCursor(D
->getAssertExpr(), StmtParent
, TU
, RegionOfInterest
)))
1302 if (auto *Message
= D
->getMessage())
1303 if (Visit(MakeCXCursor(Message
, StmtParent
, TU
, RegionOfInterest
)))
1308 bool CursorVisitor::VisitFriendDecl(FriendDecl
*D
) {
1309 if (NamedDecl
*FriendD
= D
->getFriendDecl()) {
1310 if (Visit(MakeCXCursor(FriendD
, TU
, RegionOfInterest
)))
1312 } else if (TypeSourceInfo
*TI
= D
->getFriendType()) {
1313 if (Visit(TI
->getTypeLoc()))
1319 bool CursorVisitor::VisitDecompositionDecl(DecompositionDecl
*D
) {
1320 for (auto *B
: D
->bindings()) {
1321 if (Visit(MakeCXCursor(B
, TU
, RegionOfInterest
)))
1324 return VisitVarDecl(D
);
1327 bool CursorVisitor::VisitConceptDecl(ConceptDecl
*D
) {
1328 if (VisitTemplateParameters(D
->getTemplateParameters()))
1331 if (auto *E
= D
->getConstraintExpr()) {
1332 if (Visit(MakeCXCursor(E
, D
, TU
, RegionOfInterest
)))
1338 bool CursorVisitor::VisitTypeConstraint(const TypeConstraint
&TC
) {
1339 if (TC
.getNestedNameSpecifierLoc()) {
1340 if (VisitNestedNameSpecifierLoc(TC
.getNestedNameSpecifierLoc()))
1343 if (TC
.getNamedConcept()) {
1344 if (Visit(MakeCursorTemplateRef(TC
.getNamedConcept(),
1345 TC
.getConceptNameLoc(), TU
)))
1348 if (auto Args
= TC
.getTemplateArgsAsWritten()) {
1349 for (const auto &Arg
: Args
->arguments()) {
1350 if (VisitTemplateArgumentLoc(Arg
))
1357 bool CursorVisitor::VisitConceptRequirement(const concepts::Requirement
&R
) {
1358 using namespace concepts
;
1359 switch (R
.getKind()) {
1360 case Requirement::RK_Type
: {
1361 const TypeRequirement
&TR
= cast
<TypeRequirement
>(R
);
1362 if (!TR
.isSubstitutionFailure()) {
1363 if (Visit(TR
.getType()->getTypeLoc()))
1368 case Requirement::RK_Simple
:
1369 case Requirement::RK_Compound
: {
1370 const ExprRequirement
&ER
= cast
<ExprRequirement
>(R
);
1371 if (!ER
.isExprSubstitutionFailure()) {
1372 if (Visit(ER
.getExpr()))
1375 if (ER
.getKind() == Requirement::RK_Compound
) {
1376 const auto &RTR
= ER
.getReturnTypeRequirement();
1377 if (RTR
.isTypeConstraint()) {
1378 if (const auto *Cons
= RTR
.getTypeConstraint())
1379 VisitTypeConstraint(*Cons
);
1384 case Requirement::RK_Nested
: {
1385 const NestedRequirement
&NR
= cast
<NestedRequirement
>(R
);
1386 if (!NR
.hasInvalidConstraint()) {
1387 if (Visit(NR
.getConstraintExpr()))
1396 bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name
) {
1397 switch (Name
.getName().getNameKind()) {
1398 case clang::DeclarationName::Identifier
:
1399 case clang::DeclarationName::CXXLiteralOperatorName
:
1400 case clang::DeclarationName::CXXDeductionGuideName
:
1401 case clang::DeclarationName::CXXOperatorName
:
1402 case clang::DeclarationName::CXXUsingDirective
:
1405 case clang::DeclarationName::CXXConstructorName
:
1406 case clang::DeclarationName::CXXDestructorName
:
1407 case clang::DeclarationName::CXXConversionFunctionName
:
1408 if (TypeSourceInfo
*TSInfo
= Name
.getNamedTypeInfo())
1409 return Visit(TSInfo
->getTypeLoc());
1412 case clang::DeclarationName::ObjCZeroArgSelector
:
1413 case clang::DeclarationName::ObjCOneArgSelector
:
1414 case clang::DeclarationName::ObjCMultiArgSelector
:
1415 // FIXME: Per-identifier location info?
1419 llvm_unreachable("Invalid DeclarationName::Kind!");
1422 bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier
*NNS
,
1423 SourceRange Range
) {
1424 // FIXME: This whole routine is a hack to work around the lack of proper
1425 // source information in nested-name-specifiers (PR5791). Since we do have
1426 // a beginning source location, we can visit the first component of the
1427 // nested-name-specifier, if it's a single-token component.
1431 // Get the first component in the nested-name-specifier.
1432 while (NestedNameSpecifier
*Prefix
= NNS
->getPrefix())
1435 switch (NNS
->getKind()) {
1436 case NestedNameSpecifier::Namespace
:
1438 MakeCursorNamespaceRef(NNS
->getAsNamespace(), Range
.getBegin(), TU
));
1440 case NestedNameSpecifier::NamespaceAlias
:
1441 return Visit(MakeCursorNamespaceRef(NNS
->getAsNamespaceAlias(),
1442 Range
.getBegin(), TU
));
1444 case NestedNameSpecifier::TypeSpec
: {
1445 // If the type has a form where we know that the beginning of the source
1446 // range matches up with a reference cursor. Visit the appropriate reference
1448 const Type
*T
= NNS
->getAsType();
1449 if (const TypedefType
*Typedef
= dyn_cast
<TypedefType
>(T
))
1450 return Visit(MakeCursorTypeRef(Typedef
->getDecl(), Range
.getBegin(), TU
));
1451 if (const TagType
*Tag
= dyn_cast
<TagType
>(T
))
1452 return Visit(MakeCursorTypeRef(Tag
->getDecl(), Range
.getBegin(), TU
));
1453 if (const TemplateSpecializationType
*TST
=
1454 dyn_cast
<TemplateSpecializationType
>(T
))
1455 return VisitTemplateName(TST
->getTemplateName(), Range
.getBegin());
1459 case NestedNameSpecifier::TypeSpecWithTemplate
:
1460 case NestedNameSpecifier::Global
:
1461 case NestedNameSpecifier::Identifier
:
1462 case NestedNameSpecifier::Super
:
1469 bool CursorVisitor::VisitNestedNameSpecifierLoc(
1470 NestedNameSpecifierLoc Qualifier
) {
1471 SmallVector
<NestedNameSpecifierLoc
, 4> Qualifiers
;
1472 for (; Qualifier
; Qualifier
= Qualifier
.getPrefix())
1473 Qualifiers
.push_back(Qualifier
);
1475 while (!Qualifiers
.empty()) {
1476 NestedNameSpecifierLoc Q
= Qualifiers
.pop_back_val();
1477 NestedNameSpecifier
*NNS
= Q
.getNestedNameSpecifier();
1478 switch (NNS
->getKind()) {
1479 case NestedNameSpecifier::Namespace
:
1480 if (Visit(MakeCursorNamespaceRef(NNS
->getAsNamespace(),
1481 Q
.getLocalBeginLoc(), TU
)))
1486 case NestedNameSpecifier::NamespaceAlias
:
1487 if (Visit(MakeCursorNamespaceRef(NNS
->getAsNamespaceAlias(),
1488 Q
.getLocalBeginLoc(), TU
)))
1493 case NestedNameSpecifier::TypeSpec
:
1494 case NestedNameSpecifier::TypeSpecWithTemplate
:
1495 if (Visit(Q
.getTypeLoc()))
1500 case NestedNameSpecifier::Global
:
1501 case NestedNameSpecifier::Identifier
:
1502 case NestedNameSpecifier::Super
:
1510 bool CursorVisitor::VisitTemplateParameters(
1511 const TemplateParameterList
*Params
) {
1515 for (TemplateParameterList::const_iterator P
= Params
->begin(),
1516 PEnd
= Params
->end();
1518 if (Visit(MakeCXCursor(*P
, TU
, RegionOfInterest
)))
1522 if (const auto *E
= Params
->getRequiresClause()) {
1523 if (Visit(MakeCXCursor(E
, nullptr, TU
, RegionOfInterest
)))
1530 bool CursorVisitor::VisitTemplateName(TemplateName Name
, SourceLocation Loc
) {
1531 switch (Name
.getKind()) {
1532 case TemplateName::Template
:
1533 case TemplateName::UsingTemplate
:
1534 case TemplateName::QualifiedTemplate
: // FIXME: Visit nested-name-specifier.
1535 return Visit(MakeCursorTemplateRef(Name
.getAsTemplateDecl(), Loc
, TU
));
1537 case TemplateName::OverloadedTemplate
:
1538 // Visit the overloaded template set.
1539 if (Visit(MakeCursorOverloadedDeclRef(Name
, Loc
, TU
)))
1544 case TemplateName::AssumedTemplate
:
1545 // FIXME: Visit DeclarationName?
1548 case TemplateName::DependentTemplate
:
1549 // FIXME: Visit nested-name-specifier.
1552 case TemplateName::SubstTemplateTemplateParm
:
1553 return Visit(MakeCursorTemplateRef(
1554 Name
.getAsSubstTemplateTemplateParm()->getParameter(), Loc
, TU
));
1556 case TemplateName::SubstTemplateTemplateParmPack
:
1557 return Visit(MakeCursorTemplateRef(
1558 Name
.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc
,
1561 case TemplateName::DeducedTemplate
:
1562 llvm_unreachable("DeducedTemplate shouldn't appear in source");
1565 llvm_unreachable("Invalid TemplateName::Kind!");
1568 bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc
&TAL
) {
1569 switch (TAL
.getArgument().getKind()) {
1570 case TemplateArgument::Null
:
1571 case TemplateArgument::Integral
:
1572 case TemplateArgument::Pack
:
1575 case TemplateArgument::Type
:
1576 if (TypeSourceInfo
*TSInfo
= TAL
.getTypeSourceInfo())
1577 return Visit(TSInfo
->getTypeLoc());
1580 case TemplateArgument::Declaration
:
1581 if (Expr
*E
= TAL
.getSourceDeclExpression())
1582 return Visit(MakeCXCursor(E
, StmtParent
, TU
, RegionOfInterest
));
1585 case TemplateArgument::StructuralValue
:
1586 if (Expr
*E
= TAL
.getSourceStructuralValueExpression())
1587 return Visit(MakeCXCursor(E
, StmtParent
, TU
, RegionOfInterest
));
1590 case TemplateArgument::NullPtr
:
1591 if (Expr
*E
= TAL
.getSourceNullPtrExpression())
1592 return Visit(MakeCXCursor(E
, StmtParent
, TU
, RegionOfInterest
));
1595 case TemplateArgument::Expression
:
1596 if (Expr
*E
= TAL
.getSourceExpression())
1597 return Visit(MakeCXCursor(E
, StmtParent
, TU
, RegionOfInterest
));
1600 case TemplateArgument::Template
:
1601 case TemplateArgument::TemplateExpansion
:
1602 if (VisitNestedNameSpecifierLoc(TAL
.getTemplateQualifierLoc()))
1605 return VisitTemplateName(TAL
.getArgument().getAsTemplateOrTemplatePattern(),
1606 TAL
.getTemplateNameLoc());
1609 llvm_unreachable("Invalid TemplateArgument::Kind!");
1612 bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl
*D
) {
1613 return VisitDeclContext(D
);
1616 bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL
) {
1617 return Visit(TL
.getUnqualifiedLoc());
1620 bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL
) {
1621 ASTContext
&Context
= AU
->getASTContext();
1623 // Some builtin types (such as Objective-C's "id", "sel", and
1624 // "Class") have associated declarations. Create cursors for those.
1626 switch (TL
.getTypePtr()->getKind()) {
1628 case BuiltinType::Void
:
1629 case BuiltinType::NullPtr
:
1630 case BuiltinType::Dependent
:
1631 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
1632 case BuiltinType::Id:
1633 #include "clang/Basic/OpenCLImageTypes.def"
1634 #define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
1635 #include "clang/Basic/OpenCLExtensionTypes.def"
1636 case BuiltinType::OCLSampler
:
1637 case BuiltinType::OCLEvent
:
1638 case BuiltinType::OCLClkEvent
:
1639 case BuiltinType::OCLQueue
:
1640 case BuiltinType::OCLReserveID
:
1641 #define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1642 #include "clang/Basic/AArch64SVEACLETypes.def"
1643 #define PPC_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
1644 #include "clang/Basic/PPCTypes.def"
1645 #define RVV_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1646 #include "clang/Basic/RISCVVTypes.def"
1647 #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1648 #include "clang/Basic/WebAssemblyReferenceTypes.def"
1649 #define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) case BuiltinType::Id:
1650 #include "clang/Basic/AMDGPUTypes.def"
1651 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
1652 #include "clang/Basic/HLSLIntangibleTypes.def"
1653 #define BUILTIN_TYPE(Id, SingletonId)
1654 #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1655 #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1656 #define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1657 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1658 #include "clang/AST/BuiltinTypes.def"
1661 case BuiltinType::ObjCId
:
1662 VisitType
= Context
.getObjCIdType();
1665 case BuiltinType::ObjCClass
:
1666 VisitType
= Context
.getObjCClassType();
1669 case BuiltinType::ObjCSel
:
1670 VisitType
= Context
.getObjCSelType();
1674 if (!VisitType
.isNull()) {
1675 if (const TypedefType
*Typedef
= VisitType
->getAs
<TypedefType
>())
1677 MakeCursorTypeRef(Typedef
->getDecl(), TL
.getBuiltinLoc(), TU
));
1683 bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL
) {
1684 return Visit(MakeCursorTypeRef(TL
.getTypedefNameDecl(), TL
.getNameLoc(), TU
));
1687 bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL
) {
1688 return Visit(MakeCursorTypeRef(TL
.getDecl(), TL
.getNameLoc(), TU
));
1691 bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL
) {
1692 if (TL
.isDefinition())
1693 return Visit(MakeCXCursor(TL
.getDecl(), TU
, RegionOfInterest
));
1695 return Visit(MakeCursorTypeRef(TL
.getDecl(), TL
.getNameLoc(), TU
));
1698 bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL
) {
1699 if (const auto *TC
= TL
.getDecl()->getTypeConstraint()) {
1700 if (VisitTypeConstraint(*TC
))
1704 return Visit(MakeCursorTypeRef(TL
.getDecl(), TL
.getNameLoc(), TU
));
1707 bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL
) {
1708 return Visit(MakeCursorObjCClassRef(TL
.getIFaceDecl(), TL
.getNameLoc(), TU
));
1711 bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL
) {
1712 if (Visit(MakeCursorTypeRef(TL
.getDecl(), TL
.getBeginLoc(), TU
)))
1714 for (unsigned I
= 0, N
= TL
.getNumProtocols(); I
!= N
; ++I
) {
1715 if (Visit(MakeCursorObjCProtocolRef(TL
.getProtocol(I
), TL
.getProtocolLoc(I
),
1723 bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL
) {
1724 if (TL
.hasBaseTypeAsWritten() && Visit(TL
.getBaseLoc()))
1727 for (unsigned I
= 0, N
= TL
.getNumTypeArgs(); I
!= N
; ++I
) {
1728 if (Visit(TL
.getTypeArgTInfo(I
)->getTypeLoc()))
1732 for (unsigned I
= 0, N
= TL
.getNumProtocols(); I
!= N
; ++I
) {
1733 if (Visit(MakeCursorObjCProtocolRef(TL
.getProtocol(I
), TL
.getProtocolLoc(I
),
1741 bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL
) {
1742 return Visit(TL
.getPointeeLoc());
1745 bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL
) {
1746 return Visit(TL
.getInnerLoc());
1749 bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL
) {
1750 return Visit(TL
.getInnerLoc());
1753 bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL
) {
1754 return Visit(TL
.getPointeeLoc());
1757 bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL
) {
1758 return Visit(TL
.getPointeeLoc());
1761 bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL
) {
1762 return Visit(TL
.getPointeeLoc());
1765 bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL
) {
1766 return Visit(TL
.getPointeeLoc());
1769 bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL
) {
1770 return Visit(TL
.getPointeeLoc());
1773 bool CursorVisitor::VisitUsingTypeLoc(UsingTypeLoc TL
) {
1774 auto *underlyingDecl
= TL
.getUnderlyingType()->getAsTagDecl();
1775 if (underlyingDecl
) {
1776 return Visit(MakeCursorTypeRef(underlyingDecl
, TL
.getNameLoc(), TU
));
1781 bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL
) {
1782 return Visit(TL
.getModifiedLoc());
1785 bool CursorVisitor::VisitCountAttributedTypeLoc(CountAttributedTypeLoc TL
) {
1786 return Visit(TL
.getInnerLoc());
1789 bool CursorVisitor::VisitBTFTagAttributedTypeLoc(BTFTagAttributedTypeLoc TL
) {
1790 return Visit(TL
.getWrappedLoc());
1793 bool CursorVisitor::VisitHLSLAttributedResourceTypeLoc(
1794 HLSLAttributedResourceTypeLoc TL
) {
1795 return Visit(TL
.getWrappedLoc());
1798 bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL
,
1799 bool SkipResultType
) {
1800 if (!SkipResultType
&& Visit(TL
.getReturnLoc()))
1803 for (unsigned I
= 0, N
= TL
.getNumParams(); I
!= N
; ++I
)
1804 if (Decl
*D
= TL
.getParam(I
))
1805 if (Visit(MakeCXCursor(D
, TU
, RegionOfInterest
)))
1811 bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL
) {
1812 if (Visit(TL
.getElementLoc()))
1815 if (Expr
*Size
= TL
.getSizeExpr())
1816 return Visit(MakeCXCursor(Size
, StmtParent
, TU
, RegionOfInterest
));
1821 bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL
) {
1822 return Visit(TL
.getOriginalLoc());
1825 bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL
) {
1826 return Visit(TL
.getOriginalLoc());
1829 bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
1830 DeducedTemplateSpecializationTypeLoc TL
) {
1831 if (VisitTemplateName(TL
.getTypePtr()->getTemplateName(),
1832 TL
.getTemplateNameLoc()))
1838 bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1839 TemplateSpecializationTypeLoc TL
) {
1840 // Visit the template name.
1841 if (VisitTemplateName(TL
.getTypePtr()->getTemplateName(),
1842 TL
.getTemplateNameLoc()))
1845 // Visit the template arguments.
1846 for (unsigned I
= 0, N
= TL
.getNumArgs(); I
!= N
; ++I
)
1847 if (VisitTemplateArgumentLoc(TL
.getArgLoc(I
)))
1853 bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL
) {
1854 return Visit(MakeCXCursor(TL
.getUnderlyingExpr(), StmtParent
, TU
));
1857 bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL
) {
1858 if (TypeSourceInfo
*TSInfo
= TL
.getUnmodifiedTInfo())
1859 return Visit(TSInfo
->getTypeLoc());
1864 bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL
) {
1865 if (TypeSourceInfo
*TSInfo
= TL
.getUnderlyingTInfo())
1866 return Visit(TSInfo
->getTypeLoc());
1871 bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL
) {
1872 return VisitNestedNameSpecifierLoc(TL
.getQualifierLoc());
1875 bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1876 DependentTemplateSpecializationTypeLoc TL
) {
1877 // Visit the nested-name-specifier, if there is one.
1878 if (TL
.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL
.getQualifierLoc()))
1881 // Visit the template arguments.
1882 for (unsigned I
= 0, N
= TL
.getNumArgs(); I
!= N
; ++I
)
1883 if (VisitTemplateArgumentLoc(TL
.getArgLoc(I
)))
1889 bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL
) {
1890 if (VisitNestedNameSpecifierLoc(TL
.getQualifierLoc()))
1893 return Visit(TL
.getNamedTypeLoc());
1896 bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL
) {
1897 return Visit(TL
.getPatternLoc());
1900 bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL
) {
1901 if (Expr
*E
= TL
.getUnderlyingExpr())
1902 return Visit(MakeCXCursor(E
, StmtParent
, TU
));
1907 bool CursorVisitor::VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL
) {
1908 if (Visit(TL
.getPatternLoc()))
1910 return Visit(MakeCXCursor(TL
.getIndexExpr(), StmtParent
, TU
));
1913 bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL
) {
1914 return Visit(MakeCursorTypeRef(TL
.getDecl(), TL
.getNameLoc(), TU
));
1917 bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL
) {
1918 return Visit(TL
.getValueLoc());
1921 bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL
) {
1922 return Visit(TL
.getValueLoc());
1925 #define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1926 bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1927 return Visit##PARENT##Loc(TL); \
1930 DEFAULT_TYPELOC_IMPL(Complex
, Type
)
1931 DEFAULT_TYPELOC_IMPL(ConstantArray
, ArrayType
)
1932 DEFAULT_TYPELOC_IMPL(IncompleteArray
, ArrayType
)
1933 DEFAULT_TYPELOC_IMPL(VariableArray
, ArrayType
)
1934 DEFAULT_TYPELOC_IMPL(DependentSizedArray
, ArrayType
)
1935 DEFAULT_TYPELOC_IMPL(ArrayParameter
, ConstantArrayType
)
1936 DEFAULT_TYPELOC_IMPL(DependentAddressSpace
, Type
)
1937 DEFAULT_TYPELOC_IMPL(DependentVector
, Type
)
1938 DEFAULT_TYPELOC_IMPL(DependentSizedExtVector
, Type
)
1939 DEFAULT_TYPELOC_IMPL(Vector
, Type
)
1940 DEFAULT_TYPELOC_IMPL(ExtVector
, VectorType
)
1941 DEFAULT_TYPELOC_IMPL(ConstantMatrix
, MatrixType
)
1942 DEFAULT_TYPELOC_IMPL(DependentSizedMatrix
, MatrixType
)
1943 DEFAULT_TYPELOC_IMPL(FunctionProto
, FunctionType
)
1944 DEFAULT_TYPELOC_IMPL(FunctionNoProto
, FunctionType
)
1945 DEFAULT_TYPELOC_IMPL(Record
, TagType
)
1946 DEFAULT_TYPELOC_IMPL(Enum
, TagType
)
1947 DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm
, Type
)
1948 DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack
, Type
)
1949 DEFAULT_TYPELOC_IMPL(Auto
, Type
)
1950 DEFAULT_TYPELOC_IMPL(BitInt
, Type
)
1951 DEFAULT_TYPELOC_IMPL(DependentBitInt
, Type
)
1953 bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl
*D
) {
1954 // Visit the nested-name-specifier, if present.
1955 if (NestedNameSpecifierLoc QualifierLoc
= D
->getQualifierLoc())
1956 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
1959 if (D
->isCompleteDefinition()) {
1960 for (const auto &I
: D
->bases()) {
1961 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I
, TU
)))
1966 return VisitTagDecl(D
);
1969 bool CursorVisitor::VisitAttributes(Decl
*D
) {
1970 for (const auto *I
: D
->attrs())
1971 if ((TU
->ParsingOptions
& CXTranslationUnit_VisitImplicitAttributes
||
1972 !I
->isImplicit()) &&
1973 Visit(MakeCXCursor(I
, D
, TU
)))
1979 //===----------------------------------------------------------------------===//
1980 // Data-recursive visitor methods.
1981 //===----------------------------------------------------------------------===//
1984 #define DEF_JOB(NAME, DATA, KIND) \
1985 class NAME : public VisitorJob { \
1987 NAME(const DATA *d, CXCursor parent) \
1988 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1989 static bool classof(const VisitorJob *VJ) { \
1990 return VJ->getKind() == KIND; \
1992 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1995 DEF_JOB(StmtVisit
, Stmt
, StmtVisitKind
)
1996 DEF_JOB(MemberExprParts
, MemberExpr
, MemberExprPartsKind
)
1997 DEF_JOB(DeclRefExprParts
, DeclRefExpr
, DeclRefExprPartsKind
)
1998 DEF_JOB(OverloadExprParts
, OverloadExpr
, OverloadExprPartsKind
)
1999 DEF_JOB(SizeOfPackExprParts
, SizeOfPackExpr
, SizeOfPackExprPartsKind
)
2000 DEF_JOB(LambdaExprParts
, LambdaExpr
, LambdaExprPartsKind
)
2001 DEF_JOB(ConceptSpecializationExprVisit
, ConceptSpecializationExpr
,
2002 ConceptSpecializationExprVisitKind
)
2003 DEF_JOB(RequiresExprVisit
, RequiresExpr
, RequiresExprVisitKind
)
2004 DEF_JOB(PostChildrenVisit
, void, PostChildrenVisitKind
)
2007 class ExplicitTemplateArgsVisit
: public VisitorJob
{
2009 ExplicitTemplateArgsVisit(const TemplateArgumentLoc
*Begin
,
2010 const TemplateArgumentLoc
*End
, CXCursor parent
)
2011 : VisitorJob(parent
, VisitorJob::ExplicitTemplateArgsVisitKind
, Begin
,
2013 static bool classof(const VisitorJob
*VJ
) {
2014 return VJ
->getKind() == ExplicitTemplateArgsVisitKind
;
2016 const TemplateArgumentLoc
*begin() const {
2017 return static_cast<const TemplateArgumentLoc
*>(data
[0]);
2019 const TemplateArgumentLoc
*end() {
2020 return static_cast<const TemplateArgumentLoc
*>(data
[1]);
2023 class DeclVisit
: public VisitorJob
{
2025 DeclVisit(const Decl
*D
, CXCursor parent
, bool isFirst
)
2026 : VisitorJob(parent
, VisitorJob::DeclVisitKind
, D
,
2027 isFirst
? (void *)1 : (void *)nullptr) {}
2028 static bool classof(const VisitorJob
*VJ
) {
2029 return VJ
->getKind() == DeclVisitKind
;
2031 const Decl
*get() const { return static_cast<const Decl
*>(data
[0]); }
2032 bool isFirst() const { return data
[1] != nullptr; }
2034 class TypeLocVisit
: public VisitorJob
{
2036 TypeLocVisit(TypeLoc tl
, CXCursor parent
)
2037 : VisitorJob(parent
, VisitorJob::TypeLocVisitKind
,
2038 tl
.getType().getAsOpaquePtr(), tl
.getOpaqueData()) {}
2040 static bool classof(const VisitorJob
*VJ
) {
2041 return VJ
->getKind() == TypeLocVisitKind
;
2044 TypeLoc
get() const {
2045 QualType T
= QualType::getFromOpaquePtr(data
[0]);
2046 return TypeLoc(T
, const_cast<void *>(data
[1]));
2050 class LabelRefVisit
: public VisitorJob
{
2052 LabelRefVisit(LabelDecl
*LD
, SourceLocation labelLoc
, CXCursor parent
)
2053 : VisitorJob(parent
, VisitorJob::LabelRefVisitKind
, LD
,
2054 labelLoc
.getPtrEncoding()) {}
2056 static bool classof(const VisitorJob
*VJ
) {
2057 return VJ
->getKind() == VisitorJob::LabelRefVisitKind
;
2059 const LabelDecl
*get() const {
2060 return static_cast<const LabelDecl
*>(data
[0]);
2062 SourceLocation
getLoc() const {
2063 return SourceLocation::getFromPtrEncoding(data
[1]);
2067 class NestedNameSpecifierLocVisit
: public VisitorJob
{
2069 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier
, CXCursor parent
)
2070 : VisitorJob(parent
, VisitorJob::NestedNameSpecifierLocVisitKind
,
2071 Qualifier
.getNestedNameSpecifier(),
2072 Qualifier
.getOpaqueData()) {}
2074 static bool classof(const VisitorJob
*VJ
) {
2075 return VJ
->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind
;
2078 NestedNameSpecifierLoc
get() const {
2079 return NestedNameSpecifierLoc(
2080 const_cast<NestedNameSpecifier
*>(
2081 static_cast<const NestedNameSpecifier
*>(data
[0])),
2082 const_cast<void *>(data
[1]));
2086 class DeclarationNameInfoVisit
: public VisitorJob
{
2088 DeclarationNameInfoVisit(const Stmt
*S
, CXCursor parent
)
2089 : VisitorJob(parent
, VisitorJob::DeclarationNameInfoVisitKind
, S
) {}
2090 static bool classof(const VisitorJob
*VJ
) {
2091 return VJ
->getKind() == VisitorJob::DeclarationNameInfoVisitKind
;
2093 DeclarationNameInfo
get() const {
2094 const Stmt
*S
= static_cast<const Stmt
*>(data
[0]);
2095 switch (S
->getStmtClass()) {
2097 llvm_unreachable("Unhandled Stmt");
2098 case clang::Stmt::MSDependentExistsStmtClass
:
2099 return cast
<MSDependentExistsStmt
>(S
)->getNameInfo();
2100 case Stmt::CXXDependentScopeMemberExprClass
:
2101 return cast
<CXXDependentScopeMemberExpr
>(S
)->getMemberNameInfo();
2102 case Stmt::DependentScopeDeclRefExprClass
:
2103 return cast
<DependentScopeDeclRefExpr
>(S
)->getNameInfo();
2104 case Stmt::OMPCriticalDirectiveClass
:
2105 return cast
<OMPCriticalDirective
>(S
)->getDirectiveName();
2109 class MemberRefVisit
: public VisitorJob
{
2111 MemberRefVisit(const FieldDecl
*D
, SourceLocation L
, CXCursor parent
)
2112 : VisitorJob(parent
, VisitorJob::MemberRefVisitKind
, D
,
2113 L
.getPtrEncoding()) {}
2114 static bool classof(const VisitorJob
*VJ
) {
2115 return VJ
->getKind() == VisitorJob::MemberRefVisitKind
;
2117 const FieldDecl
*get() const {
2118 return static_cast<const FieldDecl
*>(data
[0]);
2120 SourceLocation
getLoc() const {
2121 return SourceLocation::getFromRawEncoding(
2122 (SourceLocation::UIntTy
)(uintptr_t)data
[1]);
2125 class EnqueueVisitor
: public ConstStmtVisitor
<EnqueueVisitor
, void>,
2126 public ConstAttrVisitor
<EnqueueVisitor
, void> {
2127 friend class OpenACCClauseEnqueue
;
2128 friend class OMPClauseEnqueue
;
2129 VisitorWorkList
&WL
;
2133 EnqueueVisitor(VisitorWorkList
&wl
, CXCursor parent
)
2134 : WL(wl
), Parent(parent
) {}
2136 void VisitAddrLabelExpr(const AddrLabelExpr
*E
);
2137 void VisitBlockExpr(const BlockExpr
*B
);
2138 void VisitCompoundLiteralExpr(const CompoundLiteralExpr
*E
);
2139 void VisitCompoundStmt(const CompoundStmt
*S
);
2140 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr
*E
) { /* Do nothing. */
2142 void VisitMSDependentExistsStmt(const MSDependentExistsStmt
*S
);
2143 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr
*E
);
2144 void VisitCXXNewExpr(const CXXNewExpr
*E
);
2145 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr
*E
);
2146 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr
*E
);
2147 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr
*E
);
2148 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr
*E
);
2149 void VisitCXXTypeidExpr(const CXXTypeidExpr
*E
);
2150 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr
*E
);
2151 void VisitCXXUuidofExpr(const CXXUuidofExpr
*E
);
2152 void VisitCXXCatchStmt(const CXXCatchStmt
*S
);
2153 void VisitCXXForRangeStmt(const CXXForRangeStmt
*S
);
2154 void VisitDeclRefExpr(const DeclRefExpr
*D
);
2155 void VisitDeclStmt(const DeclStmt
*S
);
2156 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr
*E
);
2157 void VisitDesignatedInitExpr(const DesignatedInitExpr
*E
);
2158 void VisitExplicitCastExpr(const ExplicitCastExpr
*E
);
2159 void VisitForStmt(const ForStmt
*FS
);
2160 void VisitGotoStmt(const GotoStmt
*GS
);
2161 void VisitIfStmt(const IfStmt
*If
);
2162 void VisitInitListExpr(const InitListExpr
*IE
);
2163 void VisitMemberExpr(const MemberExpr
*M
);
2164 void VisitOffsetOfExpr(const OffsetOfExpr
*E
);
2165 void VisitObjCEncodeExpr(const ObjCEncodeExpr
*E
);
2166 void VisitObjCMessageExpr(const ObjCMessageExpr
*M
);
2167 void VisitOverloadExpr(const OverloadExpr
*E
);
2168 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr
*E
);
2169 void VisitStmt(const Stmt
*S
);
2170 void VisitSwitchStmt(const SwitchStmt
*S
);
2171 void VisitWhileStmt(const WhileStmt
*W
);
2172 void VisitTypeTraitExpr(const TypeTraitExpr
*E
);
2173 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr
*E
);
2174 void VisitExpressionTraitExpr(const ExpressionTraitExpr
*E
);
2175 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr
*U
);
2176 void VisitVAArgExpr(const VAArgExpr
*E
);
2177 void VisitSizeOfPackExpr(const SizeOfPackExpr
*E
);
2178 void VisitPseudoObjectExpr(const PseudoObjectExpr
*E
);
2179 void VisitOpaqueValueExpr(const OpaqueValueExpr
*E
);
2180 void VisitLambdaExpr(const LambdaExpr
*E
);
2181 void VisitConceptSpecializationExpr(const ConceptSpecializationExpr
*E
);
2182 void VisitRequiresExpr(const RequiresExpr
*E
);
2183 void VisitCXXParenListInitExpr(const CXXParenListInitExpr
*E
);
2184 void VisitOpenACCComputeConstruct(const OpenACCComputeConstruct
*D
);
2185 void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct
*D
);
2186 void VisitOpenACCCombinedConstruct(const OpenACCCombinedConstruct
*D
);
2187 void VisitOMPExecutableDirective(const OMPExecutableDirective
*D
);
2188 void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective
*D
);
2189 void VisitOMPLoopDirective(const OMPLoopDirective
*D
);
2190 void VisitOMPParallelDirective(const OMPParallelDirective
*D
);
2191 void VisitOMPSimdDirective(const OMPSimdDirective
*D
);
2193 VisitOMPLoopTransformationDirective(const OMPLoopTransformationDirective
*D
);
2194 void VisitOMPTileDirective(const OMPTileDirective
*D
);
2195 void VisitOMPUnrollDirective(const OMPUnrollDirective
*D
);
2196 void VisitOMPReverseDirective(const OMPReverseDirective
*D
);
2197 void VisitOMPInterchangeDirective(const OMPInterchangeDirective
*D
);
2198 void VisitOMPForDirective(const OMPForDirective
*D
);
2199 void VisitOMPForSimdDirective(const OMPForSimdDirective
*D
);
2200 void VisitOMPSectionsDirective(const OMPSectionsDirective
*D
);
2201 void VisitOMPSectionDirective(const OMPSectionDirective
*D
);
2202 void VisitOMPSingleDirective(const OMPSingleDirective
*D
);
2203 void VisitOMPMasterDirective(const OMPMasterDirective
*D
);
2204 void VisitOMPCriticalDirective(const OMPCriticalDirective
*D
);
2205 void VisitOMPParallelForDirective(const OMPParallelForDirective
*D
);
2206 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective
*D
);
2207 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective
*D
);
2208 void VisitOMPParallelMaskedDirective(const OMPParallelMaskedDirective
*D
);
2209 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective
*D
);
2210 void VisitOMPTaskDirective(const OMPTaskDirective
*D
);
2211 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective
*D
);
2212 void VisitOMPBarrierDirective(const OMPBarrierDirective
*D
);
2213 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective
*D
);
2214 void VisitOMPAssumeDirective(const OMPAssumeDirective
*D
);
2215 void VisitOMPErrorDirective(const OMPErrorDirective
*D
);
2216 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective
*D
);
2218 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective
*D
);
2219 void VisitOMPCancelDirective(const OMPCancelDirective
*D
);
2220 void VisitOMPFlushDirective(const OMPFlushDirective
*D
);
2221 void VisitOMPDepobjDirective(const OMPDepobjDirective
*D
);
2222 void VisitOMPScanDirective(const OMPScanDirective
*D
);
2223 void VisitOMPOrderedDirective(const OMPOrderedDirective
*D
);
2224 void VisitOMPAtomicDirective(const OMPAtomicDirective
*D
);
2225 void VisitOMPTargetDirective(const OMPTargetDirective
*D
);
2226 void VisitOMPTargetDataDirective(const OMPTargetDataDirective
*D
);
2227 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective
*D
);
2228 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective
*D
);
2229 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective
*D
);
2231 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective
*D
);
2232 void VisitOMPTeamsDirective(const OMPTeamsDirective
*D
);
2233 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective
*D
);
2234 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective
*D
);
2235 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective
*D
);
2236 void VisitOMPMaskedTaskLoopDirective(const OMPMaskedTaskLoopDirective
*D
);
2238 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective
*D
);
2239 void VisitOMPMaskedTaskLoopSimdDirective(
2240 const OMPMaskedTaskLoopSimdDirective
*D
);
2241 void VisitOMPParallelMasterTaskLoopDirective(
2242 const OMPParallelMasterTaskLoopDirective
*D
);
2243 void VisitOMPParallelMaskedTaskLoopDirective(
2244 const OMPParallelMaskedTaskLoopDirective
*D
);
2245 void VisitOMPParallelMasterTaskLoopSimdDirective(
2246 const OMPParallelMasterTaskLoopSimdDirective
*D
);
2247 void VisitOMPParallelMaskedTaskLoopSimdDirective(
2248 const OMPParallelMaskedTaskLoopSimdDirective
*D
);
2249 void VisitOMPDistributeDirective(const OMPDistributeDirective
*D
);
2250 void VisitOMPDistributeParallelForDirective(
2251 const OMPDistributeParallelForDirective
*D
);
2252 void VisitOMPDistributeParallelForSimdDirective(
2253 const OMPDistributeParallelForSimdDirective
*D
);
2254 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective
*D
);
2255 void VisitOMPTargetParallelForSimdDirective(
2256 const OMPTargetParallelForSimdDirective
*D
);
2257 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective
*D
);
2258 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective
*D
);
2259 void VisitOMPTeamsDistributeSimdDirective(
2260 const OMPTeamsDistributeSimdDirective
*D
);
2261 void VisitOMPTeamsDistributeParallelForSimdDirective(
2262 const OMPTeamsDistributeParallelForSimdDirective
*D
);
2263 void VisitOMPTeamsDistributeParallelForDirective(
2264 const OMPTeamsDistributeParallelForDirective
*D
);
2265 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective
*D
);
2266 void VisitOMPTargetTeamsDistributeDirective(
2267 const OMPTargetTeamsDistributeDirective
*D
);
2268 void VisitOMPTargetTeamsDistributeParallelForDirective(
2269 const OMPTargetTeamsDistributeParallelForDirective
*D
);
2270 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2271 const OMPTargetTeamsDistributeParallelForSimdDirective
*D
);
2272 void VisitOMPTargetTeamsDistributeSimdDirective(
2273 const OMPTargetTeamsDistributeSimdDirective
*D
);
2276 void VisitAnnotateAttr(const AnnotateAttr
*A
);
2279 void AddDeclarationNameInfo(const Stmt
*S
);
2280 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier
);
2281 void AddExplicitTemplateArgs(const TemplateArgumentLoc
*A
,
2282 unsigned NumTemplateArgs
);
2283 void AddMemberRef(const FieldDecl
*D
, SourceLocation L
);
2284 void AddStmt(const Stmt
*S
);
2285 void AddDecl(const Decl
*D
, bool isFirst
= true);
2286 void AddTypeLoc(TypeSourceInfo
*TI
);
2287 void EnqueueChildren(const Stmt
*S
);
2288 void EnqueueChildren(const OpenACCClause
*S
);
2289 void EnqueueChildren(const OMPClause
*S
);
2290 void EnqueueChildren(const AnnotateAttr
*A
);
2294 void EnqueueVisitor::AddDeclarationNameInfo(const Stmt
*S
) {
2295 // 'S' should always be non-null, since it comes from the
2296 // statement we are visiting.
2297 WL
.push_back(DeclarationNameInfoVisit(S
, Parent
));
2300 void EnqueueVisitor::AddNestedNameSpecifierLoc(
2301 NestedNameSpecifierLoc Qualifier
) {
2303 WL
.push_back(NestedNameSpecifierLocVisit(Qualifier
, Parent
));
2306 void EnqueueVisitor::AddStmt(const Stmt
*S
) {
2308 WL
.push_back(StmtVisit(S
, Parent
));
2310 void EnqueueVisitor::AddDecl(const Decl
*D
, bool isFirst
) {
2312 WL
.push_back(DeclVisit(D
, Parent
, isFirst
));
2314 void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc
*A
,
2315 unsigned NumTemplateArgs
) {
2316 WL
.push_back(ExplicitTemplateArgsVisit(A
, A
+ NumTemplateArgs
, Parent
));
2318 void EnqueueVisitor::AddMemberRef(const FieldDecl
*D
, SourceLocation L
) {
2320 WL
.push_back(MemberRefVisit(D
, L
, Parent
));
2322 void EnqueueVisitor::AddTypeLoc(TypeSourceInfo
*TI
) {
2324 WL
.push_back(TypeLocVisit(TI
->getTypeLoc(), Parent
));
2326 void EnqueueVisitor::EnqueueChildren(const Stmt
*S
) {
2327 unsigned size
= WL
.size();
2328 for (const Stmt
*SubStmt
: S
->children()) {
2331 if (size
== WL
.size())
2333 // Now reverse the entries we just added. This will match the DFS
2334 // ordering performed by the worklist.
2335 VisitorWorkList::iterator I
= WL
.begin() + size
, E
= WL
.end();
2339 class OMPClauseEnqueue
: public ConstOMPClauseVisitor
<OMPClauseEnqueue
> {
2340 EnqueueVisitor
*Visitor
;
2341 /// Process clauses with list of variables.
2342 template <typename T
> void VisitOMPClauseList(T
*Node
);
2345 OMPClauseEnqueue(EnqueueVisitor
*Visitor
) : Visitor(Visitor
) {}
2346 #define GEN_CLANG_CLAUSE_CLASS
2347 #define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2348 #include "llvm/Frontend/OpenMP/OMP.inc"
2349 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit
*C
);
2350 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate
*C
);
2353 void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2354 const OMPClauseWithPreInit
*C
) {
2355 Visitor
->AddStmt(C
->getPreInitStmt());
2358 void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2359 const OMPClauseWithPostUpdate
*C
) {
2360 VisitOMPClauseWithPreInit(C
);
2361 Visitor
->AddStmt(C
->getPostUpdateExpr());
2364 void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause
*C
) {
2365 VisitOMPClauseWithPreInit(C
);
2366 Visitor
->AddStmt(C
->getCondition());
2369 void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause
*C
) {
2370 Visitor
->AddStmt(C
->getCondition());
2373 void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause
*C
) {
2374 VisitOMPClauseWithPreInit(C
);
2375 Visitor
->AddStmt(C
->getNumThreads());
2378 void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause
*C
) {
2379 Visitor
->AddStmt(C
->getSafelen());
2382 void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause
*C
) {
2383 Visitor
->AddStmt(C
->getSimdlen());
2386 void OMPClauseEnqueue::VisitOMPSizesClause(const OMPSizesClause
*C
) {
2387 for (auto E
: C
->getSizesRefs())
2388 Visitor
->AddStmt(E
);
2391 void OMPClauseEnqueue::VisitOMPPermutationClause(
2392 const OMPPermutationClause
*C
) {
2393 for (auto E
: C
->getArgsRefs())
2394 Visitor
->AddStmt(E
);
2397 void OMPClauseEnqueue::VisitOMPFullClause(const OMPFullClause
*C
) {}
2399 void OMPClauseEnqueue::VisitOMPPartialClause(const OMPPartialClause
*C
) {
2400 Visitor
->AddStmt(C
->getFactor());
2403 void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause
*C
) {
2404 Visitor
->AddStmt(C
->getAllocator());
2407 void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause
*C
) {
2408 Visitor
->AddStmt(C
->getNumForLoops());
2411 void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause
*C
) {}
2413 void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause
*C
) {}
2415 void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause
*C
) {
2416 VisitOMPClauseWithPreInit(C
);
2417 Visitor
->AddStmt(C
->getChunkSize());
2420 void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause
*C
) {
2421 Visitor
->AddStmt(C
->getNumForLoops());
2424 void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause
*C
) {
2425 Visitor
->AddStmt(C
->getEventHandler());
2428 void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause
*) {}
2430 void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause
*) {}
2432 void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause
*) {}
2434 void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause
*) {}
2436 void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause
*) {}
2438 void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause
*) {}
2440 void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause
*) {}
2442 void OMPClauseEnqueue::VisitOMPCompareClause(const OMPCompareClause
*) {}
2444 void OMPClauseEnqueue::VisitOMPFailClause(const OMPFailClause
*) {}
2446 void OMPClauseEnqueue::VisitOMPAbsentClause(const OMPAbsentClause
*) {}
2448 void OMPClauseEnqueue::VisitOMPHoldsClause(const OMPHoldsClause
*) {}
2450 void OMPClauseEnqueue::VisitOMPContainsClause(const OMPContainsClause
*) {}
2452 void OMPClauseEnqueue::VisitOMPNoOpenMPClause(const OMPNoOpenMPClause
*) {}
2454 void OMPClauseEnqueue::VisitOMPNoOpenMPRoutinesClause(
2455 const OMPNoOpenMPRoutinesClause
*) {}
2457 void OMPClauseEnqueue::VisitOMPNoParallelismClause(
2458 const OMPNoParallelismClause
*) {}
2460 void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause
*) {}
2462 void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause
*) {}
2464 void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause
*) {}
2466 void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause
*) {}
2468 void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause
*) {}
2470 void OMPClauseEnqueue::VisitOMPWeakClause(const OMPWeakClause
*) {}
2472 void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause
*) {}
2474 void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause
*) {}
2476 void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause
*) {}
2478 void OMPClauseEnqueue::VisitOMPInitClause(const OMPInitClause
*C
) {
2479 VisitOMPClauseList(C
);
2482 void OMPClauseEnqueue::VisitOMPUseClause(const OMPUseClause
*C
) {
2483 Visitor
->AddStmt(C
->getInteropVar());
2486 void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause
*C
) {
2487 if (C
->getInteropVar())
2488 Visitor
->AddStmt(C
->getInteropVar());
2491 void OMPClauseEnqueue::VisitOMPNovariantsClause(const OMPNovariantsClause
*C
) {
2492 Visitor
->AddStmt(C
->getCondition());
2495 void OMPClauseEnqueue::VisitOMPNocontextClause(const OMPNocontextClause
*C
) {
2496 Visitor
->AddStmt(C
->getCondition());
2499 void OMPClauseEnqueue::VisitOMPFilterClause(const OMPFilterClause
*C
) {
2500 VisitOMPClauseWithPreInit(C
);
2501 Visitor
->AddStmt(C
->getThreadID());
2504 void OMPClauseEnqueue::VisitOMPAlignClause(const OMPAlignClause
*C
) {
2505 Visitor
->AddStmt(C
->getAlignment());
2508 void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2509 const OMPUnifiedAddressClause
*) {}
2511 void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2512 const OMPUnifiedSharedMemoryClause
*) {}
2514 void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2515 const OMPReverseOffloadClause
*) {}
2517 void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2518 const OMPDynamicAllocatorsClause
*) {}
2520 void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2521 const OMPAtomicDefaultMemOrderClause
*) {}
2523 void OMPClauseEnqueue::VisitOMPAtClause(const OMPAtClause
*) {}
2525 void OMPClauseEnqueue::VisitOMPSeverityClause(const OMPSeverityClause
*) {}
2527 void OMPClauseEnqueue::VisitOMPMessageClause(const OMPMessageClause
*) {}
2529 void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause
*C
) {
2530 Visitor
->AddStmt(C
->getDevice());
2533 void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause
*C
) {
2534 VisitOMPClauseList(C
);
2535 VisitOMPClauseWithPreInit(C
);
2538 void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2539 const OMPThreadLimitClause
*C
) {
2540 VisitOMPClauseList(C
);
2541 VisitOMPClauseWithPreInit(C
);
2544 void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause
*C
) {
2545 Visitor
->AddStmt(C
->getPriority());
2548 void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause
*C
) {
2549 Visitor
->AddStmt(C
->getGrainsize());
2552 void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause
*C
) {
2553 Visitor
->AddStmt(C
->getNumTasks());
2556 void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause
*C
) {
2557 Visitor
->AddStmt(C
->getHint());
2560 template <typename T
> void OMPClauseEnqueue::VisitOMPClauseList(T
*Node
) {
2561 for (const auto *I
: Node
->varlist()) {
2562 Visitor
->AddStmt(I
);
2566 void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause
*C
) {
2567 VisitOMPClauseList(C
);
2569 void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause
*C
) {
2570 VisitOMPClauseList(C
);
2572 void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause
*C
) {
2573 VisitOMPClauseList(C
);
2574 Visitor
->AddStmt(C
->getAllocator());
2576 void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause
*C
) {
2577 VisitOMPClauseList(C
);
2578 for (const auto *E
: C
->private_copies()) {
2579 Visitor
->AddStmt(E
);
2582 void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2583 const OMPFirstprivateClause
*C
) {
2584 VisitOMPClauseList(C
);
2585 VisitOMPClauseWithPreInit(C
);
2586 for (const auto *E
: C
->private_copies()) {
2587 Visitor
->AddStmt(E
);
2589 for (const auto *E
: C
->inits()) {
2590 Visitor
->AddStmt(E
);
2593 void OMPClauseEnqueue::VisitOMPLastprivateClause(
2594 const OMPLastprivateClause
*C
) {
2595 VisitOMPClauseList(C
);
2596 VisitOMPClauseWithPostUpdate(C
);
2597 for (auto *E
: C
->private_copies()) {
2598 Visitor
->AddStmt(E
);
2600 for (auto *E
: C
->source_exprs()) {
2601 Visitor
->AddStmt(E
);
2603 for (auto *E
: C
->destination_exprs()) {
2604 Visitor
->AddStmt(E
);
2606 for (auto *E
: C
->assignment_ops()) {
2607 Visitor
->AddStmt(E
);
2610 void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause
*C
) {
2611 VisitOMPClauseList(C
);
2613 void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause
*C
) {
2614 VisitOMPClauseList(C
);
2615 VisitOMPClauseWithPostUpdate(C
);
2616 for (auto *E
: C
->privates()) {
2617 Visitor
->AddStmt(E
);
2619 for (auto *E
: C
->lhs_exprs()) {
2620 Visitor
->AddStmt(E
);
2622 for (auto *E
: C
->rhs_exprs()) {
2623 Visitor
->AddStmt(E
);
2625 for (auto *E
: C
->reduction_ops()) {
2626 Visitor
->AddStmt(E
);
2628 if (C
->getModifier() == clang::OMPC_REDUCTION_inscan
) {
2629 for (auto *E
: C
->copy_ops()) {
2630 Visitor
->AddStmt(E
);
2632 for (auto *E
: C
->copy_array_temps()) {
2633 Visitor
->AddStmt(E
);
2635 for (auto *E
: C
->copy_array_elems()) {
2636 Visitor
->AddStmt(E
);
2640 void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2641 const OMPTaskReductionClause
*C
) {
2642 VisitOMPClauseList(C
);
2643 VisitOMPClauseWithPostUpdate(C
);
2644 for (auto *E
: C
->privates()) {
2645 Visitor
->AddStmt(E
);
2647 for (auto *E
: C
->lhs_exprs()) {
2648 Visitor
->AddStmt(E
);
2650 for (auto *E
: C
->rhs_exprs()) {
2651 Visitor
->AddStmt(E
);
2653 for (auto *E
: C
->reduction_ops()) {
2654 Visitor
->AddStmt(E
);
2657 void OMPClauseEnqueue::VisitOMPInReductionClause(
2658 const OMPInReductionClause
*C
) {
2659 VisitOMPClauseList(C
);
2660 VisitOMPClauseWithPostUpdate(C
);
2661 for (auto *E
: C
->privates()) {
2662 Visitor
->AddStmt(E
);
2664 for (auto *E
: C
->lhs_exprs()) {
2665 Visitor
->AddStmt(E
);
2667 for (auto *E
: C
->rhs_exprs()) {
2668 Visitor
->AddStmt(E
);
2670 for (auto *E
: C
->reduction_ops()) {
2671 Visitor
->AddStmt(E
);
2673 for (auto *E
: C
->taskgroup_descriptors())
2674 Visitor
->AddStmt(E
);
2676 void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause
*C
) {
2677 VisitOMPClauseList(C
);
2678 VisitOMPClauseWithPostUpdate(C
);
2679 for (const auto *E
: C
->privates()) {
2680 Visitor
->AddStmt(E
);
2682 for (const auto *E
: C
->inits()) {
2683 Visitor
->AddStmt(E
);
2685 for (const auto *E
: C
->updates()) {
2686 Visitor
->AddStmt(E
);
2688 for (const auto *E
: C
->finals()) {
2689 Visitor
->AddStmt(E
);
2691 Visitor
->AddStmt(C
->getStep());
2692 Visitor
->AddStmt(C
->getCalcStep());
2694 void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause
*C
) {
2695 VisitOMPClauseList(C
);
2696 Visitor
->AddStmt(C
->getAlignment());
2698 void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause
*C
) {
2699 VisitOMPClauseList(C
);
2700 for (auto *E
: C
->source_exprs()) {
2701 Visitor
->AddStmt(E
);
2703 for (auto *E
: C
->destination_exprs()) {
2704 Visitor
->AddStmt(E
);
2706 for (auto *E
: C
->assignment_ops()) {
2707 Visitor
->AddStmt(E
);
2710 void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2711 const OMPCopyprivateClause
*C
) {
2712 VisitOMPClauseList(C
);
2713 for (auto *E
: C
->source_exprs()) {
2714 Visitor
->AddStmt(E
);
2716 for (auto *E
: C
->destination_exprs()) {
2717 Visitor
->AddStmt(E
);
2719 for (auto *E
: C
->assignment_ops()) {
2720 Visitor
->AddStmt(E
);
2723 void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause
*C
) {
2724 VisitOMPClauseList(C
);
2726 void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause
*C
) {
2727 Visitor
->AddStmt(C
->getDepobj());
2729 void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause
*C
) {
2730 VisitOMPClauseList(C
);
2732 void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause
*C
) {
2733 VisitOMPClauseList(C
);
2735 void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2736 const OMPDistScheduleClause
*C
) {
2737 VisitOMPClauseWithPreInit(C
);
2738 Visitor
->AddStmt(C
->getChunkSize());
2740 void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2741 const OMPDefaultmapClause
* /*C*/) {}
2742 void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause
*C
) {
2743 VisitOMPClauseList(C
);
2745 void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause
*C
) {
2746 VisitOMPClauseList(C
);
2748 void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2749 const OMPUseDevicePtrClause
*C
) {
2750 VisitOMPClauseList(C
);
2752 void OMPClauseEnqueue::VisitOMPUseDeviceAddrClause(
2753 const OMPUseDeviceAddrClause
*C
) {
2754 VisitOMPClauseList(C
);
2756 void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2757 const OMPIsDevicePtrClause
*C
) {
2758 VisitOMPClauseList(C
);
2760 void OMPClauseEnqueue::VisitOMPHasDeviceAddrClause(
2761 const OMPHasDeviceAddrClause
*C
) {
2762 VisitOMPClauseList(C
);
2764 void OMPClauseEnqueue::VisitOMPNontemporalClause(
2765 const OMPNontemporalClause
*C
) {
2766 VisitOMPClauseList(C
);
2767 for (const auto *E
: C
->private_refs())
2768 Visitor
->AddStmt(E
);
2770 void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause
*C
) {}
2771 void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
2772 const OMPUsesAllocatorsClause
*C
) {
2773 for (unsigned I
= 0, E
= C
->getNumberOfAllocators(); I
< E
; ++I
) {
2774 const OMPUsesAllocatorsClause::Data
&D
= C
->getAllocatorData(I
);
2775 Visitor
->AddStmt(D
.Allocator
);
2776 Visitor
->AddStmt(D
.AllocatorTraits
);
2779 void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause
*C
) {
2780 Visitor
->AddStmt(C
->getModifier());
2781 for (const Expr
*E
: C
->varlist())
2782 Visitor
->AddStmt(E
);
2784 void OMPClauseEnqueue::VisitOMPBindClause(const OMPBindClause
*C
) {}
2785 void OMPClauseEnqueue::VisitOMPXDynCGroupMemClause(
2786 const OMPXDynCGroupMemClause
*C
) {
2787 VisitOMPClauseWithPreInit(C
);
2788 Visitor
->AddStmt(C
->getSize());
2790 void OMPClauseEnqueue::VisitOMPDoacrossClause(const OMPDoacrossClause
*C
) {
2791 VisitOMPClauseList(C
);
2793 void OMPClauseEnqueue::VisitOMPXAttributeClause(const OMPXAttributeClause
*C
) {
2795 void OMPClauseEnqueue::VisitOMPXBareClause(const OMPXBareClause
*C
) {}
2799 void EnqueueVisitor::EnqueueChildren(const OMPClause
*S
) {
2800 unsigned size
= WL
.size();
2801 OMPClauseEnqueue
Visitor(this);
2803 if (size
== WL
.size())
2805 // Now reverse the entries we just added. This will match the DFS
2806 // ordering performed by the worklist.
2807 VisitorWorkList::iterator I
= WL
.begin() + size
, E
= WL
.end();
2812 class OpenACCClauseEnqueue
: public OpenACCClauseVisitor
<OpenACCClauseEnqueue
> {
2813 EnqueueVisitor
&Visitor
;
2816 OpenACCClauseEnqueue(EnqueueVisitor
&V
) : Visitor(V
) {}
2818 void VisitVarList(const OpenACCClauseWithVarList
&C
) {
2819 for (Expr
*Var
: C
.getVarList())
2820 Visitor
.AddStmt(Var
);
2823 #define VISIT_CLAUSE(CLAUSE_NAME) \
2824 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &C);
2825 #include "clang/Basic/OpenACCClauses.def"
2828 void OpenACCClauseEnqueue::VisitDefaultClause(const OpenACCDefaultClause
&C
) {}
2829 void OpenACCClauseEnqueue::VisitIfClause(const OpenACCIfClause
&C
) {
2830 Visitor
.AddStmt(C
.getConditionExpr());
2832 void OpenACCClauseEnqueue::VisitSelfClause(const OpenACCSelfClause
&C
) {
2833 if (C
.hasConditionExpr())
2834 Visitor
.AddStmt(C
.getConditionExpr());
2836 void OpenACCClauseEnqueue::VisitNumWorkersClause(
2837 const OpenACCNumWorkersClause
&C
) {
2838 Visitor
.AddStmt(C
.getIntExpr());
2840 void OpenACCClauseEnqueue::VisitVectorLengthClause(
2841 const OpenACCVectorLengthClause
&C
) {
2842 Visitor
.AddStmt(C
.getIntExpr());
2844 void OpenACCClauseEnqueue::VisitNumGangsClause(const OpenACCNumGangsClause
&C
) {
2845 for (Expr
*IE
: C
.getIntExprs())
2846 Visitor
.AddStmt(IE
);
2849 void OpenACCClauseEnqueue::VisitTileClause(const OpenACCTileClause
&C
) {
2850 for (Expr
*IE
: C
.getSizeExprs())
2851 Visitor
.AddStmt(IE
);
2854 void OpenACCClauseEnqueue::VisitPrivateClause(const OpenACCPrivateClause
&C
) {
2858 void OpenACCClauseEnqueue::VisitFirstPrivateClause(
2859 const OpenACCFirstPrivateClause
&C
) {
2863 void OpenACCClauseEnqueue::VisitPresentClause(const OpenACCPresentClause
&C
) {
2866 void OpenACCClauseEnqueue::VisitNoCreateClause(const OpenACCNoCreateClause
&C
) {
2869 void OpenACCClauseEnqueue::VisitCopyClause(const OpenACCCopyClause
&C
) {
2872 void OpenACCClauseEnqueue::VisitCopyInClause(const OpenACCCopyInClause
&C
) {
2875 void OpenACCClauseEnqueue::VisitCopyOutClause(const OpenACCCopyOutClause
&C
) {
2878 void OpenACCClauseEnqueue::VisitCreateClause(const OpenACCCreateClause
&C
) {
2881 void OpenACCClauseEnqueue::VisitAttachClause(const OpenACCAttachClause
&C
) {
2884 void OpenACCClauseEnqueue::VisitDevicePtrClause(
2885 const OpenACCDevicePtrClause
&C
) {
2888 void OpenACCClauseEnqueue::VisitAsyncClause(const OpenACCAsyncClause
&C
) {
2890 Visitor
.AddStmt(C
.getIntExpr());
2893 void OpenACCClauseEnqueue::VisitWorkerClause(const OpenACCWorkerClause
&C
) {
2895 Visitor
.AddStmt(C
.getIntExpr());
2898 void OpenACCClauseEnqueue::VisitVectorClause(const OpenACCVectorClause
&C
) {
2900 Visitor
.AddStmt(C
.getIntExpr());
2903 void OpenACCClauseEnqueue::VisitWaitClause(const OpenACCWaitClause
&C
) {
2904 if (const Expr
*DevNumExpr
= C
.getDevNumExpr())
2905 Visitor
.AddStmt(DevNumExpr
);
2906 for (Expr
*QE
: C
.getQueueIdExprs())
2907 Visitor
.AddStmt(QE
);
2909 void OpenACCClauseEnqueue::VisitDeviceTypeClause(
2910 const OpenACCDeviceTypeClause
&C
) {}
2911 void OpenACCClauseEnqueue::VisitReductionClause(
2912 const OpenACCReductionClause
&C
) {
2915 void OpenACCClauseEnqueue::VisitAutoClause(const OpenACCAutoClause
&C
) {}
2916 void OpenACCClauseEnqueue::VisitIndependentClause(
2917 const OpenACCIndependentClause
&C
) {}
2918 void OpenACCClauseEnqueue::VisitSeqClause(const OpenACCSeqClause
&C
) {}
2919 void OpenACCClauseEnqueue::VisitCollapseClause(const OpenACCCollapseClause
&C
) {
2920 Visitor
.AddStmt(C
.getLoopCount());
2922 void OpenACCClauseEnqueue::VisitGangClause(const OpenACCGangClause
&C
) {
2923 for (unsigned I
= 0; I
< C
.getNumExprs(); ++I
) {
2924 Visitor
.AddStmt(C
.getExpr(I
).second
);
2929 void EnqueueVisitor::EnqueueChildren(const OpenACCClause
*C
) {
2930 unsigned size
= WL
.size();
2931 OpenACCClauseEnqueue
Visitor(*this);
2934 if (size
== WL
.size())
2936 // Now reverse the entries we just added. This will match the DFS
2937 // ordering performed by the worklist.
2938 VisitorWorkList::iterator I
= WL
.begin() + size
, E
= WL
.end();
2942 void EnqueueVisitor::EnqueueChildren(const AnnotateAttr
*A
) {
2943 unsigned size
= WL
.size();
2944 for (const Expr
*Arg
: A
->args()) {
2947 if (size
== WL
.size())
2949 // Now reverse the entries we just added. This will match the DFS
2950 // ordering performed by the worklist.
2951 VisitorWorkList::iterator I
= WL
.begin() + size
, E
= WL
.end();
2955 void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr
*E
) {
2956 WL
.push_back(LabelRefVisit(E
->getLabel(), E
->getLabelLoc(), Parent
));
2958 void EnqueueVisitor::VisitBlockExpr(const BlockExpr
*B
) {
2959 AddDecl(B
->getBlockDecl());
2961 void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr
*E
) {
2963 AddTypeLoc(E
->getTypeSourceInfo());
2965 void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt
*S
) {
2966 for (auto &I
: llvm::reverse(S
->body()))
2969 void EnqueueVisitor::VisitMSDependentExistsStmt(
2970 const MSDependentExistsStmt
*S
) {
2971 AddStmt(S
->getSubStmt());
2972 AddDeclarationNameInfo(S
);
2973 if (NestedNameSpecifierLoc QualifierLoc
= S
->getQualifierLoc())
2974 AddNestedNameSpecifierLoc(QualifierLoc
);
2977 void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2978 const CXXDependentScopeMemberExpr
*E
) {
2979 if (E
->hasExplicitTemplateArgs())
2980 AddExplicitTemplateArgs(E
->getTemplateArgs(), E
->getNumTemplateArgs());
2981 AddDeclarationNameInfo(E
);
2982 if (NestedNameSpecifierLoc QualifierLoc
= E
->getQualifierLoc())
2983 AddNestedNameSpecifierLoc(QualifierLoc
);
2984 if (!E
->isImplicitAccess())
2985 AddStmt(E
->getBase());
2987 void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr
*E
) {
2988 // Enqueue the initializer , if any.
2989 AddStmt(E
->getInitializer());
2990 // Enqueue the array size, if any.
2991 AddStmt(E
->getArraySize().value_or(nullptr));
2992 // Enqueue the allocated type.
2993 AddTypeLoc(E
->getAllocatedTypeSourceInfo());
2994 // Enqueue the placement arguments.
2995 for (unsigned I
= E
->getNumPlacementArgs(); I
> 0; --I
)
2996 AddStmt(E
->getPlacementArg(I
- 1));
2998 void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr
*CE
) {
2999 for (unsigned I
= CE
->getNumArgs(); I
> 1 /* Yes, this is 1 */; --I
)
3000 AddStmt(CE
->getArg(I
- 1));
3001 AddStmt(CE
->getCallee());
3002 AddStmt(CE
->getArg(0));
3004 void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
3005 const CXXPseudoDestructorExpr
*E
) {
3006 // Visit the name of the type being destroyed.
3007 AddTypeLoc(E
->getDestroyedTypeInfo());
3008 // Visit the scope type that looks disturbingly like the nested-name-specifier
3010 AddTypeLoc(E
->getScopeTypeInfo());
3011 // Visit the nested-name-specifier.
3012 if (NestedNameSpecifierLoc QualifierLoc
= E
->getQualifierLoc())
3013 AddNestedNameSpecifierLoc(QualifierLoc
);
3014 // Visit base expression.
3015 AddStmt(E
->getBase());
3017 void EnqueueVisitor::VisitCXXScalarValueInitExpr(
3018 const CXXScalarValueInitExpr
*E
) {
3019 AddTypeLoc(E
->getTypeSourceInfo());
3021 void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
3022 const CXXTemporaryObjectExpr
*E
) {
3024 AddTypeLoc(E
->getTypeSourceInfo());
3026 void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr
*E
) {
3028 if (E
->isTypeOperand())
3029 AddTypeLoc(E
->getTypeOperandSourceInfo());
3032 void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
3033 const CXXUnresolvedConstructExpr
*E
) {
3035 AddTypeLoc(E
->getTypeSourceInfo());
3037 void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr
*E
) {
3039 if (E
->isTypeOperand())
3040 AddTypeLoc(E
->getTypeOperandSourceInfo());
3043 void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt
*S
) {
3045 AddDecl(S
->getExceptionDecl());
3048 void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt
*S
) {
3049 AddStmt(S
->getBody());
3050 AddStmt(S
->getRangeInit());
3051 AddDecl(S
->getLoopVariable());
3054 void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr
*DR
) {
3055 if (DR
->hasExplicitTemplateArgs())
3056 AddExplicitTemplateArgs(DR
->getTemplateArgs(), DR
->getNumTemplateArgs());
3057 WL
.push_back(DeclRefExprParts(DR
, Parent
));
3059 void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
3060 const DependentScopeDeclRefExpr
*E
) {
3061 if (E
->hasExplicitTemplateArgs())
3062 AddExplicitTemplateArgs(E
->getTemplateArgs(), E
->getNumTemplateArgs());
3063 AddDeclarationNameInfo(E
);
3064 AddNestedNameSpecifierLoc(E
->getQualifierLoc());
3066 void EnqueueVisitor::VisitDeclStmt(const DeclStmt
*S
) {
3067 unsigned size
= WL
.size();
3068 bool isFirst
= true;
3069 for (const auto *D
: S
->decls()) {
3070 AddDecl(D
, isFirst
);
3073 if (size
== WL
.size())
3075 // Now reverse the entries we just added. This will match the DFS
3076 // ordering performed by the worklist.
3077 VisitorWorkList::iterator I
= WL
.begin() + size
, E
= WL
.end();
3080 void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr
*E
) {
3081 AddStmt(E
->getInit());
3082 for (const DesignatedInitExpr::Designator
&D
:
3083 llvm::reverse(E
->designators())) {
3084 if (D
.isFieldDesignator()) {
3085 if (const FieldDecl
*Field
= D
.getFieldDecl())
3086 AddMemberRef(Field
, D
.getFieldLoc());
3089 if (D
.isArrayDesignator()) {
3090 AddStmt(E
->getArrayIndex(D
));
3093 assert(D
.isArrayRangeDesignator() && "Unknown designator kind");
3094 AddStmt(E
->getArrayRangeEnd(D
));
3095 AddStmt(E
->getArrayRangeStart(D
));
3098 void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr
*E
) {
3100 AddTypeLoc(E
->getTypeInfoAsWritten());
3102 void EnqueueVisitor::VisitForStmt(const ForStmt
*FS
) {
3103 AddStmt(FS
->getBody());
3104 AddStmt(FS
->getInc());
3105 AddStmt(FS
->getCond());
3106 AddDecl(FS
->getConditionVariable());
3107 AddStmt(FS
->getInit());
3109 void EnqueueVisitor::VisitGotoStmt(const GotoStmt
*GS
) {
3110 WL
.push_back(LabelRefVisit(GS
->getLabel(), GS
->getLabelLoc(), Parent
));
3112 void EnqueueVisitor::VisitIfStmt(const IfStmt
*If
) {
3113 AddStmt(If
->getElse());
3114 AddStmt(If
->getThen());
3115 AddStmt(If
->getCond());
3116 AddStmt(If
->getInit());
3117 AddDecl(If
->getConditionVariable());
3119 void EnqueueVisitor::VisitInitListExpr(const InitListExpr
*IE
) {
3120 // We care about the syntactic form of the initializer list, only.
3121 if (InitListExpr
*Syntactic
= IE
->getSyntacticForm())
3123 EnqueueChildren(IE
);
3125 void EnqueueVisitor::VisitMemberExpr(const MemberExpr
*M
) {
3126 WL
.push_back(MemberExprParts(M
, Parent
));
3128 // If the base of the member access expression is an implicit 'this', don't
3130 // FIXME: If we ever want to show these implicit accesses, this will be
3131 // unfortunate. However, clang_getCursor() relies on this behavior.
3132 if (M
->isImplicitAccess())
3135 // Ignore base anonymous struct/union fields, otherwise they will shadow the
3136 // real field that we are interested in.
3137 if (auto *SubME
= dyn_cast
<MemberExpr
>(M
->getBase())) {
3138 if (auto *FD
= dyn_cast_or_null
<FieldDecl
>(SubME
->getMemberDecl())) {
3139 if (FD
->isAnonymousStructOrUnion()) {
3140 AddStmt(SubME
->getBase());
3146 AddStmt(M
->getBase());
3148 void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr
*E
) {
3149 AddTypeLoc(E
->getEncodedTypeSourceInfo());
3151 void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr
*M
) {
3153 AddTypeLoc(M
->getClassReceiverTypeInfo());
3155 void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr
*E
) {
3156 // Visit the components of the offsetof expression.
3157 for (unsigned N
= E
->getNumComponents(), I
= N
; I
> 0; --I
) {
3158 const OffsetOfNode
&Node
= E
->getComponent(I
- 1);
3159 switch (Node
.getKind()) {
3160 case OffsetOfNode::Array
:
3161 AddStmt(E
->getIndexExpr(Node
.getArrayExprIndex()));
3163 case OffsetOfNode::Field
:
3164 AddMemberRef(Node
.getField(), Node
.getSourceRange().getEnd());
3166 case OffsetOfNode::Identifier
:
3167 case OffsetOfNode::Base
:
3171 // Visit the type into which we're computing the offset.
3172 AddTypeLoc(E
->getTypeSourceInfo());
3174 void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr
*E
) {
3175 if (E
->hasExplicitTemplateArgs())
3176 AddExplicitTemplateArgs(E
->getTemplateArgs(), E
->getNumTemplateArgs());
3177 WL
.push_back(OverloadExprParts(E
, Parent
));
3179 void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
3180 const UnaryExprOrTypeTraitExpr
*E
) {
3182 if (E
->isArgumentType())
3183 AddTypeLoc(E
->getArgumentTypeInfo());
3185 void EnqueueVisitor::VisitStmt(const Stmt
*S
) { EnqueueChildren(S
); }
3186 void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt
*S
) {
3187 AddStmt(S
->getBody());
3188 AddStmt(S
->getCond());
3189 AddDecl(S
->getConditionVariable());
3192 void EnqueueVisitor::VisitWhileStmt(const WhileStmt
*W
) {
3193 AddStmt(W
->getBody());
3194 AddStmt(W
->getCond());
3195 AddDecl(W
->getConditionVariable());
3198 void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr
*E
) {
3199 for (unsigned I
= E
->getNumArgs(); I
> 0; --I
)
3200 AddTypeLoc(E
->getArg(I
- 1));
3203 void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr
*E
) {
3204 AddTypeLoc(E
->getQueriedTypeSourceInfo());
3207 void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr
*E
) {
3211 void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr
*U
) {
3212 VisitOverloadExpr(U
);
3213 if (!U
->isImplicitAccess())
3214 AddStmt(U
->getBase());
3216 void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr
*E
) {
3217 AddStmt(E
->getSubExpr());
3218 AddTypeLoc(E
->getWrittenTypeInfo());
3220 void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr
*E
) {
3221 WL
.push_back(SizeOfPackExprParts(E
, Parent
));
3223 void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr
*E
) {
3224 // If the opaque value has a source expression, just transparently
3225 // visit that. This is useful for (e.g.) pseudo-object expressions.
3226 if (Expr
*SourceExpr
= E
->getSourceExpr())
3227 return ConstStmtVisitor::Visit(SourceExpr
);
3229 void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr
*E
) {
3230 AddStmt(E
->getBody());
3231 WL
.push_back(LambdaExprParts(E
, Parent
));
3233 void EnqueueVisitor::VisitConceptSpecializationExpr(
3234 const ConceptSpecializationExpr
*E
) {
3235 WL
.push_back(ConceptSpecializationExprVisit(E
, Parent
));
3237 void EnqueueVisitor::VisitRequiresExpr(const RequiresExpr
*E
) {
3238 WL
.push_back(RequiresExprVisit(E
, Parent
));
3239 for (ParmVarDecl
*VD
: E
->getLocalParameters())
3242 void EnqueueVisitor::VisitCXXParenListInitExpr(const CXXParenListInitExpr
*E
) {
3245 void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr
*E
) {
3246 // Treat the expression like its syntactic form.
3247 ConstStmtVisitor::Visit(E
->getSyntacticForm());
3250 void EnqueueVisitor::VisitOMPExecutableDirective(
3251 const OMPExecutableDirective
*D
) {
3253 for (ArrayRef
<OMPClause
*>::iterator I
= D
->clauses().begin(),
3254 E
= D
->clauses().end();
3256 EnqueueChildren(*I
);
3259 void EnqueueVisitor::VisitOMPLoopBasedDirective(
3260 const OMPLoopBasedDirective
*D
) {
3261 VisitOMPExecutableDirective(D
);
3264 void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective
*D
) {
3265 VisitOMPLoopBasedDirective(D
);
3268 void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective
*D
) {
3269 VisitOMPExecutableDirective(D
);
3272 void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective
*D
) {
3273 VisitOMPLoopDirective(D
);
3276 void EnqueueVisitor::VisitOMPLoopTransformationDirective(
3277 const OMPLoopTransformationDirective
*D
) {
3278 VisitOMPLoopBasedDirective(D
);
3281 void EnqueueVisitor::VisitOMPTileDirective(const OMPTileDirective
*D
) {
3282 VisitOMPLoopTransformationDirective(D
);
3285 void EnqueueVisitor::VisitOMPUnrollDirective(const OMPUnrollDirective
*D
) {
3286 VisitOMPLoopTransformationDirective(D
);
3289 void EnqueueVisitor::VisitOMPReverseDirective(const OMPReverseDirective
*D
) {
3290 VisitOMPLoopTransformationDirective(D
);
3293 void EnqueueVisitor::VisitOMPInterchangeDirective(
3294 const OMPInterchangeDirective
*D
) {
3295 VisitOMPLoopTransformationDirective(D
);
3298 void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective
*D
) {
3299 VisitOMPLoopDirective(D
);
3302 void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective
*D
) {
3303 VisitOMPLoopDirective(D
);
3306 void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective
*D
) {
3307 VisitOMPExecutableDirective(D
);
3310 void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective
*D
) {
3311 VisitOMPExecutableDirective(D
);
3314 void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective
*D
) {
3315 VisitOMPExecutableDirective(D
);
3318 void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective
*D
) {
3319 VisitOMPExecutableDirective(D
);
3322 void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective
*D
) {
3323 VisitOMPExecutableDirective(D
);
3324 AddDeclarationNameInfo(D
);
3327 void EnqueueVisitor::VisitOMPParallelForDirective(
3328 const OMPParallelForDirective
*D
) {
3329 VisitOMPLoopDirective(D
);
3332 void EnqueueVisitor::VisitOMPParallelForSimdDirective(
3333 const OMPParallelForSimdDirective
*D
) {
3334 VisitOMPLoopDirective(D
);
3337 void EnqueueVisitor::VisitOMPParallelMasterDirective(
3338 const OMPParallelMasterDirective
*D
) {
3339 VisitOMPExecutableDirective(D
);
3342 void EnqueueVisitor::VisitOMPParallelMaskedDirective(
3343 const OMPParallelMaskedDirective
*D
) {
3344 VisitOMPExecutableDirective(D
);
3347 void EnqueueVisitor::VisitOMPParallelSectionsDirective(
3348 const OMPParallelSectionsDirective
*D
) {
3349 VisitOMPExecutableDirective(D
);
3352 void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective
*D
) {
3353 VisitOMPExecutableDirective(D
);
3356 void EnqueueVisitor::VisitOMPTaskyieldDirective(
3357 const OMPTaskyieldDirective
*D
) {
3358 VisitOMPExecutableDirective(D
);
3361 void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective
*D
) {
3362 VisitOMPExecutableDirective(D
);
3365 void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective
*D
) {
3366 VisitOMPExecutableDirective(D
);
3369 void EnqueueVisitor::VisitOMPAssumeDirective(const OMPAssumeDirective
*D
) {
3370 VisitOMPExecutableDirective(D
);
3373 void EnqueueVisitor::VisitOMPErrorDirective(const OMPErrorDirective
*D
) {
3374 VisitOMPExecutableDirective(D
);
3377 void EnqueueVisitor::VisitOMPTaskgroupDirective(
3378 const OMPTaskgroupDirective
*D
) {
3379 VisitOMPExecutableDirective(D
);
3380 if (const Expr
*E
= D
->getReductionRef())
3384 void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective
*D
) {
3385 VisitOMPExecutableDirective(D
);
3388 void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective
*D
) {
3389 VisitOMPExecutableDirective(D
);
3392 void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective
*D
) {
3393 VisitOMPExecutableDirective(D
);
3396 void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective
*D
) {
3397 VisitOMPExecutableDirective(D
);
3400 void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective
*D
) {
3401 VisitOMPExecutableDirective(D
);
3404 void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective
*D
) {
3405 VisitOMPExecutableDirective(D
);
3408 void EnqueueVisitor::VisitOMPTargetDataDirective(
3409 const OMPTargetDataDirective
*D
) {
3410 VisitOMPExecutableDirective(D
);
3413 void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
3414 const OMPTargetEnterDataDirective
*D
) {
3415 VisitOMPExecutableDirective(D
);
3418 void EnqueueVisitor::VisitOMPTargetExitDataDirective(
3419 const OMPTargetExitDataDirective
*D
) {
3420 VisitOMPExecutableDirective(D
);
3423 void EnqueueVisitor::VisitOMPTargetParallelDirective(
3424 const OMPTargetParallelDirective
*D
) {
3425 VisitOMPExecutableDirective(D
);
3428 void EnqueueVisitor::VisitOMPTargetParallelForDirective(
3429 const OMPTargetParallelForDirective
*D
) {
3430 VisitOMPLoopDirective(D
);
3433 void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective
*D
) {
3434 VisitOMPExecutableDirective(D
);
3437 void EnqueueVisitor::VisitOMPCancellationPointDirective(
3438 const OMPCancellationPointDirective
*D
) {
3439 VisitOMPExecutableDirective(D
);
3442 void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective
*D
) {
3443 VisitOMPExecutableDirective(D
);
3446 void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective
*D
) {
3447 VisitOMPLoopDirective(D
);
3450 void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
3451 const OMPTaskLoopSimdDirective
*D
) {
3452 VisitOMPLoopDirective(D
);
3455 void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
3456 const OMPMasterTaskLoopDirective
*D
) {
3457 VisitOMPLoopDirective(D
);
3460 void EnqueueVisitor::VisitOMPMaskedTaskLoopDirective(
3461 const OMPMaskedTaskLoopDirective
*D
) {
3462 VisitOMPLoopDirective(D
);
3465 void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
3466 const OMPMasterTaskLoopSimdDirective
*D
) {
3467 VisitOMPLoopDirective(D
);
3470 void EnqueueVisitor::VisitOMPMaskedTaskLoopSimdDirective(
3471 const OMPMaskedTaskLoopSimdDirective
*D
) {
3472 VisitOMPLoopDirective(D
);
3475 void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
3476 const OMPParallelMasterTaskLoopDirective
*D
) {
3477 VisitOMPLoopDirective(D
);
3480 void EnqueueVisitor::VisitOMPParallelMaskedTaskLoopDirective(
3481 const OMPParallelMaskedTaskLoopDirective
*D
) {
3482 VisitOMPLoopDirective(D
);
3485 void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
3486 const OMPParallelMasterTaskLoopSimdDirective
*D
) {
3487 VisitOMPLoopDirective(D
);
3490 void EnqueueVisitor::VisitOMPParallelMaskedTaskLoopSimdDirective(
3491 const OMPParallelMaskedTaskLoopSimdDirective
*D
) {
3492 VisitOMPLoopDirective(D
);
3495 void EnqueueVisitor::VisitOMPDistributeDirective(
3496 const OMPDistributeDirective
*D
) {
3497 VisitOMPLoopDirective(D
);
3500 void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
3501 const OMPDistributeParallelForDirective
*D
) {
3502 VisitOMPLoopDirective(D
);
3505 void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
3506 const OMPDistributeParallelForSimdDirective
*D
) {
3507 VisitOMPLoopDirective(D
);
3510 void EnqueueVisitor::VisitOMPDistributeSimdDirective(
3511 const OMPDistributeSimdDirective
*D
) {
3512 VisitOMPLoopDirective(D
);
3515 void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
3516 const OMPTargetParallelForSimdDirective
*D
) {
3517 VisitOMPLoopDirective(D
);
3520 void EnqueueVisitor::VisitOMPTargetSimdDirective(
3521 const OMPTargetSimdDirective
*D
) {
3522 VisitOMPLoopDirective(D
);
3525 void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3526 const OMPTeamsDistributeDirective
*D
) {
3527 VisitOMPLoopDirective(D
);
3530 void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3531 const OMPTeamsDistributeSimdDirective
*D
) {
3532 VisitOMPLoopDirective(D
);
3535 void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3536 const OMPTeamsDistributeParallelForSimdDirective
*D
) {
3537 VisitOMPLoopDirective(D
);
3540 void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3541 const OMPTeamsDistributeParallelForDirective
*D
) {
3542 VisitOMPLoopDirective(D
);
3545 void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3546 const OMPTargetTeamsDirective
*D
) {
3547 VisitOMPExecutableDirective(D
);
3550 void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3551 const OMPTargetTeamsDistributeDirective
*D
) {
3552 VisitOMPLoopDirective(D
);
3555 void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3556 const OMPTargetTeamsDistributeParallelForDirective
*D
) {
3557 VisitOMPLoopDirective(D
);
3560 void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3561 const OMPTargetTeamsDistributeParallelForSimdDirective
*D
) {
3562 VisitOMPLoopDirective(D
);
3565 void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3566 const OMPTargetTeamsDistributeSimdDirective
*D
) {
3567 VisitOMPLoopDirective(D
);
3570 void EnqueueVisitor::VisitOpenACCComputeConstruct(
3571 const OpenACCComputeConstruct
*C
) {
3573 for (auto *Clause
: C
->clauses())
3574 EnqueueChildren(Clause
);
3577 void EnqueueVisitor::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct
*C
) {
3579 for (auto *Clause
: C
->clauses())
3580 EnqueueChildren(Clause
);
3583 void EnqueueVisitor::VisitOpenACCCombinedConstruct(
3584 const OpenACCCombinedConstruct
*C
) {
3586 for (auto *Clause
: C
->clauses())
3587 EnqueueChildren(Clause
);
3590 void EnqueueVisitor::VisitAnnotateAttr(const AnnotateAttr
*A
) {
3594 void CursorVisitor::EnqueueWorkList(VisitorWorkList
&WL
, const Stmt
*S
) {
3595 EnqueueVisitor(WL
, MakeCXCursor(S
, StmtParent
, TU
, RegionOfInterest
))
3596 .ConstStmtVisitor::Visit(S
);
3599 void CursorVisitor::EnqueueWorkList(VisitorWorkList
&WL
, const Attr
*A
) {
3600 // Parent is the attribute itself when this is indirectly called from
3601 // VisitChildren. Because we need to make a CXCursor for A, we need *its*
3603 auto AttrCursor
= Parent
;
3605 // Get the attribute's parent as stored in
3606 // cxcursor::MakeCXCursor(const Attr *A, const Decl *Parent, CXTranslationUnit
3608 const Decl
*AttrParent
= static_cast<const Decl
*>(AttrCursor
.data
[1]);
3610 EnqueueVisitor(WL
, MakeCXCursor(A
, AttrParent
, TU
))
3611 .ConstAttrVisitor::Visit(A
);
3614 bool CursorVisitor::IsInRegionOfInterest(CXCursor C
) {
3615 if (RegionOfInterest
.isValid()) {
3616 SourceRange Range
= getRawCursorExtent(C
);
3617 if (Range
.isInvalid() || CompareRegionOfInterest(Range
))
3623 bool CursorVisitor::RunVisitorWorkList(VisitorWorkList
&WL
) {
3624 while (!WL
.empty()) {
3625 // Dequeue the worklist item.
3626 VisitorJob LI
= WL
.pop_back_val();
3628 // Set the Parent field, then back to its old value once we're done.
3629 SetParentRAII
SetParent(Parent
, StmtParent
, LI
.getParent());
3631 switch (LI
.getKind()) {
3632 case VisitorJob::DeclVisitKind
: {
3633 const Decl
*D
= cast
<DeclVisit
>(&LI
)->get();
3637 // For now, perform default visitation for Decls.
3638 if (Visit(MakeCXCursor(D
, TU
, RegionOfInterest
,
3639 cast
<DeclVisit
>(&LI
)->isFirst())))
3644 case VisitorJob::ExplicitTemplateArgsVisitKind
: {
3645 for (const TemplateArgumentLoc
&Arg
:
3646 *cast
<ExplicitTemplateArgsVisit
>(&LI
)) {
3647 if (VisitTemplateArgumentLoc(Arg
))
3652 case VisitorJob::TypeLocVisitKind
: {
3653 // Perform default visitation for TypeLocs.
3654 if (Visit(cast
<TypeLocVisit
>(&LI
)->get()))
3658 case VisitorJob::LabelRefVisitKind
: {
3659 const LabelDecl
*LS
= cast
<LabelRefVisit
>(&LI
)->get();
3660 if (LabelStmt
*stmt
= LS
->getStmt()) {
3661 if (Visit(MakeCursorLabelRef(stmt
, cast
<LabelRefVisit
>(&LI
)->getLoc(),
3669 case VisitorJob::NestedNameSpecifierLocVisitKind
: {
3670 NestedNameSpecifierLocVisit
*V
= cast
<NestedNameSpecifierLocVisit
>(&LI
);
3671 if (VisitNestedNameSpecifierLoc(V
->get()))
3676 case VisitorJob::DeclarationNameInfoVisitKind
: {
3677 if (VisitDeclarationNameInfo(cast
<DeclarationNameInfoVisit
>(&LI
)->get()))
3681 case VisitorJob::MemberRefVisitKind
: {
3682 MemberRefVisit
*V
= cast
<MemberRefVisit
>(&LI
);
3683 if (Visit(MakeCursorMemberRef(V
->get(), V
->getLoc(), TU
)))
3687 case VisitorJob::StmtVisitKind
: {
3688 const Stmt
*S
= cast
<StmtVisit
>(&LI
)->get();
3692 // Update the current cursor.
3693 CXCursor Cursor
= MakeCXCursor(S
, StmtParent
, TU
, RegionOfInterest
);
3694 if (!IsInRegionOfInterest(Cursor
))
3696 switch (Visitor(Cursor
, Parent
, ClientData
)) {
3697 case CXChildVisit_Break
:
3699 case CXChildVisit_Continue
:
3701 case CXChildVisit_Recurse
:
3702 if (PostChildrenVisitor
)
3703 WL
.push_back(PostChildrenVisit(nullptr, Cursor
));
3704 EnqueueWorkList(WL
, S
);
3709 case VisitorJob::MemberExprPartsKind
: {
3710 // Handle the other pieces in the MemberExpr besides the base.
3711 const MemberExpr
*M
= cast
<MemberExprParts
>(&LI
)->get();
3713 // Visit the nested-name-specifier
3714 if (NestedNameSpecifierLoc QualifierLoc
= M
->getQualifierLoc())
3715 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
3718 // Visit the declaration name.
3719 if (VisitDeclarationNameInfo(M
->getMemberNameInfo()))
3722 // Visit the explicitly-specified template arguments, if any.
3723 if (M
->hasExplicitTemplateArgs()) {
3724 for (const TemplateArgumentLoc
*Arg
= M
->getTemplateArgs(),
3725 *ArgEnd
= Arg
+ M
->getNumTemplateArgs();
3726 Arg
!= ArgEnd
; ++Arg
) {
3727 if (VisitTemplateArgumentLoc(*Arg
))
3733 case VisitorJob::DeclRefExprPartsKind
: {
3734 const DeclRefExpr
*DR
= cast
<DeclRefExprParts
>(&LI
)->get();
3735 // Visit nested-name-specifier, if present.
3736 if (NestedNameSpecifierLoc QualifierLoc
= DR
->getQualifierLoc())
3737 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
3739 // Visit declaration name.
3740 if (VisitDeclarationNameInfo(DR
->getNameInfo()))
3744 case VisitorJob::OverloadExprPartsKind
: {
3745 const OverloadExpr
*O
= cast
<OverloadExprParts
>(&LI
)->get();
3746 // Visit the nested-name-specifier.
3747 if (NestedNameSpecifierLoc QualifierLoc
= O
->getQualifierLoc())
3748 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
3750 // Visit the declaration name.
3751 if (VisitDeclarationNameInfo(O
->getNameInfo()))
3753 // Visit the overloaded declaration reference.
3754 if (Visit(MakeCursorOverloadedDeclRef(O
, TU
)))
3758 case VisitorJob::SizeOfPackExprPartsKind
: {
3759 const SizeOfPackExpr
*E
= cast
<SizeOfPackExprParts
>(&LI
)->get();
3760 NamedDecl
*Pack
= E
->getPack();
3761 if (isa
<TemplateTypeParmDecl
>(Pack
)) {
3762 if (Visit(MakeCursorTypeRef(cast
<TemplateTypeParmDecl
>(Pack
),
3763 E
->getPackLoc(), TU
)))
3769 if (isa
<TemplateTemplateParmDecl
>(Pack
)) {
3770 if (Visit(MakeCursorTemplateRef(cast
<TemplateTemplateParmDecl
>(Pack
),
3771 E
->getPackLoc(), TU
)))
3777 // Non-type template parameter packs and function parameter packs are
3778 // treated like DeclRefExpr cursors.
3782 case VisitorJob::LambdaExprPartsKind
: {
3783 // Visit non-init captures.
3784 const LambdaExpr
*E
= cast
<LambdaExprParts
>(&LI
)->get();
3785 for (LambdaExpr::capture_iterator C
= E
->explicit_capture_begin(),
3786 CEnd
= E
->explicit_capture_end();
3788 if (!C
->capturesVariable())
3790 // TODO: handle structured bindings here ?
3791 if (!isa
<VarDecl
>(C
->getCapturedVar()))
3793 if (Visit(MakeCursorVariableRef(cast
<VarDecl
>(C
->getCapturedVar()),
3794 C
->getLocation(), TU
)))
3797 // Visit init captures
3798 for (auto InitExpr
: E
->capture_inits()) {
3799 if (InitExpr
&& Visit(InitExpr
))
3803 TypeLoc TL
= E
->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3804 // Visit parameters and return type, if present.
3805 if (FunctionTypeLoc Proto
= TL
.getAs
<FunctionProtoTypeLoc
>()) {
3806 if (E
->hasExplicitParameters()) {
3807 // Visit parameters.
3808 for (unsigned I
= 0, N
= Proto
.getNumParams(); I
!= N
; ++I
)
3809 if (Visit(MakeCXCursor(Proto
.getParam(I
), TU
)))
3812 if (E
->hasExplicitResultType()) {
3813 // Visit result type.
3814 if (Visit(Proto
.getReturnLoc()))
3821 case VisitorJob::ConceptSpecializationExprVisitKind
: {
3822 const ConceptSpecializationExpr
*E
=
3823 cast
<ConceptSpecializationExprVisit
>(&LI
)->get();
3824 if (NestedNameSpecifierLoc QualifierLoc
=
3825 E
->getNestedNameSpecifierLoc()) {
3826 if (VisitNestedNameSpecifierLoc(QualifierLoc
))
3830 if (E
->getNamedConcept() &&
3831 Visit(MakeCursorTemplateRef(E
->getNamedConcept(),
3832 E
->getConceptNameLoc(), TU
)))
3835 if (auto Args
= E
->getTemplateArgsAsWritten()) {
3836 for (const auto &Arg
: Args
->arguments()) {
3837 if (VisitTemplateArgumentLoc(Arg
))
3844 case VisitorJob::RequiresExprVisitKind
: {
3845 const RequiresExpr
*E
= cast
<RequiresExprVisit
>(&LI
)->get();
3846 for (const concepts::Requirement
*R
: E
->getRequirements())
3847 VisitConceptRequirement(*R
);
3851 case VisitorJob::PostChildrenVisitKind
:
3852 if (PostChildrenVisitor(Parent
, ClientData
))
3860 bool CursorVisitor::Visit(const Stmt
*S
) {
3861 VisitorWorkList
*WL
= nullptr;
3862 if (!WorkListFreeList
.empty()) {
3863 WL
= WorkListFreeList
.back();
3865 WorkListFreeList
.pop_back();
3867 WL
= new VisitorWorkList();
3868 WorkListCache
.push_back(WL
);
3870 EnqueueWorkList(*WL
, S
);
3871 bool result
= RunVisitorWorkList(*WL
);
3872 WorkListFreeList
.push_back(WL
);
3876 bool CursorVisitor::Visit(const Attr
*A
) {
3877 VisitorWorkList
*WL
= nullptr;
3878 if (!WorkListFreeList
.empty()) {
3879 WL
= WorkListFreeList
.back();
3881 WorkListFreeList
.pop_back();
3883 WL
= new VisitorWorkList();
3884 WorkListCache
.push_back(WL
);
3886 EnqueueWorkList(*WL
, A
);
3887 bool result
= RunVisitorWorkList(*WL
);
3888 WorkListFreeList
.push_back(WL
);
3893 typedef SmallVector
<SourceRange
, 4> RefNamePieces
;
3894 RefNamePieces
buildPieces(unsigned NameFlags
, bool IsMemberRefExpr
,
3895 const DeclarationNameInfo
&NI
, SourceRange QLoc
,
3896 const SourceRange
*TemplateArgsLoc
= nullptr) {
3897 const bool WantQualifier
= NameFlags
& CXNameRange_WantQualifier
;
3898 const bool WantTemplateArgs
= NameFlags
& CXNameRange_WantTemplateArgs
;
3899 const bool WantSinglePiece
= NameFlags
& CXNameRange_WantSinglePiece
;
3901 const DeclarationName::NameKind Kind
= NI
.getName().getNameKind();
3903 RefNamePieces Pieces
;
3905 if (WantQualifier
&& QLoc
.isValid())
3906 Pieces
.push_back(QLoc
);
3908 if (Kind
!= DeclarationName::CXXOperatorName
|| IsMemberRefExpr
)
3909 Pieces
.push_back(NI
.getLoc());
3911 if (WantTemplateArgs
&& TemplateArgsLoc
&& TemplateArgsLoc
->isValid())
3912 Pieces
.push_back(*TemplateArgsLoc
);
3914 if (Kind
== DeclarationName::CXXOperatorName
) {
3915 Pieces
.push_back(NI
.getInfo().getCXXOperatorNameBeginLoc());
3916 Pieces
.push_back(NI
.getInfo().getCXXOperatorNameEndLoc());
3919 if (WantSinglePiece
) {
3920 SourceRange
R(Pieces
.front().getBegin(), Pieces
.back().getEnd());
3922 Pieces
.push_back(R
);
3929 //===----------------------------------------------------------------------===//
3931 //===----------------------------------------------------------------------===//
3934 struct RegisterFatalErrorHandler
{
3935 RegisterFatalErrorHandler() {
3936 clang_install_aborting_llvm_fatal_error_handler();
3941 static llvm::ManagedStatic
<RegisterFatalErrorHandler
>
3942 RegisterFatalErrorHandlerOnce
;
3944 static CIndexer
*clang_createIndex_Impl(
3945 int excludeDeclarationsFromPCH
, int displayDiagnostics
,
3946 unsigned char threadBackgroundPriorityForIndexing
= CXChoice_Default
,
3947 unsigned char threadBackgroundPriorityForEditing
= CXChoice_Default
) {
3948 // We use crash recovery to make some of our APIs more reliable, implicitly
3950 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3951 llvm::CrashRecoveryContext::Enable();
3953 // Look through the managed static to trigger construction of the managed
3954 // static which registers our fatal error handler. This ensures it is only
3956 (void)*RegisterFatalErrorHandlerOnce
;
3958 // Initialize targets for clang module support.
3959 llvm::InitializeAllTargets();
3960 llvm::InitializeAllTargetMCs();
3961 llvm::InitializeAllAsmPrinters();
3962 llvm::InitializeAllAsmParsers();
3964 CIndexer
*CIdxr
= new CIndexer();
3966 if (excludeDeclarationsFromPCH
)
3967 CIdxr
->setOnlyLocalDecls();
3968 if (displayDiagnostics
)
3969 CIdxr
->setDisplayDiagnostics();
3971 unsigned GlobalOptions
= CIdxr
->getCXGlobalOptFlags();
3972 const auto updateGlobalOption
=
3973 [&GlobalOptions
](unsigned char Policy
, CXGlobalOptFlags Flag
,
3974 const char *EnvironmentVariableName
) {
3976 case CXChoice_Enabled
:
3977 GlobalOptions
|= Flag
;
3979 case CXChoice_Disabled
:
3980 GlobalOptions
&= ~Flag
;
3982 case CXChoice_Default
:
3983 default: // Fall back to default behavior if Policy is unsupported.
3984 if (getenv(EnvironmentVariableName
))
3985 GlobalOptions
|= Flag
;
3988 updateGlobalOption(threadBackgroundPriorityForIndexing
,
3989 CXGlobalOpt_ThreadBackgroundPriorityForIndexing
,
3990 "LIBCLANG_BGPRIO_INDEX");
3991 updateGlobalOption(threadBackgroundPriorityForEditing
,
3992 CXGlobalOpt_ThreadBackgroundPriorityForEditing
,
3993 "LIBCLANG_BGPRIO_EDIT");
3994 CIdxr
->setCXGlobalOptFlags(GlobalOptions
);
3999 CXIndex
clang_createIndex(int excludeDeclarationsFromPCH
,
4000 int displayDiagnostics
) {
4001 return clang_createIndex_Impl(excludeDeclarationsFromPCH
, displayDiagnostics
);
4004 void clang_disposeIndex(CXIndex CIdx
) {
4006 delete static_cast<CIndexer
*>(CIdx
);
4009 CXIndex
clang_createIndexWithOptions(const CXIndexOptions
*options
) {
4010 // Adding new options to struct CXIndexOptions:
4011 // 1. If no other new option has been added in the same libclang version,
4012 // sizeof(CXIndexOptions) must increase for versioning purposes.
4013 // 2. Options should be added at the end of the struct in order to seamlessly
4014 // support older struct versions. If options->Size < sizeof(CXIndexOptions),
4015 // don't attempt to read the missing options and rely on the default values of
4016 // recently added options being reasonable. For example:
4017 // if (options->Size >= offsetof(CXIndexOptions, RecentlyAddedMember))
4018 // do_something(options->RecentlyAddedMember);
4020 // An exception: if a new option is small enough, it can be squeezed into the
4021 // /*Reserved*/ bits in CXIndexOptions. Since the default value of each option
4022 // is guaranteed to be 0 and the callers are advised to zero out the struct,
4023 // programs built against older libclang versions would implicitly set the new
4024 // options to default values, which should keep the behavior of previous
4025 // libclang versions and thus be backward-compatible.
4027 // If options->Size > sizeof(CXIndexOptions), the user may have set an option
4028 // we can't handle, in which case we return nullptr to report failure.
4029 // Replace `!=` with `>` here to support older struct versions. `!=` has the
4030 // advantage of catching more usage bugs and no disadvantages while there is a
4031 // single supported struct version (the initial version).
4032 if (options
->Size
!= sizeof(CXIndexOptions
))
4034 CIndexer
*const CIdxr
= clang_createIndex_Impl(
4035 options
->ExcludeDeclarationsFromPCH
, options
->DisplayDiagnostics
,
4036 options
->ThreadBackgroundPriorityForIndexing
,
4037 options
->ThreadBackgroundPriorityForEditing
);
4038 CIdxr
->setStorePreamblesInMemory(options
->StorePreamblesInMemory
);
4039 CIdxr
->setPreambleStoragePath(options
->PreambleStoragePath
);
4040 CIdxr
->setInvocationEmissionPath(options
->InvocationEmissionPath
);
4044 void clang_CXIndex_setGlobalOptions(CXIndex CIdx
, unsigned options
) {
4046 static_cast<CIndexer
*>(CIdx
)->setCXGlobalOptFlags(options
);
4049 unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx
) {
4051 return static_cast<CIndexer
*>(CIdx
)->getCXGlobalOptFlags();
4055 void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx
,
4058 static_cast<CIndexer
*>(CIdx
)->setInvocationEmissionPath(Path
? Path
: "");
4061 void clang_toggleCrashRecovery(unsigned isEnabled
) {
4063 llvm::CrashRecoveryContext::Enable();
4065 llvm::CrashRecoveryContext::Disable();
4068 CXTranslationUnit
clang_createTranslationUnit(CXIndex CIdx
,
4069 const char *ast_filename
) {
4070 CXTranslationUnit TU
;
4071 enum CXErrorCode Result
=
4072 clang_createTranslationUnit2(CIdx
, ast_filename
, &TU
);
4074 assert((TU
&& Result
== CXError_Success
) ||
4075 (!TU
&& Result
!= CXError_Success
));
4079 enum CXErrorCode
clang_createTranslationUnit2(CXIndex CIdx
,
4080 const char *ast_filename
,
4081 CXTranslationUnit
*out_TU
) {
4085 if (!CIdx
|| !ast_filename
|| !out_TU
)
4086 return CXError_InvalidArguments
;
4088 LOG_FUNC_SECTION
{ *Log
<< ast_filename
; }
4090 CIndexer
*CXXIdx
= static_cast<CIndexer
*>(CIdx
);
4091 FileSystemOptions FileSystemOpts
;
4092 auto HSOpts
= std::make_shared
<HeaderSearchOptions
>();
4094 IntrusiveRefCntPtr
<DiagnosticsEngine
> Diags
=
4095 CompilerInstance::createDiagnostics(new DiagnosticOptions());
4096 std::unique_ptr
<ASTUnit
> AU
= ASTUnit::LoadFromASTFile(
4097 ast_filename
, CXXIdx
->getPCHContainerOperations()->getRawReader(),
4098 ASTUnit::LoadEverything
, Diags
, FileSystemOpts
, HSOpts
,
4099 /*LangOpts=*/nullptr, CXXIdx
->getOnlyLocalDecls(), CaptureDiagsKind::All
,
4100 /*AllowASTWithCompilerErrors=*/true,
4101 /*UserFilesAreVolatile=*/true);
4102 *out_TU
= MakeCXTranslationUnit(CXXIdx
, std::move(AU
));
4103 return *out_TU
? CXError_Success
: CXError_Failure
;
4106 unsigned clang_defaultEditingTranslationUnitOptions() {
4107 return CXTranslationUnit_PrecompiledPreamble
|
4108 CXTranslationUnit_CacheCompletionResults
;
4111 CXTranslationUnit
clang_createTranslationUnitFromSourceFile(
4112 CXIndex CIdx
, const char *source_filename
, int num_command_line_args
,
4113 const char *const *command_line_args
, unsigned num_unsaved_files
,
4114 struct CXUnsavedFile
*unsaved_files
) {
4115 unsigned Options
= CXTranslationUnit_DetailedPreprocessingRecord
;
4116 return clang_parseTranslationUnit(CIdx
, source_filename
, command_line_args
,
4117 num_command_line_args
, unsaved_files
,
4118 num_unsaved_files
, Options
);
4122 clang_parseTranslationUnit_Impl(CXIndex CIdx
, const char *source_filename
,
4123 const char *const *command_line_args
,
4124 int num_command_line_args
,
4125 ArrayRef
<CXUnsavedFile
> unsaved_files
,
4126 unsigned options
, CXTranslationUnit
*out_TU
) {
4127 // Set up the initial return values.
4132 if (!CIdx
|| !out_TU
)
4133 return CXError_InvalidArguments
;
4135 CIndexer
*CXXIdx
= static_cast<CIndexer
*>(CIdx
);
4137 if (CXXIdx
->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing
))
4138 setThreadBackgroundPriority();
4140 bool PrecompilePreamble
= options
& CXTranslationUnit_PrecompiledPreamble
;
4141 bool CreatePreambleOnFirstParse
=
4142 options
& CXTranslationUnit_CreatePreambleOnFirstParse
;
4143 // FIXME: Add a flag for modules.
4144 TranslationUnitKind TUKind
= (options
& (CXTranslationUnit_Incomplete
|
4145 CXTranslationUnit_SingleFileParse
))
4148 bool CacheCodeCompletionResults
=
4149 options
& CXTranslationUnit_CacheCompletionResults
;
4150 bool IncludeBriefCommentsInCodeCompletion
=
4151 options
& CXTranslationUnit_IncludeBriefCommentsInCodeCompletion
;
4152 bool SingleFileParse
= options
& CXTranslationUnit_SingleFileParse
;
4153 bool ForSerialization
= options
& CXTranslationUnit_ForSerialization
;
4154 bool RetainExcludedCB
=
4155 options
& CXTranslationUnit_RetainExcludedConditionalBlocks
;
4156 SkipFunctionBodiesScope SkipFunctionBodies
= SkipFunctionBodiesScope::None
;
4157 if (options
& CXTranslationUnit_SkipFunctionBodies
) {
4158 SkipFunctionBodies
=
4159 (options
& CXTranslationUnit_LimitSkipFunctionBodiesToPreamble
)
4160 ? SkipFunctionBodiesScope::Preamble
4161 : SkipFunctionBodiesScope::PreambleAndMainFile
;
4164 // Configure the diagnostics.
4165 std::unique_ptr
<DiagnosticOptions
> DiagOpts
= CreateAndPopulateDiagOpts(
4166 llvm::ArrayRef(command_line_args
, num_command_line_args
));
4167 IntrusiveRefCntPtr
<DiagnosticsEngine
> Diags(
4168 CompilerInstance::createDiagnostics(DiagOpts
.release()));
4170 if (options
& CXTranslationUnit_KeepGoing
)
4171 Diags
->setFatalsAsError(true);
4173 CaptureDiagsKind CaptureDiagnostics
= CaptureDiagsKind::All
;
4174 if (options
& CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles
)
4175 CaptureDiagnostics
= CaptureDiagsKind::AllWithoutNonErrorsFromIncludes
;
4177 // Recover resources if we crash before exiting this function.
4178 llvm::CrashRecoveryContextCleanupRegistrar
<
4180 llvm::CrashRecoveryContextReleaseRefCleanup
<DiagnosticsEngine
>>
4181 DiagCleanup(Diags
.get());
4183 std::unique_ptr
<std::vector
<ASTUnit::RemappedFile
>> RemappedFiles(
4184 new std::vector
<ASTUnit::RemappedFile
>());
4186 // Recover resources if we crash before exiting this function.
4187 llvm::CrashRecoveryContextCleanupRegistrar
<std::vector
<ASTUnit::RemappedFile
>>
4188 RemappedCleanup(RemappedFiles
.get());
4190 for (auto &UF
: unsaved_files
) {
4191 std::unique_ptr
<llvm::MemoryBuffer
> MB
=
4192 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF
), UF
.Filename
);
4193 RemappedFiles
->push_back(std::make_pair(UF
.Filename
, MB
.release()));
4196 std::unique_ptr
<std::vector
<const char *>> Args(
4197 new std::vector
<const char *>());
4199 // Recover resources if we crash before exiting this method.
4200 llvm::CrashRecoveryContextCleanupRegistrar
<std::vector
<const char *>>
4201 ArgsCleanup(Args
.get());
4203 // Since the Clang C library is primarily used by batch tools dealing with
4204 // (often very broken) source code, where spell-checking can have a
4205 // significant negative impact on performance (particularly when
4206 // precompiled headers are involved), we disable it by default.
4207 // Only do this if we haven't found a spell-checking-related argument.
4208 bool FoundSpellCheckingArgument
= false;
4209 for (int I
= 0; I
!= num_command_line_args
; ++I
) {
4210 if (strcmp(command_line_args
[I
], "-fno-spell-checking") == 0 ||
4211 strcmp(command_line_args
[I
], "-fspell-checking") == 0) {
4212 FoundSpellCheckingArgument
= true;
4216 Args
->insert(Args
->end(), command_line_args
,
4217 command_line_args
+ num_command_line_args
);
4219 if (!FoundSpellCheckingArgument
)
4220 Args
->insert(Args
->begin() + 1, "-fno-spell-checking");
4222 // The 'source_filename' argument is optional. If the caller does not
4223 // specify it then it is assumed that the source file is specified
4224 // in the actual argument list.
4225 // Put the source file after command_line_args otherwise if '-x' flag is
4226 // present it will be unused.
4227 if (source_filename
)
4228 Args
->push_back(source_filename
);
4230 // Do we need the detailed preprocessing record?
4231 if (options
& CXTranslationUnit_DetailedPreprocessingRecord
) {
4232 Args
->push_back("-Xclang");
4233 Args
->push_back("-detailed-preprocessing-record");
4236 // Suppress any editor placeholder diagnostics.
4237 Args
->push_back("-fallow-editor-placeholders");
4239 unsigned NumErrors
= Diags
->getClient()->getNumErrors();
4240 std::unique_ptr
<ASTUnit
> ErrUnit
;
4241 // Unless the user specified that they want the preamble on the first parse
4242 // set it up to be created on the first reparse. This makes the first parse
4243 // faster, trading for a slower (first) reparse.
4244 unsigned PrecompilePreambleAfterNParses
=
4245 !PrecompilePreamble
? 0 : 2 - CreatePreambleOnFirstParse
;
4247 LibclangInvocationReporter
InvocationReporter(
4248 *CXXIdx
, LibclangInvocationReporter::OperationKind::ParseOperation
,
4249 options
, llvm::ArrayRef(*Args
), /*InvocationArgs=*/{}, unsaved_files
);
4250 std::unique_ptr
<ASTUnit
> Unit
= ASTUnit::LoadFromCommandLine(
4251 Args
->data(), Args
->data() + Args
->size(),
4252 CXXIdx
->getPCHContainerOperations(), Diags
,
4253 CXXIdx
->getClangResourcesPath(), CXXIdx
->getStorePreamblesInMemory(),
4254 CXXIdx
->getPreambleStoragePath(), CXXIdx
->getOnlyLocalDecls(),
4255 CaptureDiagnostics
, *RemappedFiles
.get(),
4256 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses
,
4257 TUKind
, CacheCodeCompletionResults
, IncludeBriefCommentsInCodeCompletion
,
4258 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies
, SingleFileParse
,
4259 /*UserFilesAreVolatile=*/true, ForSerialization
, RetainExcludedCB
,
4260 CXXIdx
->getPCHContainerOperations()->getRawReader().getFormats().front(),
4263 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
4264 if (!Unit
&& !ErrUnit
)
4265 return CXError_ASTReadError
;
4267 if (NumErrors
!= Diags
->getClient()->getNumErrors()) {
4268 // Make sure to check that 'Unit' is non-NULL.
4269 if (CXXIdx
->getDisplayDiagnostics())
4270 printDiagsToStderr(Unit
? Unit
.get() : ErrUnit
.get());
4273 if (isASTReadError(Unit
? Unit
.get() : ErrUnit
.get()))
4274 return CXError_ASTReadError
;
4276 *out_TU
= MakeCXTranslationUnit(CXXIdx
, std::move(Unit
));
4277 if (CXTranslationUnitImpl
*TU
= *out_TU
) {
4278 TU
->ParsingOptions
= options
;
4279 TU
->Arguments
.reserve(Args
->size());
4280 for (const char *Arg
: *Args
)
4281 TU
->Arguments
.push_back(Arg
);
4282 return CXError_Success
;
4284 return CXError_Failure
;
4288 clang_parseTranslationUnit(CXIndex CIdx
, const char *source_filename
,
4289 const char *const *command_line_args
,
4290 int num_command_line_args
,
4291 struct CXUnsavedFile
*unsaved_files
,
4292 unsigned num_unsaved_files
, unsigned options
) {
4293 CXTranslationUnit TU
;
4294 enum CXErrorCode Result
= clang_parseTranslationUnit2(
4295 CIdx
, source_filename
, command_line_args
, num_command_line_args
,
4296 unsaved_files
, num_unsaved_files
, options
, &TU
);
4298 assert((TU
&& Result
== CXError_Success
) ||
4299 (!TU
&& Result
!= CXError_Success
));
4303 enum CXErrorCode
clang_parseTranslationUnit2(
4304 CXIndex CIdx
, const char *source_filename
,
4305 const char *const *command_line_args
, int num_command_line_args
,
4306 struct CXUnsavedFile
*unsaved_files
, unsigned num_unsaved_files
,
4307 unsigned options
, CXTranslationUnit
*out_TU
) {
4308 noteBottomOfStack();
4309 SmallVector
<const char *, 4> Args
;
4310 Args
.push_back("clang");
4311 Args
.append(command_line_args
, command_line_args
+ num_command_line_args
);
4312 return clang_parseTranslationUnit2FullArgv(
4313 CIdx
, source_filename
, Args
.data(), Args
.size(), unsaved_files
,
4314 num_unsaved_files
, options
, out_TU
);
4317 enum CXErrorCode
clang_parseTranslationUnit2FullArgv(
4318 CXIndex CIdx
, const char *source_filename
,
4319 const char *const *command_line_args
, int num_command_line_args
,
4320 struct CXUnsavedFile
*unsaved_files
, unsigned num_unsaved_files
,
4321 unsigned options
, CXTranslationUnit
*out_TU
) {
4323 *Log
<< source_filename
<< ": ";
4324 for (int i
= 0; i
!= num_command_line_args
; ++i
)
4325 *Log
<< command_line_args
[i
] << " ";
4328 if (num_unsaved_files
&& !unsaved_files
)
4329 return CXError_InvalidArguments
;
4331 CXErrorCode result
= CXError_Failure
;
4332 auto ParseTranslationUnitImpl
= [=, &result
] {
4333 noteBottomOfStack();
4334 result
= clang_parseTranslationUnit_Impl(
4335 CIdx
, source_filename
, command_line_args
, num_command_line_args
,
4336 llvm::ArrayRef(unsaved_files
, num_unsaved_files
), options
, out_TU
);
4339 llvm::CrashRecoveryContext CRC
;
4341 if (!RunSafely(CRC
, ParseTranslationUnitImpl
)) {
4342 fprintf(stderr
, "libclang: crash detected during parsing: {\n");
4343 fprintf(stderr
, " 'source_filename' : '%s'\n", source_filename
);
4344 fprintf(stderr
, " 'command_line_args' : [");
4345 for (int i
= 0; i
!= num_command_line_args
; ++i
) {
4347 fprintf(stderr
, ", ");
4348 fprintf(stderr
, "'%s'", command_line_args
[i
]);
4350 fprintf(stderr
, "],\n");
4351 fprintf(stderr
, " 'unsaved_files' : [");
4352 for (unsigned i
= 0; i
!= num_unsaved_files
; ++i
) {
4354 fprintf(stderr
, ", ");
4355 fprintf(stderr
, "('%s', '...', %ld)", unsaved_files
[i
].Filename
,
4356 unsaved_files
[i
].Length
);
4358 fprintf(stderr
, "],\n");
4359 fprintf(stderr
, " 'options' : %d,\n", options
);
4360 fprintf(stderr
, "}\n");
4362 return CXError_Crashed
;
4363 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4364 if (CXTranslationUnit
*TU
= out_TU
)
4365 PrintLibclangResourceUsage(*TU
);
4371 CXString
clang_Type_getObjCEncoding(CXType CT
) {
4372 CXTranslationUnit tu
= static_cast<CXTranslationUnit
>(CT
.data
[1]);
4373 ASTContext
&Ctx
= getASTUnit(tu
)->getASTContext();
4374 std::string encoding
;
4375 Ctx
.getObjCEncodingForType(QualType::getFromOpaquePtr(CT
.data
[0]), encoding
);
4377 return cxstring::createDup(encoding
);
4380 static const IdentifierInfo
*getMacroIdentifier(CXCursor C
) {
4381 if (C
.kind
== CXCursor_MacroDefinition
) {
4382 if (const MacroDefinitionRecord
*MDR
= getCursorMacroDefinition(C
))
4383 return MDR
->getName();
4384 } else if (C
.kind
== CXCursor_MacroExpansion
) {
4385 MacroExpansionCursor ME
= getCursorMacroExpansion(C
);
4386 return ME
.getName();
4391 unsigned clang_Cursor_isMacroFunctionLike(CXCursor C
) {
4392 const IdentifierInfo
*II
= getMacroIdentifier(C
);
4396 ASTUnit
*ASTU
= getCursorASTUnit(C
);
4397 Preprocessor
&PP
= ASTU
->getPreprocessor();
4398 if (const MacroInfo
*MI
= PP
.getMacroInfo(II
))
4399 return MI
->isFunctionLike();
4403 unsigned clang_Cursor_isMacroBuiltin(CXCursor C
) {
4404 const IdentifierInfo
*II
= getMacroIdentifier(C
);
4408 ASTUnit
*ASTU
= getCursorASTUnit(C
);
4409 Preprocessor
&PP
= ASTU
->getPreprocessor();
4410 if (const MacroInfo
*MI
= PP
.getMacroInfo(II
))
4411 return MI
->isBuiltinMacro();
4415 unsigned clang_Cursor_isFunctionInlined(CXCursor C
) {
4416 const Decl
*D
= getCursorDecl(C
);
4417 const FunctionDecl
*FD
= dyn_cast_or_null
<FunctionDecl
>(D
);
4421 return FD
->isInlined();
4424 static StringLiteral
*getCFSTR_value(CallExpr
*callExpr
) {
4425 if (callExpr
->getNumArgs() != 1) {
4429 StringLiteral
*S
= nullptr;
4430 auto *arg
= callExpr
->getArg(0);
4431 if (arg
->getStmtClass() == Stmt::ImplicitCastExprClass
) {
4432 ImplicitCastExpr
*I
= static_cast<ImplicitCastExpr
*>(arg
);
4433 auto *subExpr
= I
->getSubExprAsWritten();
4435 if (subExpr
->getStmtClass() != Stmt::StringLiteralClass
) {
4439 S
= static_cast<StringLiteral
*>(I
->getSubExprAsWritten());
4440 } else if (arg
->getStmtClass() == Stmt::StringLiteralClass
) {
4441 S
= static_cast<StringLiteral
*>(callExpr
->getArg(0));
4448 struct ExprEvalResult
{
4449 CXEvalResultKind EvalType
;
4451 unsigned long long unsignedVal
;
4458 if (EvalType
!= CXEval_UnExposed
&& EvalType
!= CXEval_Float
&&
4459 EvalType
!= CXEval_Int
) {
4460 delete[] EvalData
.stringVal
;
4465 void clang_EvalResult_dispose(CXEvalResult E
) {
4466 delete static_cast<ExprEvalResult
*>(E
);
4469 CXEvalResultKind
clang_EvalResult_getKind(CXEvalResult E
) {
4471 return CXEval_UnExposed
;
4473 return ((ExprEvalResult
*)E
)->EvalType
;
4476 int clang_EvalResult_getAsInt(CXEvalResult E
) {
4477 return clang_EvalResult_getAsLongLong(E
);
4480 long long clang_EvalResult_getAsLongLong(CXEvalResult E
) {
4484 ExprEvalResult
*Result
= (ExprEvalResult
*)E
;
4485 if (Result
->IsUnsignedInt
)
4486 return Result
->EvalData
.unsignedVal
;
4487 return Result
->EvalData
.intVal
;
4490 unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E
) {
4491 return ((ExprEvalResult
*)E
)->IsUnsignedInt
;
4494 unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E
) {
4499 ExprEvalResult
*Result
= (ExprEvalResult
*)E
;
4500 if (Result
->IsUnsignedInt
)
4501 return Result
->EvalData
.unsignedVal
;
4502 return Result
->EvalData
.intVal
;
4505 double clang_EvalResult_getAsDouble(CXEvalResult E
) {
4509 return ((ExprEvalResult
*)E
)->EvalData
.floatVal
;
4512 const char *clang_EvalResult_getAsStr(CXEvalResult E
) {
4516 return ((ExprEvalResult
*)E
)->EvalData
.stringVal
;
4519 static const ExprEvalResult
*evaluateExpr(Expr
*expr
, CXCursor C
) {
4520 Expr::EvalResult ER
;
4521 ASTContext
&ctx
= getCursorContext(C
);
4525 expr
= expr
->IgnoreParens();
4526 if (expr
->isValueDependent())
4528 if (!expr
->EvaluateAsRValue(ER
, ctx
))
4533 auto result
= std::make_unique
<ExprEvalResult
>();
4534 result
->EvalType
= CXEval_UnExposed
;
4535 result
->IsUnsignedInt
= false;
4537 if (ER
.Val
.isInt()) {
4538 result
->EvalType
= CXEval_Int
;
4540 auto &val
= ER
.Val
.getInt();
4541 if (val
.isUnsigned()) {
4542 result
->IsUnsignedInt
= true;
4543 result
->EvalData
.unsignedVal
= val
.getZExtValue();
4545 result
->EvalData
.intVal
= val
.getExtValue();
4548 return result
.release();
4551 if (ER
.Val
.isFloat()) {
4552 llvm::SmallVector
<char, 100> Buffer
;
4553 ER
.Val
.getFloat().toString(Buffer
);
4554 std::string
floatStr(Buffer
.data(), Buffer
.size());
4555 result
->EvalType
= CXEval_Float
;
4557 llvm::APFloat apFloat
= ER
.Val
.getFloat();
4558 apFloat
.convert(llvm::APFloat::IEEEdouble(),
4559 llvm::APFloat::rmNearestTiesToEven
, &ignored
);
4560 result
->EvalData
.floatVal
= apFloat
.convertToDouble();
4561 return result
.release();
4564 if (expr
->getStmtClass() == Stmt::ImplicitCastExprClass
) {
4565 const auto *I
= cast
<ImplicitCastExpr
>(expr
);
4566 auto *subExpr
= I
->getSubExprAsWritten();
4567 if (subExpr
->getStmtClass() == Stmt::StringLiteralClass
||
4568 subExpr
->getStmtClass() == Stmt::ObjCStringLiteralClass
) {
4569 const StringLiteral
*StrE
= nullptr;
4570 const ObjCStringLiteral
*ObjCExpr
;
4571 ObjCExpr
= dyn_cast
<ObjCStringLiteral
>(subExpr
);
4574 StrE
= ObjCExpr
->getString();
4575 result
->EvalType
= CXEval_ObjCStrLiteral
;
4577 StrE
= cast
<StringLiteral
>(I
->getSubExprAsWritten());
4578 result
->EvalType
= CXEval_StrLiteral
;
4581 std::string
strRef(StrE
->getString().str());
4582 result
->EvalData
.stringVal
= new char[strRef
.size() + 1];
4583 strncpy((char *)result
->EvalData
.stringVal
, strRef
.c_str(),
4585 result
->EvalData
.stringVal
[strRef
.size()] = '\0';
4586 return result
.release();
4588 } else if (expr
->getStmtClass() == Stmt::ObjCStringLiteralClass
||
4589 expr
->getStmtClass() == Stmt::StringLiteralClass
) {
4590 const StringLiteral
*StrE
= nullptr;
4591 const ObjCStringLiteral
*ObjCExpr
;
4592 ObjCExpr
= dyn_cast
<ObjCStringLiteral
>(expr
);
4595 StrE
= ObjCExpr
->getString();
4596 result
->EvalType
= CXEval_ObjCStrLiteral
;
4598 StrE
= cast
<StringLiteral
>(expr
);
4599 result
->EvalType
= CXEval_StrLiteral
;
4602 std::string
strRef(StrE
->getString().str());
4603 result
->EvalData
.stringVal
= new char[strRef
.size() + 1];
4604 strncpy((char *)result
->EvalData
.stringVal
, strRef
.c_str(), strRef
.size());
4605 result
->EvalData
.stringVal
[strRef
.size()] = '\0';
4606 return result
.release();
4609 if (expr
->getStmtClass() == Stmt::CStyleCastExprClass
) {
4610 CStyleCastExpr
*CC
= static_cast<CStyleCastExpr
*>(expr
);
4612 rettype
= CC
->getType();
4613 if (rettype
.getAsString() == "CFStringRef" &&
4614 CC
->getSubExpr()->getStmtClass() == Stmt::CallExprClass
) {
4616 callExpr
= static_cast<CallExpr
*>(CC
->getSubExpr());
4617 StringLiteral
*S
= getCFSTR_value(callExpr
);
4619 std::string
strLiteral(S
->getString().str());
4620 result
->EvalType
= CXEval_CFStr
;
4622 result
->EvalData
.stringVal
= new char[strLiteral
.size() + 1];
4623 strncpy((char *)result
->EvalData
.stringVal
, strLiteral
.c_str(),
4625 result
->EvalData
.stringVal
[strLiteral
.size()] = '\0';
4626 return result
.release();
4630 } else if (expr
->getStmtClass() == Stmt::CallExprClass
) {
4631 callExpr
= static_cast<CallExpr
*>(expr
);
4632 rettype
= callExpr
->getCallReturnType(ctx
);
4634 if (rettype
->isVectorType() || callExpr
->getNumArgs() > 1)
4637 if (rettype
->isIntegralType(ctx
) || rettype
->isRealFloatingType()) {
4638 if (callExpr
->getNumArgs() == 1 &&
4639 !callExpr
->getArg(0)->getType()->isIntegralType(ctx
))
4641 } else if (rettype
.getAsString() == "CFStringRef") {
4643 StringLiteral
*S
= getCFSTR_value(callExpr
);
4645 std::string
strLiteral(S
->getString().str());
4646 result
->EvalType
= CXEval_CFStr
;
4647 result
->EvalData
.stringVal
= new char[strLiteral
.size() + 1];
4648 strncpy((char *)result
->EvalData
.stringVal
, strLiteral
.c_str(),
4650 result
->EvalData
.stringVal
[strLiteral
.size()] = '\0';
4651 return result
.release();
4654 } else if (expr
->getStmtClass() == Stmt::DeclRefExprClass
) {
4655 DeclRefExpr
*D
= static_cast<DeclRefExpr
*>(expr
);
4656 ValueDecl
*V
= D
->getDecl();
4657 if (V
->getKind() == Decl::Function
) {
4658 std::string strName
= V
->getNameAsString();
4659 result
->EvalType
= CXEval_Other
;
4660 result
->EvalData
.stringVal
= new char[strName
.size() + 1];
4661 strncpy(result
->EvalData
.stringVal
, strName
.c_str(), strName
.size());
4662 result
->EvalData
.stringVal
[strName
.size()] = '\0';
4663 return result
.release();
4670 static const Expr
*evaluateDeclExpr(const Decl
*D
) {
4673 if (auto *Var
= dyn_cast
<VarDecl
>(D
))
4674 return Var
->getInit();
4675 else if (auto *Field
= dyn_cast
<FieldDecl
>(D
))
4676 return Field
->getInClassInitializer();
4680 static const Expr
*evaluateCompoundStmtExpr(const CompoundStmt
*CS
) {
4681 assert(CS
&& "invalid compound statement");
4682 for (auto *bodyIterator
: CS
->body()) {
4683 if (const auto *E
= dyn_cast
<Expr
>(bodyIterator
))
4689 CXEvalResult
clang_Cursor_Evaluate(CXCursor C
) {
4690 const Expr
*E
= nullptr;
4691 if (clang_getCursorKind(C
) == CXCursor_CompoundStmt
)
4692 E
= evaluateCompoundStmtExpr(cast
<CompoundStmt
>(getCursorStmt(C
)));
4693 else if (clang_isDeclaration(C
.kind
))
4694 E
= evaluateDeclExpr(getCursorDecl(C
));
4695 else if (clang_isExpression(C
.kind
))
4696 E
= getCursorExpr(C
);
4698 return const_cast<CXEvalResult
>(
4699 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr
*>(E
), C
)));
4703 unsigned clang_Cursor_hasAttrs(CXCursor C
) {
4704 const Decl
*D
= getCursorDecl(C
);
4709 if (D
->hasAttrs()) {
4715 unsigned clang_defaultSaveOptions(CXTranslationUnit TU
) {
4716 return CXSaveTranslationUnit_None
;
4719 static CXSaveError
clang_saveTranslationUnit_Impl(CXTranslationUnit TU
,
4720 const char *FileName
,
4722 CIndexer
*CXXIdx
= TU
->CIdx
;
4723 if (CXXIdx
->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing
))
4724 setThreadBackgroundPriority();
4726 bool hadError
= cxtu::getASTUnit(TU
)->Save(FileName
);
4727 return hadError
? CXSaveError_Unknown
: CXSaveError_None
;
4730 int clang_saveTranslationUnit(CXTranslationUnit TU
, const char *FileName
,
4732 LOG_FUNC_SECTION
{ *Log
<< TU
<< ' ' << FileName
; }
4734 if (isNotUsableTU(TU
)) {
4736 return CXSaveError_InvalidTU
;
4739 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
4740 ASTUnit::ConcurrencyCheck
Check(*CXXUnit
);
4741 if (!CXXUnit
->hasSema())
4742 return CXSaveError_InvalidTU
;
4745 auto SaveTranslationUnitImpl
= [=, &result
]() {
4746 result
= clang_saveTranslationUnit_Impl(TU
, FileName
, options
);
4749 if (!CXXUnit
->getDiagnostics().hasUnrecoverableErrorOccurred()) {
4750 SaveTranslationUnitImpl();
4752 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4753 PrintLibclangResourceUsage(TU
);
4758 // We have an AST that has invalid nodes due to compiler errors.
4759 // Use a crash recovery thread for protection.
4761 llvm::CrashRecoveryContext CRC
;
4763 if (!RunSafely(CRC
, SaveTranslationUnitImpl
)) {
4764 fprintf(stderr
, "libclang: crash detected during AST saving: {\n");
4765 fprintf(stderr
, " 'filename' : '%s'\n", FileName
);
4766 fprintf(stderr
, " 'options' : %d,\n", options
);
4767 fprintf(stderr
, "}\n");
4769 return CXSaveError_Unknown
;
4771 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4772 PrintLibclangResourceUsage(TU
);
4778 void clang_disposeTranslationUnit(CXTranslationUnit CTUnit
) {
4780 // If the translation unit has been marked as unsafe to free, just discard
4782 ASTUnit
*Unit
= cxtu::getASTUnit(CTUnit
);
4783 if (Unit
&& Unit
->isUnsafeToFree())
4786 delete cxtu::getASTUnit(CTUnit
);
4787 delete CTUnit
->StringPool
;
4788 delete static_cast<CXDiagnosticSetImpl
*>(CTUnit
->Diagnostics
);
4789 disposeOverridenCXCursorsPool(CTUnit
->OverridenCursorsPool
);
4790 delete CTUnit
->CommentToXML
;
4795 unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit
) {
4797 ASTUnit
*Unit
= cxtu::getASTUnit(CTUnit
);
4799 if (Unit
&& Unit
->isUnsafeToFree())
4802 Unit
->ResetForParse();
4809 unsigned clang_defaultReparseOptions(CXTranslationUnit TU
) {
4810 return CXReparse_None
;
4814 clang_reparseTranslationUnit_Impl(CXTranslationUnit TU
,
4815 ArrayRef
<CXUnsavedFile
> unsaved_files
,
4818 if (isNotUsableTU(TU
)) {
4820 return CXError_InvalidArguments
;
4823 // Reset the associated diagnostics.
4824 delete static_cast<CXDiagnosticSetImpl
*>(TU
->Diagnostics
);
4825 TU
->Diagnostics
= nullptr;
4827 CIndexer
*CXXIdx
= TU
->CIdx
;
4828 if (CXXIdx
->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing
))
4829 setThreadBackgroundPriority();
4831 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
4832 ASTUnit::ConcurrencyCheck
Check(*CXXUnit
);
4834 std::unique_ptr
<std::vector
<ASTUnit::RemappedFile
>> RemappedFiles(
4835 new std::vector
<ASTUnit::RemappedFile
>());
4837 // Recover resources if we crash before exiting this function.
4838 llvm::CrashRecoveryContextCleanupRegistrar
<std::vector
<ASTUnit::RemappedFile
>>
4839 RemappedCleanup(RemappedFiles
.get());
4841 for (auto &UF
: unsaved_files
) {
4842 std::unique_ptr
<llvm::MemoryBuffer
> MB
=
4843 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF
), UF
.Filename
);
4844 RemappedFiles
->push_back(std::make_pair(UF
.Filename
, MB
.release()));
4847 if (!CXXUnit
->Reparse(CXXIdx
->getPCHContainerOperations(),
4848 *RemappedFiles
.get()))
4849 return CXError_Success
;
4850 if (isASTReadError(CXXUnit
))
4851 return CXError_ASTReadError
;
4852 return CXError_Failure
;
4855 int clang_reparseTranslationUnit(CXTranslationUnit TU
,
4856 unsigned num_unsaved_files
,
4857 struct CXUnsavedFile
*unsaved_files
,
4859 LOG_FUNC_SECTION
{ *Log
<< TU
; }
4861 if (num_unsaved_files
&& !unsaved_files
)
4862 return CXError_InvalidArguments
;
4865 auto ReparseTranslationUnitImpl
= [=, &result
]() {
4866 result
= clang_reparseTranslationUnit_Impl(
4867 TU
, llvm::ArrayRef(unsaved_files
, num_unsaved_files
), options
);
4870 llvm::CrashRecoveryContext CRC
;
4872 if (!RunSafely(CRC
, ReparseTranslationUnitImpl
)) {
4873 fprintf(stderr
, "libclang: crash detected during reparsing\n");
4874 cxtu::getASTUnit(TU
)->setUnsafeToFree(true);
4875 return CXError_Crashed
;
4876 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4877 PrintLibclangResourceUsage(TU
);
4882 CXString
clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit
) {
4883 if (isNotUsableTU(CTUnit
)) {
4885 return cxstring::createEmpty();
4888 ASTUnit
*CXXUnit
= cxtu::getASTUnit(CTUnit
);
4889 return cxstring::createDup(CXXUnit
->getOriginalSourceFileName());
4892 CXCursor
clang_getTranslationUnitCursor(CXTranslationUnit TU
) {
4893 if (isNotUsableTU(TU
)) {
4895 return clang_getNullCursor();
4898 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
4899 return MakeCXCursor(CXXUnit
->getASTContext().getTranslationUnitDecl(), TU
);
4902 CXTargetInfo
clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit
) {
4903 if (isNotUsableTU(CTUnit
)) {
4908 CXTargetInfoImpl
*impl
= new CXTargetInfoImpl();
4909 impl
->TranslationUnit
= CTUnit
;
4913 CXString
clang_TargetInfo_getTriple(CXTargetInfo TargetInfo
) {
4915 return cxstring::createEmpty();
4917 CXTranslationUnit CTUnit
= TargetInfo
->TranslationUnit
;
4918 assert(!isNotUsableTU(CTUnit
) &&
4919 "Unexpected unusable translation unit in TargetInfo");
4921 ASTUnit
*CXXUnit
= cxtu::getASTUnit(CTUnit
);
4922 std::string Triple
=
4923 CXXUnit
->getASTContext().getTargetInfo().getTriple().normalize();
4924 return cxstring::createDup(Triple
);
4927 int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo
) {
4931 CXTranslationUnit CTUnit
= TargetInfo
->TranslationUnit
;
4932 assert(!isNotUsableTU(CTUnit
) &&
4933 "Unexpected unusable translation unit in TargetInfo");
4935 ASTUnit
*CXXUnit
= cxtu::getASTUnit(CTUnit
);
4936 return CXXUnit
->getASTContext().getTargetInfo().getMaxPointerWidth();
4939 void clang_TargetInfo_dispose(CXTargetInfo TargetInfo
) {
4946 //===----------------------------------------------------------------------===//
4947 // CXFile Operations.
4948 //===----------------------------------------------------------------------===//
4950 CXString
clang_getFileName(CXFile SFile
) {
4952 return cxstring::createNull();
4954 FileEntryRef FEnt
= *cxfile::getFileEntryRef(SFile
);
4955 return cxstring::createRef(FEnt
.getName());
4958 time_t clang_getFileTime(CXFile SFile
) {
4962 FileEntryRef FEnt
= *cxfile::getFileEntryRef(SFile
);
4963 return FEnt
.getModificationTime();
4966 CXFile
clang_getFile(CXTranslationUnit TU
, const char *file_name
) {
4967 if (isNotUsableTU(TU
)) {
4972 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
4974 FileManager
&FMgr
= CXXUnit
->getFileManager();
4975 return cxfile::makeCXFile(FMgr
.getOptionalFileRef(file_name
));
4978 const char *clang_getFileContents(CXTranslationUnit TU
, CXFile file
,
4980 if (isNotUsableTU(TU
)) {
4985 const SourceManager
&SM
= cxtu::getASTUnit(TU
)->getSourceManager();
4986 FileID fid
= SM
.translateFile(*cxfile::getFileEntryRef(file
));
4987 std::optional
<llvm::MemoryBufferRef
> buf
= SM
.getBufferOrNone(fid
);
4994 *size
= buf
->getBufferSize();
4995 return buf
->getBufferStart();
4998 unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU
, CXFile file
) {
4999 if (isNotUsableTU(TU
)) {
5007 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
5008 FileEntryRef FEnt
= *cxfile::getFileEntryRef(file
);
5009 return CXXUnit
->getPreprocessor()
5010 .getHeaderSearchInfo()
5011 .isFileMultipleIncludeGuarded(FEnt
);
5014 int clang_getFileUniqueID(CXFile file
, CXFileUniqueID
*outID
) {
5015 if (!file
|| !outID
)
5018 FileEntryRef FEnt
= *cxfile::getFileEntryRef(file
);
5019 const llvm::sys::fs::UniqueID
&ID
= FEnt
.getUniqueID();
5020 outID
->data
[0] = ID
.getDevice();
5021 outID
->data
[1] = ID
.getFile();
5022 outID
->data
[2] = FEnt
.getModificationTime();
5026 int clang_File_isEqual(CXFile file1
, CXFile file2
) {
5030 if (!file1
|| !file2
)
5033 FileEntryRef FEnt1
= *cxfile::getFileEntryRef(file1
);
5034 FileEntryRef FEnt2
= *cxfile::getFileEntryRef(file2
);
5035 return FEnt1
.getUniqueID() == FEnt2
.getUniqueID();
5038 CXString
clang_File_tryGetRealPathName(CXFile SFile
) {
5040 return cxstring::createNull();
5042 FileEntryRef FEnt
= *cxfile::getFileEntryRef(SFile
);
5043 return cxstring::createRef(FEnt
.getFileEntry().tryGetRealPathName());
5046 //===----------------------------------------------------------------------===//
5047 // CXCursor Operations.
5048 //===----------------------------------------------------------------------===//
5050 static const Decl
*getDeclFromExpr(const Stmt
*E
) {
5051 if (const ImplicitCastExpr
*CE
= dyn_cast
<ImplicitCastExpr
>(E
))
5052 return getDeclFromExpr(CE
->getSubExpr());
5054 if (const DeclRefExpr
*RefExpr
= dyn_cast
<DeclRefExpr
>(E
))
5055 return RefExpr
->getDecl();
5056 if (const MemberExpr
*ME
= dyn_cast
<MemberExpr
>(E
))
5057 return ME
->getMemberDecl();
5058 if (const ObjCIvarRefExpr
*RE
= dyn_cast
<ObjCIvarRefExpr
>(E
))
5059 return RE
->getDecl();
5060 if (const ObjCPropertyRefExpr
*PRE
= dyn_cast
<ObjCPropertyRefExpr
>(E
)) {
5061 if (PRE
->isExplicitProperty())
5062 return PRE
->getExplicitProperty();
5063 // It could be messaging both getter and setter as in:
5065 // in which case prefer to associate the setter since it is less obvious
5066 // from inspecting the source that the setter is going to get called.
5067 if (PRE
->isMessagingSetter())
5068 return PRE
->getImplicitPropertySetter();
5069 return PRE
->getImplicitPropertyGetter();
5071 if (const PseudoObjectExpr
*POE
= dyn_cast
<PseudoObjectExpr
>(E
))
5072 return getDeclFromExpr(POE
->getSyntacticForm());
5073 if (const OpaqueValueExpr
*OVE
= dyn_cast
<OpaqueValueExpr
>(E
))
5074 if (Expr
*Src
= OVE
->getSourceExpr())
5075 return getDeclFromExpr(Src
);
5077 if (const CallExpr
*CE
= dyn_cast
<CallExpr
>(E
))
5078 return getDeclFromExpr(CE
->getCallee());
5079 if (const CXXConstructExpr
*CE
= dyn_cast
<CXXConstructExpr
>(E
))
5080 if (!CE
->isElidable())
5081 return CE
->getConstructor();
5082 if (const CXXInheritedCtorInitExpr
*CE
=
5083 dyn_cast
<CXXInheritedCtorInitExpr
>(E
))
5084 return CE
->getConstructor();
5085 if (const ObjCMessageExpr
*OME
= dyn_cast
<ObjCMessageExpr
>(E
))
5086 return OME
->getMethodDecl();
5088 if (const ObjCProtocolExpr
*PE
= dyn_cast
<ObjCProtocolExpr
>(E
))
5089 return PE
->getProtocol();
5090 if (const SubstNonTypeTemplateParmPackExpr
*NTTP
=
5091 dyn_cast
<SubstNonTypeTemplateParmPackExpr
>(E
))
5092 return NTTP
->getParameterPack();
5093 if (const SizeOfPackExpr
*SizeOfPack
= dyn_cast
<SizeOfPackExpr
>(E
))
5094 if (isa
<NonTypeTemplateParmDecl
>(SizeOfPack
->getPack()) ||
5095 isa
<ParmVarDecl
>(SizeOfPack
->getPack()))
5096 return SizeOfPack
->getPack();
5101 static SourceLocation
getLocationFromExpr(const Expr
*E
) {
5102 if (const ImplicitCastExpr
*CE
= dyn_cast
<ImplicitCastExpr
>(E
))
5103 return getLocationFromExpr(CE
->getSubExpr());
5105 if (const ObjCMessageExpr
*Msg
= dyn_cast
<ObjCMessageExpr
>(E
))
5106 return /*FIXME:*/ Msg
->getLeftLoc();
5107 if (const DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(E
))
5108 return DRE
->getLocation();
5109 if (const MemberExpr
*Member
= dyn_cast
<MemberExpr
>(E
))
5110 return Member
->getMemberLoc();
5111 if (const ObjCIvarRefExpr
*Ivar
= dyn_cast
<ObjCIvarRefExpr
>(E
))
5112 return Ivar
->getLocation();
5113 if (const SizeOfPackExpr
*SizeOfPack
= dyn_cast
<SizeOfPackExpr
>(E
))
5114 return SizeOfPack
->getPackLoc();
5115 if (const ObjCPropertyRefExpr
*PropRef
= dyn_cast
<ObjCPropertyRefExpr
>(E
))
5116 return PropRef
->getLocation();
5118 return E
->getBeginLoc();
5123 unsigned clang_visitChildren(CXCursor parent
, CXCursorVisitor visitor
,
5124 CXClientData client_data
) {
5125 CursorVisitor
CursorVis(getCursorTU(parent
), visitor
, client_data
,
5126 /*VisitPreprocessorLast=*/false);
5127 return CursorVis
.VisitChildren(parent
);
5130 #ifndef __has_feature
5131 #define __has_feature(x) 0
5133 #if __has_feature(blocks)
5134 typedef enum CXChildVisitResult (^CXCursorVisitorBlock
)(CXCursor cursor
,
5137 static enum CXChildVisitResult
visitWithBlock(CXCursor cursor
, CXCursor parent
,
5138 CXClientData client_data
) {
5139 CXCursorVisitorBlock block
= (CXCursorVisitorBlock
)client_data
;
5140 return block(cursor
, parent
);
5143 // If we are compiled with a compiler that doesn't have native blocks support,
5144 // define and call the block manually, so the
5145 typedef struct _CXChildVisitResult
{
5149 enum CXChildVisitResult (*invoke
)(struct _CXChildVisitResult
*, CXCursor
,
5151 } * CXCursorVisitorBlock
;
5153 static enum CXChildVisitResult
visitWithBlock(CXCursor cursor
, CXCursor parent
,
5154 CXClientData client_data
) {
5155 CXCursorVisitorBlock block
= (CXCursorVisitorBlock
)client_data
;
5156 return block
->invoke(block
, cursor
, parent
);
5160 unsigned clang_visitChildrenWithBlock(CXCursor parent
,
5161 CXCursorVisitorBlock block
) {
5162 return clang_visitChildren(parent
, visitWithBlock
, block
);
5165 static CXString
getDeclSpelling(const Decl
*D
) {
5167 return cxstring::createEmpty();
5169 const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
);
5171 if (const ObjCPropertyImplDecl
*PropImpl
=
5172 dyn_cast
<ObjCPropertyImplDecl
>(D
))
5173 if (ObjCPropertyDecl
*Property
= PropImpl
->getPropertyDecl())
5174 return cxstring::createDup(Property
->getIdentifier()->getName());
5176 if (const ImportDecl
*ImportD
= dyn_cast
<ImportDecl
>(D
))
5177 if (Module
*Mod
= ImportD
->getImportedModule())
5178 return cxstring::createDup(Mod
->getFullModuleName());
5180 return cxstring::createEmpty();
5183 if (const ObjCMethodDecl
*OMD
= dyn_cast
<ObjCMethodDecl
>(ND
))
5184 return cxstring::createDup(OMD
->getSelector().getAsString());
5186 if (const ObjCCategoryImplDecl
*CIMP
= dyn_cast
<ObjCCategoryImplDecl
>(ND
))
5187 // No, this isn't the same as the code below. getIdentifier() is non-virtual
5188 // and returns different names. NamedDecl returns the class name and
5189 // ObjCCategoryImplDecl returns the category name.
5190 return cxstring::createRef(CIMP
->getIdentifier()->getNameStart());
5192 if (isa
<UsingDirectiveDecl
>(D
))
5193 return cxstring::createEmpty();
5195 SmallString
<1024> S
;
5196 llvm::raw_svector_ostream
os(S
);
5199 return cxstring::createDup(os
.str());
5202 CXString
clang_getCursorSpelling(CXCursor C
) {
5203 if (clang_isTranslationUnit(C
.kind
))
5204 return clang_getTranslationUnitSpelling(getCursorTU(C
));
5206 if (clang_isReference(C
.kind
)) {
5208 case CXCursor_ObjCSuperClassRef
: {
5209 const ObjCInterfaceDecl
*Super
= getCursorObjCSuperClassRef(C
).first
;
5210 return cxstring::createRef(Super
->getIdentifier()->getNameStart());
5212 case CXCursor_ObjCClassRef
: {
5213 const ObjCInterfaceDecl
*Class
= getCursorObjCClassRef(C
).first
;
5214 return cxstring::createRef(Class
->getIdentifier()->getNameStart());
5216 case CXCursor_ObjCProtocolRef
: {
5217 const ObjCProtocolDecl
*OID
= getCursorObjCProtocolRef(C
).first
;
5218 assert(OID
&& "getCursorSpelling(): Missing protocol decl");
5219 return cxstring::createRef(OID
->getIdentifier()->getNameStart());
5221 case CXCursor_CXXBaseSpecifier
: {
5222 const CXXBaseSpecifier
*B
= getCursorCXXBaseSpecifier(C
);
5223 return cxstring::createDup(B
->getType().getAsString());
5225 case CXCursor_TypeRef
: {
5226 const TypeDecl
*Type
= getCursorTypeRef(C
).first
;
5227 assert(Type
&& "Missing type decl");
5229 return cxstring::createDup(
5230 getCursorContext(C
).getTypeDeclType(Type
).getAsString());
5232 case CXCursor_TemplateRef
: {
5233 const TemplateDecl
*Template
= getCursorTemplateRef(C
).first
;
5234 assert(Template
&& "Missing template decl");
5236 return cxstring::createDup(Template
->getNameAsString());
5239 case CXCursor_NamespaceRef
: {
5240 const NamedDecl
*NS
= getCursorNamespaceRef(C
).first
;
5241 assert(NS
&& "Missing namespace decl");
5243 return cxstring::createDup(NS
->getNameAsString());
5246 case CXCursor_MemberRef
: {
5247 const FieldDecl
*Field
= getCursorMemberRef(C
).first
;
5248 assert(Field
&& "Missing member decl");
5250 return cxstring::createDup(Field
->getNameAsString());
5253 case CXCursor_LabelRef
: {
5254 const LabelStmt
*Label
= getCursorLabelRef(C
).first
;
5255 assert(Label
&& "Missing label");
5257 return cxstring::createRef(Label
->getName());
5260 case CXCursor_OverloadedDeclRef
: {
5261 OverloadedDeclRefStorage Storage
= getCursorOverloadedDeclRef(C
).first
;
5262 if (const Decl
*D
= Storage
.dyn_cast
<const Decl
*>()) {
5263 if (const NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
))
5264 return cxstring::createDup(ND
->getNameAsString());
5265 return cxstring::createEmpty();
5267 if (const OverloadExpr
*E
= Storage
.dyn_cast
<const OverloadExpr
*>())
5268 return cxstring::createDup(E
->getName().getAsString());
5269 OverloadedTemplateStorage
*Ovl
=
5270 Storage
.get
<OverloadedTemplateStorage
*>();
5271 if (Ovl
->size() == 0)
5272 return cxstring::createEmpty();
5273 return cxstring::createDup((*Ovl
->begin())->getNameAsString());
5276 case CXCursor_VariableRef
: {
5277 const VarDecl
*Var
= getCursorVariableRef(C
).first
;
5278 assert(Var
&& "Missing variable decl");
5280 return cxstring::createDup(Var
->getNameAsString());
5284 return cxstring::createRef("<not implemented>");
5288 if (clang_isExpression(C
.kind
)) {
5289 const Expr
*E
= getCursorExpr(C
);
5291 if (C
.kind
== CXCursor_ObjCStringLiteral
||
5292 C
.kind
== CXCursor_StringLiteral
) {
5293 const StringLiteral
*SLit
;
5294 if (const ObjCStringLiteral
*OSL
= dyn_cast
<ObjCStringLiteral
>(E
)) {
5295 SLit
= OSL
->getString();
5297 SLit
= cast
<StringLiteral
>(E
);
5299 SmallString
<256> Buf
;
5300 llvm::raw_svector_ostream
OS(Buf
);
5301 SLit
->outputString(OS
);
5302 return cxstring::createDup(OS
.str());
5305 if (C
.kind
== CXCursor_BinaryOperator
||
5306 C
.kind
== CXCursor_CompoundAssignOperator
) {
5307 return clang_Cursor_getBinaryOpcodeStr(clang_Cursor_getBinaryOpcode(C
));
5310 const Decl
*D
= getDeclFromExpr(getCursorExpr(C
));
5312 return getDeclSpelling(D
);
5313 return cxstring::createEmpty();
5316 if (clang_isStatement(C
.kind
)) {
5317 const Stmt
*S
= getCursorStmt(C
);
5318 if (const LabelStmt
*Label
= dyn_cast_or_null
<LabelStmt
>(S
))
5319 return cxstring::createRef(Label
->getName());
5321 return cxstring::createEmpty();
5324 if (C
.kind
== CXCursor_MacroExpansion
)
5325 return cxstring::createRef(
5326 getCursorMacroExpansion(C
).getName()->getNameStart());
5328 if (C
.kind
== CXCursor_MacroDefinition
)
5329 return cxstring::createRef(
5330 getCursorMacroDefinition(C
)->getName()->getNameStart());
5332 if (C
.kind
== CXCursor_InclusionDirective
)
5333 return cxstring::createDup(getCursorInclusionDirective(C
)->getFileName());
5335 if (clang_isDeclaration(C
.kind
))
5336 return getDeclSpelling(getCursorDecl(C
));
5338 if (C
.kind
== CXCursor_AnnotateAttr
) {
5339 const AnnotateAttr
*AA
= cast
<AnnotateAttr
>(cxcursor::getCursorAttr(C
));
5340 return cxstring::createDup(AA
->getAnnotation());
5343 if (C
.kind
== CXCursor_AsmLabelAttr
) {
5344 const AsmLabelAttr
*AA
= cast
<AsmLabelAttr
>(cxcursor::getCursorAttr(C
));
5345 return cxstring::createDup(AA
->getLabel());
5348 if (C
.kind
== CXCursor_PackedAttr
) {
5349 return cxstring::createRef("packed");
5352 if (C
.kind
== CXCursor_VisibilityAttr
) {
5353 const VisibilityAttr
*AA
= cast
<VisibilityAttr
>(cxcursor::getCursorAttr(C
));
5354 switch (AA
->getVisibility()) {
5355 case VisibilityAttr::VisibilityType::Default
:
5356 return cxstring::createRef("default");
5357 case VisibilityAttr::VisibilityType::Hidden
:
5358 return cxstring::createRef("hidden");
5359 case VisibilityAttr::VisibilityType::Protected
:
5360 return cxstring::createRef("protected");
5362 llvm_unreachable("unknown visibility type");
5365 return cxstring::createEmpty();
5368 CXSourceRange
clang_Cursor_getSpellingNameRange(CXCursor C
, unsigned pieceIndex
,
5370 if (clang_Cursor_isNull(C
))
5371 return clang_getNullRange();
5373 ASTContext
&Ctx
= getCursorContext(C
);
5375 if (clang_isStatement(C
.kind
)) {
5376 const Stmt
*S
= getCursorStmt(C
);
5377 if (const LabelStmt
*Label
= dyn_cast_or_null
<LabelStmt
>(S
)) {
5379 return clang_getNullRange();
5380 return cxloc::translateSourceRange(Ctx
, Label
->getIdentLoc());
5383 return clang_getNullRange();
5386 if (C
.kind
== CXCursor_ObjCMessageExpr
) {
5387 if (const ObjCMessageExpr
*ME
=
5388 dyn_cast_or_null
<ObjCMessageExpr
>(getCursorExpr(C
))) {
5389 if (pieceIndex
>= ME
->getNumSelectorLocs())
5390 return clang_getNullRange();
5391 return cxloc::translateSourceRange(Ctx
, ME
->getSelectorLoc(pieceIndex
));
5395 if (C
.kind
== CXCursor_ObjCInstanceMethodDecl
||
5396 C
.kind
== CXCursor_ObjCClassMethodDecl
) {
5397 if (const ObjCMethodDecl
*MD
=
5398 dyn_cast_or_null
<ObjCMethodDecl
>(getCursorDecl(C
))) {
5399 if (pieceIndex
>= MD
->getNumSelectorLocs())
5400 return clang_getNullRange();
5401 return cxloc::translateSourceRange(Ctx
, MD
->getSelectorLoc(pieceIndex
));
5405 if (C
.kind
== CXCursor_ObjCCategoryDecl
||
5406 C
.kind
== CXCursor_ObjCCategoryImplDecl
) {
5408 return clang_getNullRange();
5409 if (const ObjCCategoryDecl
*CD
=
5410 dyn_cast_or_null
<ObjCCategoryDecl
>(getCursorDecl(C
)))
5411 return cxloc::translateSourceRange(Ctx
, CD
->getCategoryNameLoc());
5412 if (const ObjCCategoryImplDecl
*CID
=
5413 dyn_cast_or_null
<ObjCCategoryImplDecl
>(getCursorDecl(C
)))
5414 return cxloc::translateSourceRange(Ctx
, CID
->getCategoryNameLoc());
5417 if (C
.kind
== CXCursor_ModuleImportDecl
) {
5419 return clang_getNullRange();
5420 if (const ImportDecl
*ImportD
=
5421 dyn_cast_or_null
<ImportDecl
>(getCursorDecl(C
))) {
5422 ArrayRef
<SourceLocation
> Locs
= ImportD
->getIdentifierLocs();
5424 return cxloc::translateSourceRange(
5425 Ctx
, SourceRange(Locs
.front(), Locs
.back()));
5427 return clang_getNullRange();
5430 if (C
.kind
== CXCursor_CXXMethod
|| C
.kind
== CXCursor_Destructor
||
5431 C
.kind
== CXCursor_ConversionFunction
||
5432 C
.kind
== CXCursor_FunctionDecl
) {
5434 return clang_getNullRange();
5435 if (const FunctionDecl
*FD
=
5436 dyn_cast_or_null
<FunctionDecl
>(getCursorDecl(C
))) {
5437 DeclarationNameInfo FunctionName
= FD
->getNameInfo();
5438 return cxloc::translateSourceRange(Ctx
, FunctionName
.getSourceRange());
5440 return clang_getNullRange();
5443 // FIXME: A CXCursor_InclusionDirective should give the location of the
5444 // filename, but we don't keep track of this.
5446 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
5447 // but we don't keep track of this.
5449 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
5450 // but we don't keep track of this.
5452 // Default handling, give the location of the cursor.
5455 return clang_getNullRange();
5457 CXSourceLocation CXLoc
= clang_getCursorLocation(C
);
5458 SourceLocation Loc
= cxloc::translateSourceLocation(CXLoc
);
5459 return cxloc::translateSourceRange(Ctx
, Loc
);
5462 CXString
clang_Cursor_getMangling(CXCursor C
) {
5463 if (clang_isInvalid(C
.kind
) || !clang_isDeclaration(C
.kind
))
5464 return cxstring::createEmpty();
5466 // Mangling only works for functions and variables.
5467 const Decl
*D
= getCursorDecl(C
);
5468 if (!D
|| !(isa
<FunctionDecl
>(D
) || isa
<VarDecl
>(D
)))
5469 return cxstring::createEmpty();
5471 ASTContext
&Ctx
= D
->getASTContext();
5472 ASTNameGenerator
ASTNameGen(Ctx
);
5473 return cxstring::createDup(ASTNameGen
.getName(D
));
5476 CXStringSet
*clang_Cursor_getCXXManglings(CXCursor C
) {
5477 if (clang_isInvalid(C
.kind
) || !clang_isDeclaration(C
.kind
))
5480 const Decl
*D
= getCursorDecl(C
);
5481 if (!(isa
<CXXRecordDecl
>(D
) || isa
<CXXMethodDecl
>(D
)))
5484 ASTContext
&Ctx
= D
->getASTContext();
5485 ASTNameGenerator
ASTNameGen(Ctx
);
5486 std::vector
<std::string
> Manglings
= ASTNameGen
.getAllManglings(D
);
5487 return cxstring::createSet(Manglings
);
5490 CXStringSet
*clang_Cursor_getObjCManglings(CXCursor C
) {
5491 if (clang_isInvalid(C
.kind
) || !clang_isDeclaration(C
.kind
))
5494 const Decl
*D
= getCursorDecl(C
);
5495 if (!(isa
<ObjCInterfaceDecl
>(D
) || isa
<ObjCImplementationDecl
>(D
)))
5498 ASTContext
&Ctx
= D
->getASTContext();
5499 ASTNameGenerator
ASTNameGen(Ctx
);
5500 std::vector
<std::string
> Manglings
= ASTNameGen
.getAllManglings(D
);
5501 return cxstring::createSet(Manglings
);
5504 CXPrintingPolicy
clang_getCursorPrintingPolicy(CXCursor C
) {
5505 if (clang_Cursor_isNull(C
))
5507 return new PrintingPolicy(getCursorContext(C
).getPrintingPolicy());
5510 void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy
) {
5512 delete static_cast<PrintingPolicy
*>(Policy
);
5516 clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy
,
5517 enum CXPrintingPolicyProperty Property
) {
5521 PrintingPolicy
*P
= static_cast<PrintingPolicy
*>(Policy
);
5523 case CXPrintingPolicy_Indentation
:
5524 return P
->Indentation
;
5525 case CXPrintingPolicy_SuppressSpecifiers
:
5526 return P
->SuppressSpecifiers
;
5527 case CXPrintingPolicy_SuppressTagKeyword
:
5528 return P
->SuppressTagKeyword
;
5529 case CXPrintingPolicy_IncludeTagDefinition
:
5530 return P
->IncludeTagDefinition
;
5531 case CXPrintingPolicy_SuppressScope
:
5532 return P
->SuppressScope
;
5533 case CXPrintingPolicy_SuppressUnwrittenScope
:
5534 return P
->SuppressUnwrittenScope
;
5535 case CXPrintingPolicy_SuppressInitializers
:
5536 return P
->SuppressInitializers
;
5537 case CXPrintingPolicy_ConstantArraySizeAsWritten
:
5538 return P
->ConstantArraySizeAsWritten
;
5539 case CXPrintingPolicy_AnonymousTagLocations
:
5540 return P
->AnonymousTagLocations
;
5541 case CXPrintingPolicy_SuppressStrongLifetime
:
5542 return P
->SuppressStrongLifetime
;
5543 case CXPrintingPolicy_SuppressLifetimeQualifiers
:
5544 return P
->SuppressLifetimeQualifiers
;
5545 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors
:
5546 return P
->SuppressTemplateArgsInCXXConstructors
;
5547 case CXPrintingPolicy_Bool
:
5549 case CXPrintingPolicy_Restrict
:
5551 case CXPrintingPolicy_Alignof
:
5553 case CXPrintingPolicy_UnderscoreAlignof
:
5554 return P
->UnderscoreAlignof
;
5555 case CXPrintingPolicy_UseVoidForZeroParams
:
5556 return P
->UseVoidForZeroParams
;
5557 case CXPrintingPolicy_TerseOutput
:
5558 return P
->TerseOutput
;
5559 case CXPrintingPolicy_PolishForDeclaration
:
5560 return P
->PolishForDeclaration
;
5561 case CXPrintingPolicy_Half
:
5563 case CXPrintingPolicy_MSWChar
:
5565 case CXPrintingPolicy_IncludeNewlines
:
5566 return P
->IncludeNewlines
;
5567 case CXPrintingPolicy_MSVCFormatting
:
5568 return P
->MSVCFormatting
;
5569 case CXPrintingPolicy_ConstantsAsWritten
:
5570 return P
->ConstantsAsWritten
;
5571 case CXPrintingPolicy_SuppressImplicitBase
:
5572 return P
->SuppressImplicitBase
;
5573 case CXPrintingPolicy_FullyQualifiedName
:
5574 return P
->FullyQualifiedName
;
5577 assert(false && "Invalid CXPrintingPolicyProperty");
5581 void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy
,
5582 enum CXPrintingPolicyProperty Property
,
5587 PrintingPolicy
*P
= static_cast<PrintingPolicy
*>(Policy
);
5589 case CXPrintingPolicy_Indentation
:
5590 P
->Indentation
= Value
;
5592 case CXPrintingPolicy_SuppressSpecifiers
:
5593 P
->SuppressSpecifiers
= Value
;
5595 case CXPrintingPolicy_SuppressTagKeyword
:
5596 P
->SuppressTagKeyword
= Value
;
5598 case CXPrintingPolicy_IncludeTagDefinition
:
5599 P
->IncludeTagDefinition
= Value
;
5601 case CXPrintingPolicy_SuppressScope
:
5602 P
->SuppressScope
= Value
;
5604 case CXPrintingPolicy_SuppressUnwrittenScope
:
5605 P
->SuppressUnwrittenScope
= Value
;
5607 case CXPrintingPolicy_SuppressInitializers
:
5608 P
->SuppressInitializers
= Value
;
5610 case CXPrintingPolicy_ConstantArraySizeAsWritten
:
5611 P
->ConstantArraySizeAsWritten
= Value
;
5613 case CXPrintingPolicy_AnonymousTagLocations
:
5614 P
->AnonymousTagLocations
= Value
;
5616 case CXPrintingPolicy_SuppressStrongLifetime
:
5617 P
->SuppressStrongLifetime
= Value
;
5619 case CXPrintingPolicy_SuppressLifetimeQualifiers
:
5620 P
->SuppressLifetimeQualifiers
= Value
;
5622 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors
:
5623 P
->SuppressTemplateArgsInCXXConstructors
= Value
;
5625 case CXPrintingPolicy_Bool
:
5628 case CXPrintingPolicy_Restrict
:
5629 P
->Restrict
= Value
;
5631 case CXPrintingPolicy_Alignof
:
5634 case CXPrintingPolicy_UnderscoreAlignof
:
5635 P
->UnderscoreAlignof
= Value
;
5637 case CXPrintingPolicy_UseVoidForZeroParams
:
5638 P
->UseVoidForZeroParams
= Value
;
5640 case CXPrintingPolicy_TerseOutput
:
5641 P
->TerseOutput
= Value
;
5643 case CXPrintingPolicy_PolishForDeclaration
:
5644 P
->PolishForDeclaration
= Value
;
5646 case CXPrintingPolicy_Half
:
5649 case CXPrintingPolicy_MSWChar
:
5652 case CXPrintingPolicy_IncludeNewlines
:
5653 P
->IncludeNewlines
= Value
;
5655 case CXPrintingPolicy_MSVCFormatting
:
5656 P
->MSVCFormatting
= Value
;
5658 case CXPrintingPolicy_ConstantsAsWritten
:
5659 P
->ConstantsAsWritten
= Value
;
5661 case CXPrintingPolicy_SuppressImplicitBase
:
5662 P
->SuppressImplicitBase
= Value
;
5664 case CXPrintingPolicy_FullyQualifiedName
:
5665 P
->FullyQualifiedName
= Value
;
5669 assert(false && "Invalid CXPrintingPolicyProperty");
5672 CXString
clang_getCursorPrettyPrinted(CXCursor C
, CXPrintingPolicy cxPolicy
) {
5673 if (clang_Cursor_isNull(C
))
5674 return cxstring::createEmpty();
5676 if (clang_isDeclaration(C
.kind
)) {
5677 const Decl
*D
= getCursorDecl(C
);
5679 return cxstring::createEmpty();
5681 SmallString
<128> Str
;
5682 llvm::raw_svector_ostream
OS(Str
);
5683 PrintingPolicy
*UserPolicy
= static_cast<PrintingPolicy
*>(cxPolicy
);
5684 D
->print(OS
, UserPolicy
? *UserPolicy
5685 : getCursorContext(C
).getPrintingPolicy());
5687 return cxstring::createDup(OS
.str());
5690 return cxstring::createEmpty();
5693 CXString
clang_getCursorDisplayName(CXCursor C
) {
5694 if (!clang_isDeclaration(C
.kind
))
5695 return clang_getCursorSpelling(C
);
5697 const Decl
*D
= getCursorDecl(C
);
5699 return cxstring::createEmpty();
5701 PrintingPolicy Policy
= getCursorContext(C
).getPrintingPolicy();
5702 if (const FunctionTemplateDecl
*FunTmpl
= dyn_cast
<FunctionTemplateDecl
>(D
))
5703 D
= FunTmpl
->getTemplatedDecl();
5705 if (const FunctionDecl
*Function
= dyn_cast
<FunctionDecl
>(D
)) {
5706 SmallString
<64> Str
;
5707 llvm::raw_svector_ostream
OS(Str
);
5709 if (Function
->getPrimaryTemplate())
5712 for (unsigned I
= 0, N
= Function
->getNumParams(); I
!= N
; ++I
) {
5715 OS
<< Function
->getParamDecl(I
)->getType().getAsString(Policy
);
5718 if (Function
->isVariadic()) {
5719 if (Function
->getNumParams())
5724 return cxstring::createDup(OS
.str());
5727 if (const ClassTemplateDecl
*ClassTemplate
= dyn_cast
<ClassTemplateDecl
>(D
)) {
5728 SmallString
<64> Str
;
5729 llvm::raw_svector_ostream
OS(Str
);
5730 OS
<< *ClassTemplate
;
5732 TemplateParameterList
*Params
= ClassTemplate
->getTemplateParameters();
5733 for (unsigned I
= 0, N
= Params
->size(); I
!= N
; ++I
) {
5737 NamedDecl
*Param
= Params
->getParam(I
);
5738 if (Param
->getIdentifier()) {
5739 OS
<< Param
->getIdentifier()->getName();
5743 // There is no parameter name, which makes this tricky. Try to come up
5744 // with something useful that isn't too long.
5745 if (TemplateTypeParmDecl
*TTP
= dyn_cast
<TemplateTypeParmDecl
>(Param
))
5746 if (const auto *TC
= TTP
->getTypeConstraint()) {
5747 TC
->getConceptNameInfo().printName(OS
, Policy
);
5748 if (TC
->hasExplicitTemplateArgs())
5751 OS
<< (TTP
->wasDeclaredWithTypename() ? "typename" : "class");
5752 else if (NonTypeTemplateParmDecl
*NTTP
=
5753 dyn_cast
<NonTypeTemplateParmDecl
>(Param
))
5754 OS
<< NTTP
->getType().getAsString(Policy
);
5756 OS
<< "template<...> class";
5760 return cxstring::createDup(OS
.str());
5763 if (const ClassTemplateSpecializationDecl
*ClassSpec
=
5764 dyn_cast
<ClassTemplateSpecializationDecl
>(D
)) {
5765 SmallString
<128> Str
;
5766 llvm::raw_svector_ostream
OS(Str
);
5768 // If the template arguments were written explicitly, use them..
5769 if (const auto *ArgsWritten
= ClassSpec
->getTemplateArgsAsWritten()) {
5770 printTemplateArgumentList(
5771 OS
, ArgsWritten
->arguments(), Policy
,
5772 ClassSpec
->getSpecializedTemplate()->getTemplateParameters());
5774 printTemplateArgumentList(
5775 OS
, ClassSpec
->getTemplateArgs().asArray(), Policy
,
5776 ClassSpec
->getSpecializedTemplate()->getTemplateParameters());
5778 return cxstring::createDup(OS
.str());
5781 return clang_getCursorSpelling(C
);
5784 CXString
clang_getCursorKindSpelling(enum CXCursorKind Kind
) {
5786 case CXCursor_FunctionDecl
:
5787 return cxstring::createRef("FunctionDecl");
5788 case CXCursor_TypedefDecl
:
5789 return cxstring::createRef("TypedefDecl");
5790 case CXCursor_EnumDecl
:
5791 return cxstring::createRef("EnumDecl");
5792 case CXCursor_EnumConstantDecl
:
5793 return cxstring::createRef("EnumConstantDecl");
5794 case CXCursor_StructDecl
:
5795 return cxstring::createRef("StructDecl");
5796 case CXCursor_UnionDecl
:
5797 return cxstring::createRef("UnionDecl");
5798 case CXCursor_ClassDecl
:
5799 return cxstring::createRef("ClassDecl");
5800 case CXCursor_FieldDecl
:
5801 return cxstring::createRef("FieldDecl");
5802 case CXCursor_VarDecl
:
5803 return cxstring::createRef("VarDecl");
5804 case CXCursor_ParmDecl
:
5805 return cxstring::createRef("ParmDecl");
5806 case CXCursor_ObjCInterfaceDecl
:
5807 return cxstring::createRef("ObjCInterfaceDecl");
5808 case CXCursor_ObjCCategoryDecl
:
5809 return cxstring::createRef("ObjCCategoryDecl");
5810 case CXCursor_ObjCProtocolDecl
:
5811 return cxstring::createRef("ObjCProtocolDecl");
5812 case CXCursor_ObjCPropertyDecl
:
5813 return cxstring::createRef("ObjCPropertyDecl");
5814 case CXCursor_ObjCIvarDecl
:
5815 return cxstring::createRef("ObjCIvarDecl");
5816 case CXCursor_ObjCInstanceMethodDecl
:
5817 return cxstring::createRef("ObjCInstanceMethodDecl");
5818 case CXCursor_ObjCClassMethodDecl
:
5819 return cxstring::createRef("ObjCClassMethodDecl");
5820 case CXCursor_ObjCImplementationDecl
:
5821 return cxstring::createRef("ObjCImplementationDecl");
5822 case CXCursor_ObjCCategoryImplDecl
:
5823 return cxstring::createRef("ObjCCategoryImplDecl");
5824 case CXCursor_CXXMethod
:
5825 return cxstring::createRef("CXXMethod");
5826 case CXCursor_UnexposedDecl
:
5827 return cxstring::createRef("UnexposedDecl");
5828 case CXCursor_ObjCSuperClassRef
:
5829 return cxstring::createRef("ObjCSuperClassRef");
5830 case CXCursor_ObjCProtocolRef
:
5831 return cxstring::createRef("ObjCProtocolRef");
5832 case CXCursor_ObjCClassRef
:
5833 return cxstring::createRef("ObjCClassRef");
5834 case CXCursor_TypeRef
:
5835 return cxstring::createRef("TypeRef");
5836 case CXCursor_TemplateRef
:
5837 return cxstring::createRef("TemplateRef");
5838 case CXCursor_NamespaceRef
:
5839 return cxstring::createRef("NamespaceRef");
5840 case CXCursor_MemberRef
:
5841 return cxstring::createRef("MemberRef");
5842 case CXCursor_LabelRef
:
5843 return cxstring::createRef("LabelRef");
5844 case CXCursor_OverloadedDeclRef
:
5845 return cxstring::createRef("OverloadedDeclRef");
5846 case CXCursor_VariableRef
:
5847 return cxstring::createRef("VariableRef");
5848 case CXCursor_IntegerLiteral
:
5849 return cxstring::createRef("IntegerLiteral");
5850 case CXCursor_FixedPointLiteral
:
5851 return cxstring::createRef("FixedPointLiteral");
5852 case CXCursor_FloatingLiteral
:
5853 return cxstring::createRef("FloatingLiteral");
5854 case CXCursor_ImaginaryLiteral
:
5855 return cxstring::createRef("ImaginaryLiteral");
5856 case CXCursor_StringLiteral
:
5857 return cxstring::createRef("StringLiteral");
5858 case CXCursor_CharacterLiteral
:
5859 return cxstring::createRef("CharacterLiteral");
5860 case CXCursor_ParenExpr
:
5861 return cxstring::createRef("ParenExpr");
5862 case CXCursor_UnaryOperator
:
5863 return cxstring::createRef("UnaryOperator");
5864 case CXCursor_ArraySubscriptExpr
:
5865 return cxstring::createRef("ArraySubscriptExpr");
5866 case CXCursor_ArraySectionExpr
:
5867 return cxstring::createRef("ArraySectionExpr");
5868 case CXCursor_OMPArrayShapingExpr
:
5869 return cxstring::createRef("OMPArrayShapingExpr");
5870 case CXCursor_OMPIteratorExpr
:
5871 return cxstring::createRef("OMPIteratorExpr");
5872 case CXCursor_BinaryOperator
:
5873 return cxstring::createRef("BinaryOperator");
5874 case CXCursor_CompoundAssignOperator
:
5875 return cxstring::createRef("CompoundAssignOperator");
5876 case CXCursor_ConditionalOperator
:
5877 return cxstring::createRef("ConditionalOperator");
5878 case CXCursor_CStyleCastExpr
:
5879 return cxstring::createRef("CStyleCastExpr");
5880 case CXCursor_CompoundLiteralExpr
:
5881 return cxstring::createRef("CompoundLiteralExpr");
5882 case CXCursor_InitListExpr
:
5883 return cxstring::createRef("InitListExpr");
5884 case CXCursor_AddrLabelExpr
:
5885 return cxstring::createRef("AddrLabelExpr");
5886 case CXCursor_StmtExpr
:
5887 return cxstring::createRef("StmtExpr");
5888 case CXCursor_GenericSelectionExpr
:
5889 return cxstring::createRef("GenericSelectionExpr");
5890 case CXCursor_GNUNullExpr
:
5891 return cxstring::createRef("GNUNullExpr");
5892 case CXCursor_CXXStaticCastExpr
:
5893 return cxstring::createRef("CXXStaticCastExpr");
5894 case CXCursor_CXXDynamicCastExpr
:
5895 return cxstring::createRef("CXXDynamicCastExpr");
5896 case CXCursor_CXXReinterpretCastExpr
:
5897 return cxstring::createRef("CXXReinterpretCastExpr");
5898 case CXCursor_CXXConstCastExpr
:
5899 return cxstring::createRef("CXXConstCastExpr");
5900 case CXCursor_CXXFunctionalCastExpr
:
5901 return cxstring::createRef("CXXFunctionalCastExpr");
5902 case CXCursor_CXXAddrspaceCastExpr
:
5903 return cxstring::createRef("CXXAddrspaceCastExpr");
5904 case CXCursor_CXXTypeidExpr
:
5905 return cxstring::createRef("CXXTypeidExpr");
5906 case CXCursor_CXXBoolLiteralExpr
:
5907 return cxstring::createRef("CXXBoolLiteralExpr");
5908 case CXCursor_CXXNullPtrLiteralExpr
:
5909 return cxstring::createRef("CXXNullPtrLiteralExpr");
5910 case CXCursor_CXXThisExpr
:
5911 return cxstring::createRef("CXXThisExpr");
5912 case CXCursor_CXXThrowExpr
:
5913 return cxstring::createRef("CXXThrowExpr");
5914 case CXCursor_CXXNewExpr
:
5915 return cxstring::createRef("CXXNewExpr");
5916 case CXCursor_CXXDeleteExpr
:
5917 return cxstring::createRef("CXXDeleteExpr");
5918 case CXCursor_UnaryExpr
:
5919 return cxstring::createRef("UnaryExpr");
5920 case CXCursor_ObjCStringLiteral
:
5921 return cxstring::createRef("ObjCStringLiteral");
5922 case CXCursor_ObjCBoolLiteralExpr
:
5923 return cxstring::createRef("ObjCBoolLiteralExpr");
5924 case CXCursor_ObjCAvailabilityCheckExpr
:
5925 return cxstring::createRef("ObjCAvailabilityCheckExpr");
5926 case CXCursor_ObjCSelfExpr
:
5927 return cxstring::createRef("ObjCSelfExpr");
5928 case CXCursor_ObjCEncodeExpr
:
5929 return cxstring::createRef("ObjCEncodeExpr");
5930 case CXCursor_ObjCSelectorExpr
:
5931 return cxstring::createRef("ObjCSelectorExpr");
5932 case CXCursor_ObjCProtocolExpr
:
5933 return cxstring::createRef("ObjCProtocolExpr");
5934 case CXCursor_ObjCBridgedCastExpr
:
5935 return cxstring::createRef("ObjCBridgedCastExpr");
5936 case CXCursor_BlockExpr
:
5937 return cxstring::createRef("BlockExpr");
5938 case CXCursor_PackExpansionExpr
:
5939 return cxstring::createRef("PackExpansionExpr");
5940 case CXCursor_SizeOfPackExpr
:
5941 return cxstring::createRef("SizeOfPackExpr");
5942 case CXCursor_PackIndexingExpr
:
5943 return cxstring::createRef("PackIndexingExpr");
5944 case CXCursor_LambdaExpr
:
5945 return cxstring::createRef("LambdaExpr");
5946 case CXCursor_UnexposedExpr
:
5947 return cxstring::createRef("UnexposedExpr");
5948 case CXCursor_DeclRefExpr
:
5949 return cxstring::createRef("DeclRefExpr");
5950 case CXCursor_MemberRefExpr
:
5951 return cxstring::createRef("MemberRefExpr");
5952 case CXCursor_CallExpr
:
5953 return cxstring::createRef("CallExpr");
5954 case CXCursor_ObjCMessageExpr
:
5955 return cxstring::createRef("ObjCMessageExpr");
5956 case CXCursor_BuiltinBitCastExpr
:
5957 return cxstring::createRef("BuiltinBitCastExpr");
5958 case CXCursor_ConceptSpecializationExpr
:
5959 return cxstring::createRef("ConceptSpecializationExpr");
5960 case CXCursor_RequiresExpr
:
5961 return cxstring::createRef("RequiresExpr");
5962 case CXCursor_CXXParenListInitExpr
:
5963 return cxstring::createRef("CXXParenListInitExpr");
5964 case CXCursor_UnexposedStmt
:
5965 return cxstring::createRef("UnexposedStmt");
5966 case CXCursor_DeclStmt
:
5967 return cxstring::createRef("DeclStmt");
5968 case CXCursor_LabelStmt
:
5969 return cxstring::createRef("LabelStmt");
5970 case CXCursor_CompoundStmt
:
5971 return cxstring::createRef("CompoundStmt");
5972 case CXCursor_CaseStmt
:
5973 return cxstring::createRef("CaseStmt");
5974 case CXCursor_DefaultStmt
:
5975 return cxstring::createRef("DefaultStmt");
5976 case CXCursor_IfStmt
:
5977 return cxstring::createRef("IfStmt");
5978 case CXCursor_SwitchStmt
:
5979 return cxstring::createRef("SwitchStmt");
5980 case CXCursor_WhileStmt
:
5981 return cxstring::createRef("WhileStmt");
5982 case CXCursor_DoStmt
:
5983 return cxstring::createRef("DoStmt");
5984 case CXCursor_ForStmt
:
5985 return cxstring::createRef("ForStmt");
5986 case CXCursor_GotoStmt
:
5987 return cxstring::createRef("GotoStmt");
5988 case CXCursor_IndirectGotoStmt
:
5989 return cxstring::createRef("IndirectGotoStmt");
5990 case CXCursor_ContinueStmt
:
5991 return cxstring::createRef("ContinueStmt");
5992 case CXCursor_BreakStmt
:
5993 return cxstring::createRef("BreakStmt");
5994 case CXCursor_ReturnStmt
:
5995 return cxstring::createRef("ReturnStmt");
5996 case CXCursor_GCCAsmStmt
:
5997 return cxstring::createRef("GCCAsmStmt");
5998 case CXCursor_MSAsmStmt
:
5999 return cxstring::createRef("MSAsmStmt");
6000 case CXCursor_ObjCAtTryStmt
:
6001 return cxstring::createRef("ObjCAtTryStmt");
6002 case CXCursor_ObjCAtCatchStmt
:
6003 return cxstring::createRef("ObjCAtCatchStmt");
6004 case CXCursor_ObjCAtFinallyStmt
:
6005 return cxstring::createRef("ObjCAtFinallyStmt");
6006 case CXCursor_ObjCAtThrowStmt
:
6007 return cxstring::createRef("ObjCAtThrowStmt");
6008 case CXCursor_ObjCAtSynchronizedStmt
:
6009 return cxstring::createRef("ObjCAtSynchronizedStmt");
6010 case CXCursor_ObjCAutoreleasePoolStmt
:
6011 return cxstring::createRef("ObjCAutoreleasePoolStmt");
6012 case CXCursor_ObjCForCollectionStmt
:
6013 return cxstring::createRef("ObjCForCollectionStmt");
6014 case CXCursor_CXXCatchStmt
:
6015 return cxstring::createRef("CXXCatchStmt");
6016 case CXCursor_CXXTryStmt
:
6017 return cxstring::createRef("CXXTryStmt");
6018 case CXCursor_CXXForRangeStmt
:
6019 return cxstring::createRef("CXXForRangeStmt");
6020 case CXCursor_SEHTryStmt
:
6021 return cxstring::createRef("SEHTryStmt");
6022 case CXCursor_SEHExceptStmt
:
6023 return cxstring::createRef("SEHExceptStmt");
6024 case CXCursor_SEHFinallyStmt
:
6025 return cxstring::createRef("SEHFinallyStmt");
6026 case CXCursor_SEHLeaveStmt
:
6027 return cxstring::createRef("SEHLeaveStmt");
6028 case CXCursor_NullStmt
:
6029 return cxstring::createRef("NullStmt");
6030 case CXCursor_InvalidFile
:
6031 return cxstring::createRef("InvalidFile");
6032 case CXCursor_InvalidCode
:
6033 return cxstring::createRef("InvalidCode");
6034 case CXCursor_NoDeclFound
:
6035 return cxstring::createRef("NoDeclFound");
6036 case CXCursor_NotImplemented
:
6037 return cxstring::createRef("NotImplemented");
6038 case CXCursor_TranslationUnit
:
6039 return cxstring::createRef("TranslationUnit");
6040 case CXCursor_UnexposedAttr
:
6041 return cxstring::createRef("UnexposedAttr");
6042 case CXCursor_IBActionAttr
:
6043 return cxstring::createRef("attribute(ibaction)");
6044 case CXCursor_IBOutletAttr
:
6045 return cxstring::createRef("attribute(iboutlet)");
6046 case CXCursor_IBOutletCollectionAttr
:
6047 return cxstring::createRef("attribute(iboutletcollection)");
6048 case CXCursor_CXXFinalAttr
:
6049 return cxstring::createRef("attribute(final)");
6050 case CXCursor_CXXOverrideAttr
:
6051 return cxstring::createRef("attribute(override)");
6052 case CXCursor_AnnotateAttr
:
6053 return cxstring::createRef("attribute(annotate)");
6054 case CXCursor_AsmLabelAttr
:
6055 return cxstring::createRef("asm label");
6056 case CXCursor_PackedAttr
:
6057 return cxstring::createRef("attribute(packed)");
6058 case CXCursor_PureAttr
:
6059 return cxstring::createRef("attribute(pure)");
6060 case CXCursor_ConstAttr
:
6061 return cxstring::createRef("attribute(const)");
6062 case CXCursor_NoDuplicateAttr
:
6063 return cxstring::createRef("attribute(noduplicate)");
6064 case CXCursor_CUDAConstantAttr
:
6065 return cxstring::createRef("attribute(constant)");
6066 case CXCursor_CUDADeviceAttr
:
6067 return cxstring::createRef("attribute(device)");
6068 case CXCursor_CUDAGlobalAttr
:
6069 return cxstring::createRef("attribute(global)");
6070 case CXCursor_CUDAHostAttr
:
6071 return cxstring::createRef("attribute(host)");
6072 case CXCursor_CUDASharedAttr
:
6073 return cxstring::createRef("attribute(shared)");
6074 case CXCursor_VisibilityAttr
:
6075 return cxstring::createRef("attribute(visibility)");
6076 case CXCursor_DLLExport
:
6077 return cxstring::createRef("attribute(dllexport)");
6078 case CXCursor_DLLImport
:
6079 return cxstring::createRef("attribute(dllimport)");
6080 case CXCursor_NSReturnsRetained
:
6081 return cxstring::createRef("attribute(ns_returns_retained)");
6082 case CXCursor_NSReturnsNotRetained
:
6083 return cxstring::createRef("attribute(ns_returns_not_retained)");
6084 case CXCursor_NSReturnsAutoreleased
:
6085 return cxstring::createRef("attribute(ns_returns_autoreleased)");
6086 case CXCursor_NSConsumesSelf
:
6087 return cxstring::createRef("attribute(ns_consumes_self)");
6088 case CXCursor_NSConsumed
:
6089 return cxstring::createRef("attribute(ns_consumed)");
6090 case CXCursor_ObjCException
:
6091 return cxstring::createRef("attribute(objc_exception)");
6092 case CXCursor_ObjCNSObject
:
6093 return cxstring::createRef("attribute(NSObject)");
6094 case CXCursor_ObjCIndependentClass
:
6095 return cxstring::createRef("attribute(objc_independent_class)");
6096 case CXCursor_ObjCPreciseLifetime
:
6097 return cxstring::createRef("attribute(objc_precise_lifetime)");
6098 case CXCursor_ObjCReturnsInnerPointer
:
6099 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
6100 case CXCursor_ObjCRequiresSuper
:
6101 return cxstring::createRef("attribute(objc_requires_super)");
6102 case CXCursor_ObjCRootClass
:
6103 return cxstring::createRef("attribute(objc_root_class)");
6104 case CXCursor_ObjCSubclassingRestricted
:
6105 return cxstring::createRef("attribute(objc_subclassing_restricted)");
6106 case CXCursor_ObjCExplicitProtocolImpl
:
6107 return cxstring::createRef(
6108 "attribute(objc_protocol_requires_explicit_implementation)");
6109 case CXCursor_ObjCDesignatedInitializer
:
6110 return cxstring::createRef("attribute(objc_designated_initializer)");
6111 case CXCursor_ObjCRuntimeVisible
:
6112 return cxstring::createRef("attribute(objc_runtime_visible)");
6113 case CXCursor_ObjCBoxable
:
6114 return cxstring::createRef("attribute(objc_boxable)");
6115 case CXCursor_FlagEnum
:
6116 return cxstring::createRef("attribute(flag_enum)");
6117 case CXCursor_PreprocessingDirective
:
6118 return cxstring::createRef("preprocessing directive");
6119 case CXCursor_MacroDefinition
:
6120 return cxstring::createRef("macro definition");
6121 case CXCursor_MacroExpansion
:
6122 return cxstring::createRef("macro expansion");
6123 case CXCursor_InclusionDirective
:
6124 return cxstring::createRef("inclusion directive");
6125 case CXCursor_Namespace
:
6126 return cxstring::createRef("Namespace");
6127 case CXCursor_LinkageSpec
:
6128 return cxstring::createRef("LinkageSpec");
6129 case CXCursor_CXXBaseSpecifier
:
6130 return cxstring::createRef("C++ base class specifier");
6131 case CXCursor_Constructor
:
6132 return cxstring::createRef("CXXConstructor");
6133 case CXCursor_Destructor
:
6134 return cxstring::createRef("CXXDestructor");
6135 case CXCursor_ConversionFunction
:
6136 return cxstring::createRef("CXXConversion");
6137 case CXCursor_TemplateTypeParameter
:
6138 return cxstring::createRef("TemplateTypeParameter");
6139 case CXCursor_NonTypeTemplateParameter
:
6140 return cxstring::createRef("NonTypeTemplateParameter");
6141 case CXCursor_TemplateTemplateParameter
:
6142 return cxstring::createRef("TemplateTemplateParameter");
6143 case CXCursor_FunctionTemplate
:
6144 return cxstring::createRef("FunctionTemplate");
6145 case CXCursor_ClassTemplate
:
6146 return cxstring::createRef("ClassTemplate");
6147 case CXCursor_ClassTemplatePartialSpecialization
:
6148 return cxstring::createRef("ClassTemplatePartialSpecialization");
6149 case CXCursor_NamespaceAlias
:
6150 return cxstring::createRef("NamespaceAlias");
6151 case CXCursor_UsingDirective
:
6152 return cxstring::createRef("UsingDirective");
6153 case CXCursor_UsingDeclaration
:
6154 return cxstring::createRef("UsingDeclaration");
6155 case CXCursor_TypeAliasDecl
:
6156 return cxstring::createRef("TypeAliasDecl");
6157 case CXCursor_ObjCSynthesizeDecl
:
6158 return cxstring::createRef("ObjCSynthesizeDecl");
6159 case CXCursor_ObjCDynamicDecl
:
6160 return cxstring::createRef("ObjCDynamicDecl");
6161 case CXCursor_CXXAccessSpecifier
:
6162 return cxstring::createRef("CXXAccessSpecifier");
6163 case CXCursor_ModuleImportDecl
:
6164 return cxstring::createRef("ModuleImport");
6165 case CXCursor_OMPCanonicalLoop
:
6166 return cxstring::createRef("OMPCanonicalLoop");
6167 case CXCursor_OMPMetaDirective
:
6168 return cxstring::createRef("OMPMetaDirective");
6169 case CXCursor_OMPParallelDirective
:
6170 return cxstring::createRef("OMPParallelDirective");
6171 case CXCursor_OMPSimdDirective
:
6172 return cxstring::createRef("OMPSimdDirective");
6173 case CXCursor_OMPTileDirective
:
6174 return cxstring::createRef("OMPTileDirective");
6175 case CXCursor_OMPUnrollDirective
:
6176 return cxstring::createRef("OMPUnrollDirective");
6177 case CXCursor_OMPReverseDirective
:
6178 return cxstring::createRef("OMPReverseDirective");
6179 case CXCursor_OMPInterchangeDirective
:
6180 return cxstring::createRef("OMPInterchangeDirective");
6181 case CXCursor_OMPForDirective
:
6182 return cxstring::createRef("OMPForDirective");
6183 case CXCursor_OMPForSimdDirective
:
6184 return cxstring::createRef("OMPForSimdDirective");
6185 case CXCursor_OMPSectionsDirective
:
6186 return cxstring::createRef("OMPSectionsDirective");
6187 case CXCursor_OMPSectionDirective
:
6188 return cxstring::createRef("OMPSectionDirective");
6189 case CXCursor_OMPScopeDirective
:
6190 return cxstring::createRef("OMPScopeDirective");
6191 case CXCursor_OMPSingleDirective
:
6192 return cxstring::createRef("OMPSingleDirective");
6193 case CXCursor_OMPMasterDirective
:
6194 return cxstring::createRef("OMPMasterDirective");
6195 case CXCursor_OMPCriticalDirective
:
6196 return cxstring::createRef("OMPCriticalDirective");
6197 case CXCursor_OMPParallelForDirective
:
6198 return cxstring::createRef("OMPParallelForDirective");
6199 case CXCursor_OMPParallelForSimdDirective
:
6200 return cxstring::createRef("OMPParallelForSimdDirective");
6201 case CXCursor_OMPParallelMasterDirective
:
6202 return cxstring::createRef("OMPParallelMasterDirective");
6203 case CXCursor_OMPParallelMaskedDirective
:
6204 return cxstring::createRef("OMPParallelMaskedDirective");
6205 case CXCursor_OMPParallelSectionsDirective
:
6206 return cxstring::createRef("OMPParallelSectionsDirective");
6207 case CXCursor_OMPTaskDirective
:
6208 return cxstring::createRef("OMPTaskDirective");
6209 case CXCursor_OMPTaskyieldDirective
:
6210 return cxstring::createRef("OMPTaskyieldDirective");
6211 case CXCursor_OMPBarrierDirective
:
6212 return cxstring::createRef("OMPBarrierDirective");
6213 case CXCursor_OMPTaskwaitDirective
:
6214 return cxstring::createRef("OMPTaskwaitDirective");
6215 case CXCursor_OMPAssumeDirective
:
6216 return cxstring::createRef("OMPAssumeDirective");
6217 case CXCursor_OMPErrorDirective
:
6218 return cxstring::createRef("OMPErrorDirective");
6219 case CXCursor_OMPTaskgroupDirective
:
6220 return cxstring::createRef("OMPTaskgroupDirective");
6221 case CXCursor_OMPFlushDirective
:
6222 return cxstring::createRef("OMPFlushDirective");
6223 case CXCursor_OMPDepobjDirective
:
6224 return cxstring::createRef("OMPDepobjDirective");
6225 case CXCursor_OMPScanDirective
:
6226 return cxstring::createRef("OMPScanDirective");
6227 case CXCursor_OMPOrderedDirective
:
6228 return cxstring::createRef("OMPOrderedDirective");
6229 case CXCursor_OMPAtomicDirective
:
6230 return cxstring::createRef("OMPAtomicDirective");
6231 case CXCursor_OMPTargetDirective
:
6232 return cxstring::createRef("OMPTargetDirective");
6233 case CXCursor_OMPTargetDataDirective
:
6234 return cxstring::createRef("OMPTargetDataDirective");
6235 case CXCursor_OMPTargetEnterDataDirective
:
6236 return cxstring::createRef("OMPTargetEnterDataDirective");
6237 case CXCursor_OMPTargetExitDataDirective
:
6238 return cxstring::createRef("OMPTargetExitDataDirective");
6239 case CXCursor_OMPTargetParallelDirective
:
6240 return cxstring::createRef("OMPTargetParallelDirective");
6241 case CXCursor_OMPTargetParallelForDirective
:
6242 return cxstring::createRef("OMPTargetParallelForDirective");
6243 case CXCursor_OMPTargetUpdateDirective
:
6244 return cxstring::createRef("OMPTargetUpdateDirective");
6245 case CXCursor_OMPTeamsDirective
:
6246 return cxstring::createRef("OMPTeamsDirective");
6247 case CXCursor_OMPCancellationPointDirective
:
6248 return cxstring::createRef("OMPCancellationPointDirective");
6249 case CXCursor_OMPCancelDirective
:
6250 return cxstring::createRef("OMPCancelDirective");
6251 case CXCursor_OMPTaskLoopDirective
:
6252 return cxstring::createRef("OMPTaskLoopDirective");
6253 case CXCursor_OMPTaskLoopSimdDirective
:
6254 return cxstring::createRef("OMPTaskLoopSimdDirective");
6255 case CXCursor_OMPMasterTaskLoopDirective
:
6256 return cxstring::createRef("OMPMasterTaskLoopDirective");
6257 case CXCursor_OMPMaskedTaskLoopDirective
:
6258 return cxstring::createRef("OMPMaskedTaskLoopDirective");
6259 case CXCursor_OMPMasterTaskLoopSimdDirective
:
6260 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
6261 case CXCursor_OMPMaskedTaskLoopSimdDirective
:
6262 return cxstring::createRef("OMPMaskedTaskLoopSimdDirective");
6263 case CXCursor_OMPParallelMasterTaskLoopDirective
:
6264 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
6265 case CXCursor_OMPParallelMaskedTaskLoopDirective
:
6266 return cxstring::createRef("OMPParallelMaskedTaskLoopDirective");
6267 case CXCursor_OMPParallelMasterTaskLoopSimdDirective
:
6268 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
6269 case CXCursor_OMPParallelMaskedTaskLoopSimdDirective
:
6270 return cxstring::createRef("OMPParallelMaskedTaskLoopSimdDirective");
6271 case CXCursor_OMPDistributeDirective
:
6272 return cxstring::createRef("OMPDistributeDirective");
6273 case CXCursor_OMPDistributeParallelForDirective
:
6274 return cxstring::createRef("OMPDistributeParallelForDirective");
6275 case CXCursor_OMPDistributeParallelForSimdDirective
:
6276 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
6277 case CXCursor_OMPDistributeSimdDirective
:
6278 return cxstring::createRef("OMPDistributeSimdDirective");
6279 case CXCursor_OMPTargetParallelForSimdDirective
:
6280 return cxstring::createRef("OMPTargetParallelForSimdDirective");
6281 case CXCursor_OMPTargetSimdDirective
:
6282 return cxstring::createRef("OMPTargetSimdDirective");
6283 case CXCursor_OMPTeamsDistributeDirective
:
6284 return cxstring::createRef("OMPTeamsDistributeDirective");
6285 case CXCursor_OMPTeamsDistributeSimdDirective
:
6286 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
6287 case CXCursor_OMPTeamsDistributeParallelForSimdDirective
:
6288 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
6289 case CXCursor_OMPTeamsDistributeParallelForDirective
:
6290 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
6291 case CXCursor_OMPTargetTeamsDirective
:
6292 return cxstring::createRef("OMPTargetTeamsDirective");
6293 case CXCursor_OMPTargetTeamsDistributeDirective
:
6294 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
6295 case CXCursor_OMPTargetTeamsDistributeParallelForDirective
:
6296 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
6297 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective
:
6298 return cxstring::createRef(
6299 "OMPTargetTeamsDistributeParallelForSimdDirective");
6300 case CXCursor_OMPTargetTeamsDistributeSimdDirective
:
6301 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
6302 case CXCursor_OMPInteropDirective
:
6303 return cxstring::createRef("OMPInteropDirective");
6304 case CXCursor_OMPDispatchDirective
:
6305 return cxstring::createRef("OMPDispatchDirective");
6306 case CXCursor_OMPMaskedDirective
:
6307 return cxstring::createRef("OMPMaskedDirective");
6308 case CXCursor_OMPGenericLoopDirective
:
6309 return cxstring::createRef("OMPGenericLoopDirective");
6310 case CXCursor_OMPTeamsGenericLoopDirective
:
6311 return cxstring::createRef("OMPTeamsGenericLoopDirective");
6312 case CXCursor_OMPTargetTeamsGenericLoopDirective
:
6313 return cxstring::createRef("OMPTargetTeamsGenericLoopDirective");
6314 case CXCursor_OMPParallelGenericLoopDirective
:
6315 return cxstring::createRef("OMPParallelGenericLoopDirective");
6316 case CXCursor_OMPTargetParallelGenericLoopDirective
:
6317 return cxstring::createRef("OMPTargetParallelGenericLoopDirective");
6318 case CXCursor_OverloadCandidate
:
6319 return cxstring::createRef("OverloadCandidate");
6320 case CXCursor_TypeAliasTemplateDecl
:
6321 return cxstring::createRef("TypeAliasTemplateDecl");
6322 case CXCursor_StaticAssert
:
6323 return cxstring::createRef("StaticAssert");
6324 case CXCursor_FriendDecl
:
6325 return cxstring::createRef("FriendDecl");
6326 case CXCursor_ConvergentAttr
:
6327 return cxstring::createRef("attribute(convergent)");
6328 case CXCursor_WarnUnusedAttr
:
6329 return cxstring::createRef("attribute(warn_unused)");
6330 case CXCursor_WarnUnusedResultAttr
:
6331 return cxstring::createRef("attribute(warn_unused_result)");
6332 case CXCursor_AlignedAttr
:
6333 return cxstring::createRef("attribute(aligned)");
6334 case CXCursor_ConceptDecl
:
6335 return cxstring::createRef("ConceptDecl");
6336 case CXCursor_OpenACCComputeConstruct
:
6337 return cxstring::createRef("OpenACCComputeConstruct");
6338 case CXCursor_OpenACCLoopConstruct
:
6339 return cxstring::createRef("OpenACCLoopConstruct");
6340 case CXCursor_OpenACCCombinedConstruct
:
6341 return cxstring::createRef("OpenACCCombinedConstruct");
6344 llvm_unreachable("Unhandled CXCursorKind");
6347 struct GetCursorData
{
6348 SourceLocation TokenBeginLoc
;
6349 bool PointsAtMacroArgExpansion
;
6350 bool VisitedObjCPropertyImplDecl
;
6351 SourceLocation VisitedDeclaratorDeclStartLoc
;
6352 CXCursor
&BestCursor
;
6354 GetCursorData(SourceManager
&SM
, SourceLocation tokenBegin
,
6355 CXCursor
&outputCursor
)
6356 : TokenBeginLoc(tokenBegin
), BestCursor(outputCursor
) {
6357 PointsAtMacroArgExpansion
= SM
.isMacroArgExpansion(tokenBegin
);
6358 VisitedObjCPropertyImplDecl
= false;
6362 static enum CXChildVisitResult
6363 GetCursorVisitor(CXCursor cursor
, CXCursor parent
, CXClientData client_data
) {
6364 GetCursorData
*Data
= static_cast<GetCursorData
*>(client_data
);
6365 CXCursor
*BestCursor
= &Data
->BestCursor
;
6367 // If we point inside a macro argument we should provide info of what the
6368 // token is so use the actual cursor, don't replace it with a macro expansion
6370 if (cursor
.kind
== CXCursor_MacroExpansion
&& Data
->PointsAtMacroArgExpansion
)
6371 return CXChildVisit_Recurse
;
6373 if (clang_isDeclaration(cursor
.kind
)) {
6374 // Avoid having the implicit methods override the property decls.
6375 if (const ObjCMethodDecl
*MD
=
6376 dyn_cast_or_null
<ObjCMethodDecl
>(getCursorDecl(cursor
))) {
6377 if (MD
->isImplicit())
6378 return CXChildVisit_Break
;
6380 } else if (const ObjCInterfaceDecl
*ID
=
6381 dyn_cast_or_null
<ObjCInterfaceDecl
>(getCursorDecl(cursor
))) {
6382 // Check that when we have multiple @class references in the same line,
6383 // that later ones do not override the previous ones.
6386 // source ranges for both start at '@', so 'Bar' will end up overriding
6387 // 'Foo' even though the cursor location was at 'Foo'.
6388 if (BestCursor
->kind
== CXCursor_ObjCInterfaceDecl
||
6389 BestCursor
->kind
== CXCursor_ObjCClassRef
)
6390 if (const ObjCInterfaceDecl
*PrevID
=
6391 dyn_cast_or_null
<ObjCInterfaceDecl
>(
6392 getCursorDecl(*BestCursor
))) {
6393 if (PrevID
!= ID
&& !PrevID
->isThisDeclarationADefinition() &&
6394 !ID
->isThisDeclarationADefinition())
6395 return CXChildVisit_Break
;
6398 } else if (const DeclaratorDecl
*DD
=
6399 dyn_cast_or_null
<DeclaratorDecl
>(getCursorDecl(cursor
))) {
6400 SourceLocation StartLoc
= DD
->getSourceRange().getBegin();
6401 // Check that when we have multiple declarators in the same line,
6402 // that later ones do not override the previous ones.
6405 // source ranges for both start at 'int', so 'Bar' will end up overriding
6406 // 'Foo' even though the cursor location was at 'Foo'.
6407 if (Data
->VisitedDeclaratorDeclStartLoc
== StartLoc
)
6408 return CXChildVisit_Break
;
6409 Data
->VisitedDeclaratorDeclStartLoc
= StartLoc
;
6411 } else if (const ObjCPropertyImplDecl
*PropImp
=
6412 dyn_cast_or_null
<ObjCPropertyImplDecl
>(
6413 getCursorDecl(cursor
))) {
6415 // Check that when we have multiple @synthesize in the same line,
6416 // that later ones do not override the previous ones.
6418 // @synthesize Foo, Bar;
6419 // source ranges for both start at '@', so 'Bar' will end up overriding
6420 // 'Foo' even though the cursor location was at 'Foo'.
6421 if (Data
->VisitedObjCPropertyImplDecl
)
6422 return CXChildVisit_Break
;
6423 Data
->VisitedObjCPropertyImplDecl
= true;
6427 if (clang_isExpression(cursor
.kind
) &&
6428 clang_isDeclaration(BestCursor
->kind
)) {
6429 if (const Decl
*D
= getCursorDecl(*BestCursor
)) {
6430 // Avoid having the cursor of an expression replace the declaration cursor
6431 // when the expression source range overlaps the declaration range.
6432 // This can happen for C++ constructor expressions whose range generally
6433 // include the variable declaration, e.g.:
6434 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
6436 if (D
->getLocation().isValid() && Data
->TokenBeginLoc
.isValid() &&
6437 D
->getLocation() == Data
->TokenBeginLoc
)
6438 return CXChildVisit_Break
;
6442 // If our current best cursor is the construction of a temporary object,
6443 // don't replace that cursor with a type reference, because we want
6444 // clang_getCursor() to point at the constructor.
6445 if (clang_isExpression(BestCursor
->kind
) &&
6446 isa
<CXXTemporaryObjectExpr
>(getCursorExpr(*BestCursor
)) &&
6447 cursor
.kind
== CXCursor_TypeRef
) {
6448 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
6449 // as having the actual point on the type reference.
6450 *BestCursor
= getTypeRefedCallExprCursor(*BestCursor
);
6451 return CXChildVisit_Recurse
;
6454 // If we already have an Objective-C superclass reference, don't
6455 // update it further.
6456 if (BestCursor
->kind
== CXCursor_ObjCSuperClassRef
)
6457 return CXChildVisit_Break
;
6459 *BestCursor
= cursor
;
6460 return CXChildVisit_Recurse
;
6463 CXCursor
clang_getCursor(CXTranslationUnit TU
, CXSourceLocation Loc
) {
6464 if (isNotUsableTU(TU
)) {
6466 return clang_getNullCursor();
6469 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
6470 ASTUnit::ConcurrencyCheck
Check(*CXXUnit
);
6472 SourceLocation SLoc
= cxloc::translateSourceLocation(Loc
);
6473 CXCursor Result
= cxcursor::getCursor(TU
, SLoc
);
6477 unsigned SearchLine
, SearchColumn
;
6479 unsigned ResultLine
, ResultColumn
;
6480 CXString SearchFileName
, ResultFileName
, KindSpelling
, USR
;
6481 const char *IsDef
= clang_isCursorDefinition(Result
) ? " (Definition)" : "";
6482 CXSourceLocation ResultLoc
= clang_getCursorLocation(Result
);
6484 clang_getFileLocation(Loc
, &SearchFile
, &SearchLine
, &SearchColumn
,
6486 clang_getFileLocation(ResultLoc
, &ResultFile
, &ResultLine
, &ResultColumn
,
6488 SearchFileName
= clang_getFileName(SearchFile
);
6489 ResultFileName
= clang_getFileName(ResultFile
);
6490 KindSpelling
= clang_getCursorKindSpelling(Result
.kind
);
6491 USR
= clang_getCursorUSR(Result
);
6492 *Log
<< llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName
),
6493 SearchLine
, SearchColumn
,
6494 clang_getCString(KindSpelling
))
6495 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName
),
6496 ResultLine
, ResultColumn
, clang_getCString(USR
),
6498 clang_disposeString(SearchFileName
);
6499 clang_disposeString(ResultFileName
);
6500 clang_disposeString(KindSpelling
);
6501 clang_disposeString(USR
);
6503 CXCursor Definition
= clang_getCursorDefinition(Result
);
6504 if (!clang_equalCursors(Definition
, clang_getNullCursor())) {
6505 CXSourceLocation DefinitionLoc
= clang_getCursorLocation(Definition
);
6506 CXString DefinitionKindSpelling
=
6507 clang_getCursorKindSpelling(Definition
.kind
);
6508 CXFile DefinitionFile
;
6509 unsigned DefinitionLine
, DefinitionColumn
;
6510 clang_getFileLocation(DefinitionLoc
, &DefinitionFile
, &DefinitionLine
,
6511 &DefinitionColumn
, nullptr);
6512 CXString DefinitionFileName
= clang_getFileName(DefinitionFile
);
6513 *Log
<< llvm::format(" -> %s(%s:%d:%d)",
6514 clang_getCString(DefinitionKindSpelling
),
6515 clang_getCString(DefinitionFileName
), DefinitionLine
,
6517 clang_disposeString(DefinitionFileName
);
6518 clang_disposeString(DefinitionKindSpelling
);
6525 CXCursor
clang_getNullCursor(void) {
6526 return MakeCXCursorInvalid(CXCursor_InvalidFile
);
6529 unsigned clang_equalCursors(CXCursor X
, CXCursor Y
) {
6530 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
6531 // can't set consistently. For example, when visiting a DeclStmt we will set
6532 // it but we don't set it on the result of clang_getCursorDefinition for
6533 // a reference of the same declaration.
6534 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
6535 // when visiting a DeclStmt currently, the AST should be enhanced to be able
6536 // to provide that kind of info.
6537 if (clang_isDeclaration(X
.kind
))
6538 X
.data
[1] = nullptr;
6539 if (clang_isDeclaration(Y
.kind
))
6540 Y
.data
[1] = nullptr;
6545 unsigned clang_hashCursor(CXCursor C
) {
6547 if (clang_isExpression(C
.kind
) || clang_isStatement(C
.kind
))
6550 return llvm::DenseMapInfo
<std::pair
<unsigned, const void *>>::getHashValue(
6551 std::make_pair(C
.kind
, C
.data
[Index
]));
6554 unsigned clang_isInvalid(enum CXCursorKind K
) {
6555 return K
>= CXCursor_FirstInvalid
&& K
<= CXCursor_LastInvalid
;
6558 unsigned clang_isDeclaration(enum CXCursorKind K
) {
6559 return (K
>= CXCursor_FirstDecl
&& K
<= CXCursor_LastDecl
) ||
6560 (K
>= CXCursor_FirstExtraDecl
&& K
<= CXCursor_LastExtraDecl
);
6563 unsigned clang_isInvalidDeclaration(CXCursor C
) {
6564 if (clang_isDeclaration(C
.kind
)) {
6565 if (const Decl
*D
= getCursorDecl(C
))
6566 return D
->isInvalidDecl();
6572 unsigned clang_isReference(enum CXCursorKind K
) {
6573 return K
>= CXCursor_FirstRef
&& K
<= CXCursor_LastRef
;
6576 unsigned clang_isExpression(enum CXCursorKind K
) {
6577 return K
>= CXCursor_FirstExpr
&& K
<= CXCursor_LastExpr
;
6580 unsigned clang_isStatement(enum CXCursorKind K
) {
6581 return K
>= CXCursor_FirstStmt
&& K
<= CXCursor_LastStmt
;
6584 unsigned clang_isAttribute(enum CXCursorKind K
) {
6585 return K
>= CXCursor_FirstAttr
&& K
<= CXCursor_LastAttr
;
6588 unsigned clang_isTranslationUnit(enum CXCursorKind K
) {
6589 return K
== CXCursor_TranslationUnit
;
6592 unsigned clang_isPreprocessing(enum CXCursorKind K
) {
6593 return K
>= CXCursor_FirstPreprocessing
&& K
<= CXCursor_LastPreprocessing
;
6596 unsigned clang_isUnexposed(enum CXCursorKind K
) {
6598 case CXCursor_UnexposedDecl
:
6599 case CXCursor_UnexposedExpr
:
6600 case CXCursor_UnexposedStmt
:
6601 case CXCursor_UnexposedAttr
:
6608 CXCursorKind
clang_getCursorKind(CXCursor C
) { return C
.kind
; }
6610 CXSourceLocation
clang_getCursorLocation(CXCursor C
) {
6611 if (clang_isReference(C
.kind
)) {
6613 case CXCursor_ObjCSuperClassRef
: {
6614 std::pair
<const ObjCInterfaceDecl
*, SourceLocation
> P
=
6615 getCursorObjCSuperClassRef(C
);
6616 return cxloc::translateSourceLocation(P
.first
->getASTContext(), P
.second
);
6619 case CXCursor_ObjCProtocolRef
: {
6620 std::pair
<const ObjCProtocolDecl
*, SourceLocation
> P
=
6621 getCursorObjCProtocolRef(C
);
6622 return cxloc::translateSourceLocation(P
.first
->getASTContext(), P
.second
);
6625 case CXCursor_ObjCClassRef
: {
6626 std::pair
<const ObjCInterfaceDecl
*, SourceLocation
> P
=
6627 getCursorObjCClassRef(C
);
6628 return cxloc::translateSourceLocation(P
.first
->getASTContext(), P
.second
);
6631 case CXCursor_TypeRef
: {
6632 std::pair
<const TypeDecl
*, SourceLocation
> P
= getCursorTypeRef(C
);
6633 return cxloc::translateSourceLocation(P
.first
->getASTContext(), P
.second
);
6636 case CXCursor_TemplateRef
: {
6637 std::pair
<const TemplateDecl
*, SourceLocation
> P
=
6638 getCursorTemplateRef(C
);
6639 return cxloc::translateSourceLocation(P
.first
->getASTContext(), P
.second
);
6642 case CXCursor_NamespaceRef
: {
6643 std::pair
<const NamedDecl
*, SourceLocation
> P
= getCursorNamespaceRef(C
);
6644 return cxloc::translateSourceLocation(P
.first
->getASTContext(), P
.second
);
6647 case CXCursor_MemberRef
: {
6648 std::pair
<const FieldDecl
*, SourceLocation
> P
= getCursorMemberRef(C
);
6649 return cxloc::translateSourceLocation(P
.first
->getASTContext(), P
.second
);
6652 case CXCursor_VariableRef
: {
6653 std::pair
<const VarDecl
*, SourceLocation
> P
= getCursorVariableRef(C
);
6654 return cxloc::translateSourceLocation(P
.first
->getASTContext(), P
.second
);
6657 case CXCursor_CXXBaseSpecifier
: {
6658 const CXXBaseSpecifier
*BaseSpec
= getCursorCXXBaseSpecifier(C
);
6660 return clang_getNullLocation();
6662 if (TypeSourceInfo
*TSInfo
= BaseSpec
->getTypeSourceInfo())
6663 return cxloc::translateSourceLocation(
6664 getCursorContext(C
), TSInfo
->getTypeLoc().getBeginLoc());
6666 return cxloc::translateSourceLocation(getCursorContext(C
),
6667 BaseSpec
->getBeginLoc());
6670 case CXCursor_LabelRef
: {
6671 std::pair
<const LabelStmt
*, SourceLocation
> P
= getCursorLabelRef(C
);
6672 return cxloc::translateSourceLocation(getCursorContext(C
), P
.second
);
6675 case CXCursor_OverloadedDeclRef
:
6676 return cxloc::translateSourceLocation(
6677 getCursorContext(C
), getCursorOverloadedDeclRef(C
).second
);
6680 // FIXME: Need a way to enumerate all non-reference cases.
6681 llvm_unreachable("Missed a reference kind");
6685 if (clang_isExpression(C
.kind
))
6686 return cxloc::translateSourceLocation(
6687 getCursorContext(C
), getLocationFromExpr(getCursorExpr(C
)));
6689 if (clang_isStatement(C
.kind
))
6690 return cxloc::translateSourceLocation(getCursorContext(C
),
6691 getCursorStmt(C
)->getBeginLoc());
6693 if (C
.kind
== CXCursor_PreprocessingDirective
) {
6694 SourceLocation L
= cxcursor::getCursorPreprocessingDirective(C
).getBegin();
6695 return cxloc::translateSourceLocation(getCursorContext(C
), L
);
6698 if (C
.kind
== CXCursor_MacroExpansion
) {
6700 cxcursor::getCursorMacroExpansion(C
).getSourceRange().getBegin();
6701 return cxloc::translateSourceLocation(getCursorContext(C
), L
);
6704 if (C
.kind
== CXCursor_MacroDefinition
) {
6705 SourceLocation L
= cxcursor::getCursorMacroDefinition(C
)->getLocation();
6706 return cxloc::translateSourceLocation(getCursorContext(C
), L
);
6709 if (C
.kind
== CXCursor_InclusionDirective
) {
6711 cxcursor::getCursorInclusionDirective(C
)->getSourceRange().getBegin();
6712 return cxloc::translateSourceLocation(getCursorContext(C
), L
);
6715 if (clang_isAttribute(C
.kind
)) {
6716 SourceLocation L
= cxcursor::getCursorAttr(C
)->getLocation();
6717 return cxloc::translateSourceLocation(getCursorContext(C
), L
);
6720 if (!clang_isDeclaration(C
.kind
))
6721 return clang_getNullLocation();
6723 const Decl
*D
= getCursorDecl(C
);
6725 return clang_getNullLocation();
6727 SourceLocation Loc
= D
->getLocation();
6728 // FIXME: Multiple variables declared in a single declaration
6729 // currently lack the information needed to correctly determine their
6730 // ranges when accounting for the type-specifier. We use context
6731 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6732 // and if so, whether it is the first decl.
6733 if (const VarDecl
*VD
= dyn_cast
<VarDecl
>(D
)) {
6734 if (!cxcursor::isFirstInDeclGroup(C
))
6735 Loc
= VD
->getLocation();
6738 // For ObjC methods, give the start location of the method name.
6739 if (const ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(D
))
6740 Loc
= MD
->getSelectorStartLoc();
6742 return cxloc::translateSourceLocation(getCursorContext(C
), Loc
);
6747 CXCursor
cxcursor::getCursor(CXTranslationUnit TU
, SourceLocation SLoc
) {
6750 // Guard against an invalid SourceLocation, or we may assert in one
6751 // of the following calls.
6752 if (SLoc
.isInvalid())
6753 return clang_getNullCursor();
6755 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
6757 // Translate the given source location to make it point at the beginning of
6758 // the token under the cursor.
6759 SLoc
= Lexer::GetBeginningOfToken(SLoc
, CXXUnit
->getSourceManager(),
6760 CXXUnit
->getASTContext().getLangOpts());
6762 CXCursor Result
= MakeCXCursorInvalid(CXCursor_NoDeclFound
);
6763 if (SLoc
.isValid()) {
6764 GetCursorData
ResultData(CXXUnit
->getSourceManager(), SLoc
, Result
);
6765 CursorVisitor
CursorVis(TU
, GetCursorVisitor
, &ResultData
,
6766 /*VisitPreprocessorLast=*/true,
6767 /*VisitIncludedEntities=*/false,
6768 SourceLocation(SLoc
));
6769 CursorVis
.visitFileRegion();
6775 static SourceRange
getRawCursorExtent(CXCursor C
) {
6776 if (clang_isReference(C
.kind
)) {
6778 case CXCursor_ObjCSuperClassRef
:
6779 return getCursorObjCSuperClassRef(C
).second
;
6781 case CXCursor_ObjCProtocolRef
:
6782 return getCursorObjCProtocolRef(C
).second
;
6784 case CXCursor_ObjCClassRef
:
6785 return getCursorObjCClassRef(C
).second
;
6787 case CXCursor_TypeRef
:
6788 return getCursorTypeRef(C
).second
;
6790 case CXCursor_TemplateRef
:
6791 return getCursorTemplateRef(C
).second
;
6793 case CXCursor_NamespaceRef
:
6794 return getCursorNamespaceRef(C
).second
;
6796 case CXCursor_MemberRef
:
6797 return getCursorMemberRef(C
).second
;
6799 case CXCursor_CXXBaseSpecifier
:
6800 return getCursorCXXBaseSpecifier(C
)->getSourceRange();
6802 case CXCursor_LabelRef
:
6803 return getCursorLabelRef(C
).second
;
6805 case CXCursor_OverloadedDeclRef
:
6806 return getCursorOverloadedDeclRef(C
).second
;
6808 case CXCursor_VariableRef
:
6809 return getCursorVariableRef(C
).second
;
6812 // FIXME: Need a way to enumerate all non-reference cases.
6813 llvm_unreachable("Missed a reference kind");
6817 if (clang_isExpression(C
.kind
))
6818 return getCursorExpr(C
)->getSourceRange();
6820 if (clang_isStatement(C
.kind
))
6821 return getCursorStmt(C
)->getSourceRange();
6823 if (clang_isAttribute(C
.kind
))
6824 return getCursorAttr(C
)->getRange();
6826 if (C
.kind
== CXCursor_PreprocessingDirective
)
6827 return cxcursor::getCursorPreprocessingDirective(C
);
6829 if (C
.kind
== CXCursor_MacroExpansion
) {
6830 ASTUnit
*TU
= getCursorASTUnit(C
);
6831 SourceRange Range
= cxcursor::getCursorMacroExpansion(C
).getSourceRange();
6832 return TU
->mapRangeFromPreamble(Range
);
6835 if (C
.kind
== CXCursor_MacroDefinition
) {
6836 ASTUnit
*TU
= getCursorASTUnit(C
);
6837 SourceRange Range
= cxcursor::getCursorMacroDefinition(C
)->getSourceRange();
6838 return TU
->mapRangeFromPreamble(Range
);
6841 if (C
.kind
== CXCursor_InclusionDirective
) {
6842 ASTUnit
*TU
= getCursorASTUnit(C
);
6844 cxcursor::getCursorInclusionDirective(C
)->getSourceRange();
6845 return TU
->mapRangeFromPreamble(Range
);
6848 if (C
.kind
== CXCursor_TranslationUnit
) {
6849 ASTUnit
*TU
= getCursorASTUnit(C
);
6850 FileID MainID
= TU
->getSourceManager().getMainFileID();
6851 SourceLocation Start
= TU
->getSourceManager().getLocForStartOfFile(MainID
);
6852 SourceLocation End
= TU
->getSourceManager().getLocForEndOfFile(MainID
);
6853 return SourceRange(Start
, End
);
6856 if (clang_isDeclaration(C
.kind
)) {
6857 const Decl
*D
= cxcursor::getCursorDecl(C
);
6859 return SourceRange();
6861 SourceRange R
= D
->getSourceRange();
6862 // FIXME: Multiple variables declared in a single declaration
6863 // currently lack the information needed to correctly determine their
6864 // ranges when accounting for the type-specifier. We use context
6865 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6866 // and if so, whether it is the first decl.
6867 if (const VarDecl
*VD
= dyn_cast
<VarDecl
>(D
)) {
6868 if (!cxcursor::isFirstInDeclGroup(C
))
6869 R
.setBegin(VD
->getLocation());
6873 return SourceRange();
6876 /// Retrieves the "raw" cursor extent, which is then extended to include
6877 /// the decl-specifier-seq for declarations.
6878 static SourceRange
getFullCursorExtent(CXCursor C
, SourceManager
&SrcMgr
) {
6879 if (clang_isDeclaration(C
.kind
)) {
6880 const Decl
*D
= cxcursor::getCursorDecl(C
);
6882 return SourceRange();
6884 SourceRange R
= D
->getSourceRange();
6886 // Adjust the start of the location for declarations preceded by
6887 // declaration specifiers.
6888 SourceLocation StartLoc
;
6889 if (const DeclaratorDecl
*DD
= dyn_cast
<DeclaratorDecl
>(D
)) {
6890 if (TypeSourceInfo
*TI
= DD
->getTypeSourceInfo())
6891 StartLoc
= TI
->getTypeLoc().getBeginLoc();
6892 } else if (const TypedefDecl
*Typedef
= dyn_cast
<TypedefDecl
>(D
)) {
6893 if (TypeSourceInfo
*TI
= Typedef
->getTypeSourceInfo())
6894 StartLoc
= TI
->getTypeLoc().getBeginLoc();
6897 if (StartLoc
.isValid() && R
.getBegin().isValid() &&
6898 SrcMgr
.isBeforeInTranslationUnit(StartLoc
, R
.getBegin()))
6899 R
.setBegin(StartLoc
);
6901 // FIXME: Multiple variables declared in a single declaration
6902 // currently lack the information needed to correctly determine their
6903 // ranges when accounting for the type-specifier. We use context
6904 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6905 // and if so, whether it is the first decl.
6906 if (const VarDecl
*VD
= dyn_cast
<VarDecl
>(D
)) {
6907 if (!cxcursor::isFirstInDeclGroup(C
))
6908 R
.setBegin(VD
->getLocation());
6914 return getRawCursorExtent(C
);
6917 CXSourceRange
clang_getCursorExtent(CXCursor C
) {
6918 SourceRange R
= getRawCursorExtent(C
);
6920 return clang_getNullRange();
6922 return cxloc::translateSourceRange(getCursorContext(C
), R
);
6925 CXCursor
clang_getCursorReferenced(CXCursor C
) {
6926 if (clang_isInvalid(C
.kind
))
6927 return clang_getNullCursor();
6929 CXTranslationUnit tu
= getCursorTU(C
);
6930 if (clang_isDeclaration(C
.kind
)) {
6931 const Decl
*D
= getCursorDecl(C
);
6933 return clang_getNullCursor();
6934 if (const UsingDecl
*Using
= dyn_cast
<UsingDecl
>(D
))
6935 return MakeCursorOverloadedDeclRef(Using
, D
->getLocation(), tu
);
6936 if (const ObjCPropertyImplDecl
*PropImpl
=
6937 dyn_cast
<ObjCPropertyImplDecl
>(D
))
6938 if (ObjCPropertyDecl
*Property
= PropImpl
->getPropertyDecl())
6939 return MakeCXCursor(Property
, tu
);
6944 if (clang_isExpression(C
.kind
)) {
6945 const Expr
*E
= getCursorExpr(C
);
6946 const Decl
*D
= getDeclFromExpr(E
);
6948 CXCursor declCursor
= MakeCXCursor(D
, tu
);
6949 declCursor
= getSelectorIdentifierCursor(getSelectorIdentifierIndex(C
),
6954 if (const OverloadExpr
*Ovl
= dyn_cast_or_null
<OverloadExpr
>(E
))
6955 return MakeCursorOverloadedDeclRef(Ovl
, tu
);
6957 return clang_getNullCursor();
6960 if (clang_isStatement(C
.kind
)) {
6961 const Stmt
*S
= getCursorStmt(C
);
6962 if (const GotoStmt
*Goto
= dyn_cast_or_null
<GotoStmt
>(S
))
6963 if (LabelDecl
*label
= Goto
->getLabel())
6964 if (LabelStmt
*labelS
= label
->getStmt())
6965 return MakeCXCursor(labelS
, getCursorDecl(C
), tu
);
6967 return clang_getNullCursor();
6970 if (C
.kind
== CXCursor_MacroExpansion
) {
6971 if (const MacroDefinitionRecord
*Def
=
6972 getCursorMacroExpansion(C
).getDefinition())
6973 return MakeMacroDefinitionCursor(Def
, tu
);
6976 if (!clang_isReference(C
.kind
))
6977 return clang_getNullCursor();
6980 case CXCursor_ObjCSuperClassRef
:
6981 return MakeCXCursor(getCursorObjCSuperClassRef(C
).first
, tu
);
6983 case CXCursor_ObjCProtocolRef
: {
6984 const ObjCProtocolDecl
*Prot
= getCursorObjCProtocolRef(C
).first
;
6985 if (const ObjCProtocolDecl
*Def
= Prot
->getDefinition())
6986 return MakeCXCursor(Def
, tu
);
6988 return MakeCXCursor(Prot
, tu
);
6991 case CXCursor_ObjCClassRef
: {
6992 const ObjCInterfaceDecl
*Class
= getCursorObjCClassRef(C
).first
;
6993 if (const ObjCInterfaceDecl
*Def
= Class
->getDefinition())
6994 return MakeCXCursor(Def
, tu
);
6996 return MakeCXCursor(Class
, tu
);
6999 case CXCursor_TypeRef
:
7000 return MakeCXCursor(getCursorTypeRef(C
).first
, tu
);
7002 case CXCursor_TemplateRef
:
7003 return MakeCXCursor(getCursorTemplateRef(C
).first
, tu
);
7005 case CXCursor_NamespaceRef
:
7006 return MakeCXCursor(getCursorNamespaceRef(C
).first
, tu
);
7008 case CXCursor_MemberRef
:
7009 return MakeCXCursor(getCursorMemberRef(C
).first
, tu
);
7011 case CXCursor_CXXBaseSpecifier
: {
7012 const CXXBaseSpecifier
*B
= cxcursor::getCursorCXXBaseSpecifier(C
);
7013 return clang_getTypeDeclaration(cxtype::MakeCXType(B
->getType(), tu
));
7016 case CXCursor_LabelRef
:
7017 // FIXME: We end up faking the "parent" declaration here because we
7018 // don't want to make CXCursor larger.
7019 return MakeCXCursor(
7020 getCursorLabelRef(C
).first
,
7021 cxtu::getASTUnit(tu
)->getASTContext().getTranslationUnitDecl(), tu
);
7023 case CXCursor_OverloadedDeclRef
:
7026 case CXCursor_VariableRef
:
7027 return MakeCXCursor(getCursorVariableRef(C
).first
, tu
);
7030 // We would prefer to enumerate all non-reference cursor kinds here.
7031 llvm_unreachable("Unhandled reference cursor kind");
7035 CXCursor
clang_getCursorDefinition(CXCursor C
) {
7036 if (clang_isInvalid(C
.kind
))
7037 return clang_getNullCursor();
7039 CXTranslationUnit TU
= getCursorTU(C
);
7041 bool WasReference
= false;
7042 if (clang_isReference(C
.kind
) || clang_isExpression(C
.kind
)) {
7043 C
= clang_getCursorReferenced(C
);
7044 WasReference
= true;
7047 if (C
.kind
== CXCursor_MacroExpansion
)
7048 return clang_getCursorReferenced(C
);
7050 if (!clang_isDeclaration(C
.kind
))
7051 return clang_getNullCursor();
7053 const Decl
*D
= getCursorDecl(C
);
7055 return clang_getNullCursor();
7057 switch (D
->getKind()) {
7058 // Declaration kinds that don't really separate the notions of
7059 // declaration and definition.
7060 case Decl::Namespace
:
7062 case Decl::TypeAlias
:
7063 case Decl::TypeAliasTemplate
:
7064 case Decl::TemplateTypeParm
:
7065 case Decl::EnumConstant
:
7068 case Decl::MSProperty
:
7070 case Decl::HLSLBuffer
:
7071 case Decl::UnnamedGlobalConstant
:
7072 case Decl::TemplateParamObject
:
7073 case Decl::IndirectField
:
7074 case Decl::ObjCIvar
:
7075 case Decl::ObjCAtDefsField
:
7076 case Decl::ImplicitParam
:
7078 case Decl::NonTypeTemplateParm
:
7079 case Decl::TemplateTemplateParm
:
7080 case Decl::ObjCCategoryImpl
:
7081 case Decl::ObjCImplementation
:
7082 case Decl::AccessSpec
:
7083 case Decl::LinkageSpec
:
7085 case Decl::ObjCPropertyImpl
:
7086 case Decl::FileScopeAsm
:
7087 case Decl::TopLevelStmt
:
7088 case Decl::StaticAssert
:
7090 case Decl::Captured
:
7091 case Decl::OMPCapturedExpr
:
7092 case Decl::Label
: // FIXME: Is this right??
7093 case Decl::CXXDeductionGuide
:
7095 case Decl::OMPThreadPrivate
:
7096 case Decl::OMPAllocate
:
7097 case Decl::OMPDeclareReduction
:
7098 case Decl::OMPDeclareMapper
:
7099 case Decl::OMPRequires
:
7100 case Decl::ObjCTypeParam
:
7101 case Decl::BuiltinTemplate
:
7102 case Decl::PragmaComment
:
7103 case Decl::PragmaDetectMismatch
:
7104 case Decl::UsingPack
:
7106 case Decl::ImplicitConceptSpecialization
:
7107 case Decl::LifetimeExtendedTemporary
:
7108 case Decl::RequiresExprBody
:
7109 case Decl::UnresolvedUsingIfExists
:
7112 // Declaration kinds that don't make any sense here, but are
7113 // nonetheless harmless.
7115 case Decl::TranslationUnit
:
7116 case Decl::ExternCContext
:
7119 // Declaration kinds for which the definition is not resolvable.
7120 case Decl::UnresolvedUsingTypename
:
7121 case Decl::UnresolvedUsingValue
:
7124 case Decl::UsingDirective
:
7125 return MakeCXCursor(cast
<UsingDirectiveDecl
>(D
)->getNominatedNamespace(),
7128 case Decl::NamespaceAlias
:
7129 return MakeCXCursor(cast
<NamespaceAliasDecl
>(D
)->getNamespace(), TU
);
7133 case Decl::CXXRecord
:
7134 case Decl::ClassTemplateSpecialization
:
7135 case Decl::ClassTemplatePartialSpecialization
:
7136 if (TagDecl
*Def
= cast
<TagDecl
>(D
)->getDefinition())
7137 return MakeCXCursor(Def
, TU
);
7138 return clang_getNullCursor();
7140 case Decl::Function
:
7141 case Decl::CXXMethod
:
7142 case Decl::CXXConstructor
:
7143 case Decl::CXXDestructor
:
7144 case Decl::CXXConversion
: {
7145 const FunctionDecl
*Def
= nullptr;
7146 if (cast
<FunctionDecl
>(D
)->getBody(Def
))
7147 return MakeCXCursor(Def
, TU
);
7148 return clang_getNullCursor();
7152 case Decl::VarTemplateSpecialization
:
7153 case Decl::VarTemplatePartialSpecialization
:
7154 case Decl::Decomposition
: {
7155 // Ask the variable if it has a definition.
7156 if (const VarDecl
*Def
= cast
<VarDecl
>(D
)->getDefinition())
7157 return MakeCXCursor(Def
, TU
);
7158 return clang_getNullCursor();
7161 case Decl::FunctionTemplate
: {
7162 const FunctionDecl
*Def
= nullptr;
7163 if (cast
<FunctionTemplateDecl
>(D
)->getTemplatedDecl()->getBody(Def
))
7164 return MakeCXCursor(Def
->getDescribedFunctionTemplate(), TU
);
7165 return clang_getNullCursor();
7168 case Decl::ClassTemplate
: {
7169 if (RecordDecl
*Def
=
7170 cast
<ClassTemplateDecl
>(D
)->getTemplatedDecl()->getDefinition())
7171 return MakeCXCursor(cast
<CXXRecordDecl
>(Def
)->getDescribedClassTemplate(),
7173 return clang_getNullCursor();
7176 case Decl::VarTemplate
: {
7178 cast
<VarTemplateDecl
>(D
)->getTemplatedDecl()->getDefinition())
7179 return MakeCXCursor(cast
<VarDecl
>(Def
)->getDescribedVarTemplate(), TU
);
7180 return clang_getNullCursor();
7184 case Decl::UsingEnum
:
7185 return MakeCursorOverloadedDeclRef(cast
<BaseUsingDecl
>(D
), D
->getLocation(),
7188 case Decl::UsingShadow
:
7189 case Decl::ConstructorUsingShadow
:
7190 return clang_getCursorDefinition(
7191 MakeCXCursor(cast
<UsingShadowDecl
>(D
)->getTargetDecl(), TU
));
7193 case Decl::ObjCMethod
: {
7194 const ObjCMethodDecl
*Method
= cast
<ObjCMethodDecl
>(D
);
7195 if (Method
->isThisDeclarationADefinition())
7198 // Dig out the method definition in the associated
7199 // @implementation, if we have it.
7200 // FIXME: The ASTs should make finding the definition easier.
7201 if (const ObjCInterfaceDecl
*Class
=
7202 dyn_cast
<ObjCInterfaceDecl
>(Method
->getDeclContext()))
7203 if (ObjCImplementationDecl
*ClassImpl
= Class
->getImplementation())
7204 if (ObjCMethodDecl
*Def
= ClassImpl
->getMethod(
7205 Method
->getSelector(), Method
->isInstanceMethod()))
7206 if (Def
->isThisDeclarationADefinition())
7207 return MakeCXCursor(Def
, TU
);
7209 return clang_getNullCursor();
7212 case Decl::ObjCCategory
:
7213 if (ObjCCategoryImplDecl
*Impl
=
7214 cast
<ObjCCategoryDecl
>(D
)->getImplementation())
7215 return MakeCXCursor(Impl
, TU
);
7216 return clang_getNullCursor();
7218 case Decl::ObjCProtocol
:
7219 if (const ObjCProtocolDecl
*Def
=
7220 cast
<ObjCProtocolDecl
>(D
)->getDefinition())
7221 return MakeCXCursor(Def
, TU
);
7222 return clang_getNullCursor();
7224 case Decl::ObjCInterface
: {
7225 // There are two notions of a "definition" for an Objective-C
7226 // class: the interface and its implementation. When we resolved a
7227 // reference to an Objective-C class, produce the @interface as
7228 // the definition; when we were provided with the interface,
7229 // produce the @implementation as the definition.
7230 const ObjCInterfaceDecl
*IFace
= cast
<ObjCInterfaceDecl
>(D
);
7232 if (const ObjCInterfaceDecl
*Def
= IFace
->getDefinition())
7233 return MakeCXCursor(Def
, TU
);
7234 } else if (ObjCImplementationDecl
*Impl
= IFace
->getImplementation())
7235 return MakeCXCursor(Impl
, TU
);
7236 return clang_getNullCursor();
7239 case Decl::ObjCProperty
:
7240 // FIXME: We don't really know where to find the
7241 // ObjCPropertyImplDecls that implement this property.
7242 return clang_getNullCursor();
7244 case Decl::ObjCCompatibleAlias
:
7245 if (const ObjCInterfaceDecl
*Class
=
7246 cast
<ObjCCompatibleAliasDecl
>(D
)->getClassInterface())
7247 if (const ObjCInterfaceDecl
*Def
= Class
->getDefinition())
7248 return MakeCXCursor(Def
, TU
);
7250 return clang_getNullCursor();
7253 if (NamedDecl
*Friend
= cast
<FriendDecl
>(D
)->getFriendDecl())
7254 return clang_getCursorDefinition(MakeCXCursor(Friend
, TU
));
7255 return clang_getNullCursor();
7257 case Decl::FriendTemplate
:
7258 if (NamedDecl
*Friend
= cast
<FriendTemplateDecl
>(D
)->getFriendDecl())
7259 return clang_getCursorDefinition(MakeCXCursor(Friend
, TU
));
7260 return clang_getNullCursor();
7263 return clang_getNullCursor();
7266 unsigned clang_isCursorDefinition(CXCursor C
) {
7267 if (!clang_isDeclaration(C
.kind
))
7270 return clang_getCursorDefinition(C
) == C
;
7273 CXCursor
clang_getCanonicalCursor(CXCursor C
) {
7274 if (!clang_isDeclaration(C
.kind
))
7277 if (const Decl
*D
= getCursorDecl(C
)) {
7278 if (const ObjCCategoryImplDecl
*CatImplD
=
7279 dyn_cast
<ObjCCategoryImplDecl
>(D
))
7280 if (ObjCCategoryDecl
*CatD
= CatImplD
->getCategoryDecl())
7281 return MakeCXCursor(CatD
, getCursorTU(C
));
7283 if (const ObjCImplDecl
*ImplD
= dyn_cast
<ObjCImplDecl
>(D
))
7284 if (const ObjCInterfaceDecl
*IFD
= ImplD
->getClassInterface())
7285 return MakeCXCursor(IFD
, getCursorTU(C
));
7287 return MakeCXCursor(D
->getCanonicalDecl(), getCursorTU(C
));
7293 int clang_Cursor_getObjCSelectorIndex(CXCursor cursor
) {
7294 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor
).first
;
7297 unsigned clang_getNumOverloadedDecls(CXCursor C
) {
7298 if (C
.kind
!= CXCursor_OverloadedDeclRef
)
7301 OverloadedDeclRefStorage Storage
= getCursorOverloadedDeclRef(C
).first
;
7302 if (const OverloadExpr
*E
= Storage
.dyn_cast
<const OverloadExpr
*>())
7303 return E
->getNumDecls();
7305 if (OverloadedTemplateStorage
*S
=
7306 Storage
.dyn_cast
<OverloadedTemplateStorage
*>())
7309 const Decl
*D
= Storage
.get
<const Decl
*>();
7310 if (const UsingDecl
*Using
= dyn_cast
<UsingDecl
>(D
))
7311 return Using
->shadow_size();
7316 CXCursor
clang_getOverloadedDecl(CXCursor cursor
, unsigned index
) {
7317 if (cursor
.kind
!= CXCursor_OverloadedDeclRef
)
7318 return clang_getNullCursor();
7320 if (index
>= clang_getNumOverloadedDecls(cursor
))
7321 return clang_getNullCursor();
7323 CXTranslationUnit TU
= getCursorTU(cursor
);
7324 OverloadedDeclRefStorage Storage
= getCursorOverloadedDeclRef(cursor
).first
;
7325 if (const OverloadExpr
*E
= Storage
.dyn_cast
<const OverloadExpr
*>())
7326 return MakeCXCursor(E
->decls_begin()[index
], TU
);
7328 if (OverloadedTemplateStorage
*S
=
7329 Storage
.dyn_cast
<OverloadedTemplateStorage
*>())
7330 return MakeCXCursor(S
->begin()[index
], TU
);
7332 const Decl
*D
= Storage
.get
<const Decl
*>();
7333 if (const UsingDecl
*Using
= dyn_cast
<UsingDecl
>(D
)) {
7334 // FIXME: This is, unfortunately, linear time.
7335 UsingDecl::shadow_iterator Pos
= Using
->shadow_begin();
7336 std::advance(Pos
, index
);
7337 return MakeCXCursor(cast
<UsingShadowDecl
>(*Pos
)->getTargetDecl(), TU
);
7340 return clang_getNullCursor();
7343 void clang_getDefinitionSpellingAndExtent(
7344 CXCursor C
, const char **startBuf
, const char **endBuf
, unsigned *startLine
,
7345 unsigned *startColumn
, unsigned *endLine
, unsigned *endColumn
) {
7346 assert(getCursorDecl(C
) && "CXCursor has null decl");
7347 const auto *FD
= cast
<FunctionDecl
>(getCursorDecl(C
));
7348 const auto *Body
= cast
<CompoundStmt
>(FD
->getBody());
7350 SourceManager
&SM
= FD
->getASTContext().getSourceManager();
7351 *startBuf
= SM
.getCharacterData(Body
->getLBracLoc());
7352 *endBuf
= SM
.getCharacterData(Body
->getRBracLoc());
7353 *startLine
= SM
.getSpellingLineNumber(Body
->getLBracLoc());
7354 *startColumn
= SM
.getSpellingColumnNumber(Body
->getLBracLoc());
7355 *endLine
= SM
.getSpellingLineNumber(Body
->getRBracLoc());
7356 *endColumn
= SM
.getSpellingColumnNumber(Body
->getRBracLoc());
7359 CXSourceRange
clang_getCursorReferenceNameRange(CXCursor C
, unsigned NameFlags
,
7360 unsigned PieceIndex
) {
7361 RefNamePieces Pieces
;
7364 case CXCursor_MemberRefExpr
:
7365 if (const MemberExpr
*E
= dyn_cast
<MemberExpr
>(getCursorExpr(C
)))
7366 Pieces
= buildPieces(NameFlags
, true, E
->getMemberNameInfo(),
7367 E
->getQualifierLoc().getSourceRange());
7370 case CXCursor_DeclRefExpr
:
7371 if (const DeclRefExpr
*E
= dyn_cast
<DeclRefExpr
>(getCursorExpr(C
))) {
7372 SourceRange
TemplateArgLoc(E
->getLAngleLoc(), E
->getRAngleLoc());
7374 buildPieces(NameFlags
, false, E
->getNameInfo(),
7375 E
->getQualifierLoc().getSourceRange(), &TemplateArgLoc
);
7379 case CXCursor_CallExpr
:
7380 if (const CXXOperatorCallExpr
*OCE
=
7381 dyn_cast
<CXXOperatorCallExpr
>(getCursorExpr(C
))) {
7382 const Expr
*Callee
= OCE
->getCallee();
7383 if (const ImplicitCastExpr
*ICE
= dyn_cast
<ImplicitCastExpr
>(Callee
))
7384 Callee
= ICE
->getSubExpr();
7386 if (const DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(Callee
))
7387 Pieces
= buildPieces(NameFlags
, false, DRE
->getNameInfo(),
7388 DRE
->getQualifierLoc().getSourceRange());
7396 if (Pieces
.empty()) {
7397 if (PieceIndex
== 0)
7398 return clang_getCursorExtent(C
);
7399 } else if (PieceIndex
< Pieces
.size()) {
7400 SourceRange R
= Pieces
[PieceIndex
];
7402 return cxloc::translateSourceRange(getCursorContext(C
), R
);
7405 return clang_getNullRange();
7408 void clang_enableStackTraces(void) {
7409 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
7410 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
7413 void clang_executeOnThread(void (*fn
)(void *), void *user_data
,
7414 unsigned stack_size
) {
7415 llvm::thread
Thread(stack_size
== 0 ? clang::DesiredStackSize
7416 : std::optional
<unsigned>(stack_size
),
7421 //===----------------------------------------------------------------------===//
7422 // Token-based Operations.
7423 //===----------------------------------------------------------------------===//
7426 * int_data[0]: a CXTokenKind
7427 * int_data[1]: starting token location
7428 * int_data[2]: token length
7429 * int_data[3]: reserved
7430 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
7433 CXTokenKind
clang_getTokenKind(CXToken CXTok
) {
7434 return static_cast<CXTokenKind
>(CXTok
.int_data
[0]);
7437 CXString
clang_getTokenSpelling(CXTranslationUnit TU
, CXToken CXTok
) {
7438 switch (clang_getTokenKind(CXTok
)) {
7439 case CXToken_Identifier
:
7440 case CXToken_Keyword
:
7441 // We know we have an IdentifierInfo*, so use that.
7442 return cxstring::createRef(
7443 static_cast<IdentifierInfo
*>(CXTok
.ptr_data
)->getNameStart());
7445 case CXToken_Literal
: {
7446 // We have stashed the starting pointer in the ptr_data field. Use it.
7447 const char *Text
= static_cast<const char *>(CXTok
.ptr_data
);
7448 return cxstring::createDup(StringRef(Text
, CXTok
.int_data
[2]));
7451 case CXToken_Punctuation
:
7452 case CXToken_Comment
:
7456 if (isNotUsableTU(TU
)) {
7458 return cxstring::createEmpty();
7461 // We have to find the starting buffer pointer the hard way, by
7462 // deconstructing the source location.
7463 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
7465 return cxstring::createEmpty();
7467 SourceLocation Loc
= SourceLocation::getFromRawEncoding(CXTok
.int_data
[1]);
7468 std::pair
<FileID
, unsigned> LocInfo
=
7469 CXXUnit
->getSourceManager().getDecomposedSpellingLoc(Loc
);
7470 bool Invalid
= false;
7472 CXXUnit
->getSourceManager().getBufferData(LocInfo
.first
, &Invalid
);
7474 return cxstring::createEmpty();
7476 return cxstring::createDup(Buffer
.substr(LocInfo
.second
, CXTok
.int_data
[2]));
7479 CXSourceLocation
clang_getTokenLocation(CXTranslationUnit TU
, CXToken CXTok
) {
7480 if (isNotUsableTU(TU
)) {
7482 return clang_getNullLocation();
7485 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
7487 return clang_getNullLocation();
7489 return cxloc::translateSourceLocation(
7490 CXXUnit
->getASTContext(),
7491 SourceLocation::getFromRawEncoding(CXTok
.int_data
[1]));
7494 CXSourceRange
clang_getTokenExtent(CXTranslationUnit TU
, CXToken CXTok
) {
7495 if (isNotUsableTU(TU
)) {
7497 return clang_getNullRange();
7500 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
7502 return clang_getNullRange();
7504 return cxloc::translateSourceRange(
7505 CXXUnit
->getASTContext(),
7506 SourceLocation::getFromRawEncoding(CXTok
.int_data
[1]));
7509 static void getTokens(ASTUnit
*CXXUnit
, SourceRange Range
,
7510 SmallVectorImpl
<CXToken
> &CXTokens
) {
7511 SourceManager
&SourceMgr
= CXXUnit
->getSourceManager();
7512 std::pair
<FileID
, unsigned> BeginLocInfo
=
7513 SourceMgr
.getDecomposedSpellingLoc(Range
.getBegin());
7514 std::pair
<FileID
, unsigned> EndLocInfo
=
7515 SourceMgr
.getDecomposedSpellingLoc(Range
.getEnd());
7517 // Cannot tokenize across files.
7518 if (BeginLocInfo
.first
!= EndLocInfo
.first
)
7522 bool Invalid
= false;
7523 StringRef Buffer
= SourceMgr
.getBufferData(BeginLocInfo
.first
, &Invalid
);
7527 Lexer
Lex(SourceMgr
.getLocForStartOfFile(BeginLocInfo
.first
),
7528 CXXUnit
->getASTContext().getLangOpts(), Buffer
.begin(),
7529 Buffer
.data() + BeginLocInfo
.second
, Buffer
.end());
7530 Lex
.SetCommentRetentionState(true);
7532 // Lex tokens until we hit the end of the range.
7533 const char *EffectiveBufferEnd
= Buffer
.data() + EndLocInfo
.second
;
7535 bool previousWasAt
= false;
7537 // Lex the next token
7538 Lex
.LexFromRawLexer(Tok
);
7539 if (Tok
.is(tok::eof
))
7542 // Initialize the CXToken.
7546 CXTok
.int_data
[1] = Tok
.getLocation().getRawEncoding();
7547 CXTok
.int_data
[2] = Tok
.getLength();
7548 CXTok
.int_data
[3] = 0;
7550 // - Kind-specific fields
7551 if (Tok
.isLiteral()) {
7552 CXTok
.int_data
[0] = CXToken_Literal
;
7553 CXTok
.ptr_data
= const_cast<char *>(Tok
.getLiteralData());
7554 } else if (Tok
.is(tok::raw_identifier
)) {
7555 // Lookup the identifier to determine whether we have a keyword.
7556 IdentifierInfo
*II
= CXXUnit
->getPreprocessor().LookUpIdentifierInfo(Tok
);
7558 if ((II
->getObjCKeywordID() != tok::objc_not_keyword
) && previousWasAt
) {
7559 CXTok
.int_data
[0] = CXToken_Keyword
;
7562 Tok
.is(tok::identifier
) ? CXToken_Identifier
: CXToken_Keyword
;
7564 CXTok
.ptr_data
= II
;
7565 } else if (Tok
.is(tok::comment
)) {
7566 CXTok
.int_data
[0] = CXToken_Comment
;
7567 CXTok
.ptr_data
= nullptr;
7569 CXTok
.int_data
[0] = CXToken_Punctuation
;
7570 CXTok
.ptr_data
= nullptr;
7572 CXTokens
.push_back(CXTok
);
7573 previousWasAt
= Tok
.is(tok::at
);
7574 } while (Lex
.getBufferLocation() < EffectiveBufferEnd
);
7577 CXToken
*clang_getToken(CXTranslationUnit TU
, CXSourceLocation Location
) {
7578 LOG_FUNC_SECTION
{ *Log
<< TU
<< ' ' << Location
; }
7580 if (isNotUsableTU(TU
)) {
7585 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
7589 SourceLocation Begin
= cxloc::translateSourceLocation(Location
);
7590 if (Begin
.isInvalid())
7592 SourceManager
&SM
= CXXUnit
->getSourceManager();
7593 std::pair
<FileID
, unsigned> DecomposedEnd
= SM
.getDecomposedLoc(Begin
);
7594 DecomposedEnd
.second
+=
7595 Lexer::MeasureTokenLength(Begin
, SM
, CXXUnit
->getLangOpts());
7597 SourceLocation End
=
7598 SM
.getComposedLoc(DecomposedEnd
.first
, DecomposedEnd
.second
);
7600 SmallVector
<CXToken
, 32> CXTokens
;
7601 getTokens(CXXUnit
, SourceRange(Begin
, End
), CXTokens
);
7603 if (CXTokens
.empty())
7607 CXToken
*Token
= static_cast<CXToken
*>(llvm::safe_malloc(sizeof(CXToken
)));
7609 memmove(Token
, CXTokens
.data(), sizeof(CXToken
));
7613 void clang_tokenize(CXTranslationUnit TU
, CXSourceRange Range
, CXToken
**Tokens
,
7614 unsigned *NumTokens
) {
7615 LOG_FUNC_SECTION
{ *Log
<< TU
<< ' ' << Range
; }
7622 if (isNotUsableTU(TU
)) {
7627 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
7628 if (!CXXUnit
|| !Tokens
|| !NumTokens
)
7631 ASTUnit::ConcurrencyCheck
Check(*CXXUnit
);
7633 SourceRange R
= cxloc::translateCXSourceRange(Range
);
7637 SmallVector
<CXToken
, 32> CXTokens
;
7638 getTokens(CXXUnit
, R
, CXTokens
);
7640 if (CXTokens
.empty())
7643 *Tokens
= static_cast<CXToken
*>(
7644 llvm::safe_malloc(sizeof(CXToken
) * CXTokens
.size()));
7645 memmove(*Tokens
, CXTokens
.data(), sizeof(CXToken
) * CXTokens
.size());
7646 *NumTokens
= CXTokens
.size();
7649 void clang_disposeTokens(CXTranslationUnit TU
, CXToken
*Tokens
,
7650 unsigned NumTokens
) {
7654 //===----------------------------------------------------------------------===//
7655 // Token annotation APIs.
7656 //===----------------------------------------------------------------------===//
7658 static enum CXChildVisitResult
AnnotateTokensVisitor(CXCursor cursor
,
7660 CXClientData client_data
);
7661 static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor
,
7662 CXClientData client_data
);
7665 class AnnotateTokensWorker
{
7670 unsigned PreprocessingTokIdx
;
7671 CursorVisitor AnnotateVis
;
7672 SourceManager
&SrcMgr
;
7673 bool HasContextSensitiveKeywords
;
7675 struct PostChildrenAction
{
7677 enum Action
{ Invalid
, Ignore
, Postpone
} action
;
7679 using PostChildrenActions
= SmallVector
<PostChildrenAction
, 0>;
7681 struct PostChildrenInfo
{
7683 SourceRange CursorRange
;
7684 unsigned BeforeReachingCursorIdx
;
7685 unsigned BeforeChildrenTokenIdx
;
7686 PostChildrenActions ChildActions
;
7688 SmallVector
<PostChildrenInfo
, 8> PostChildrenInfos
;
7690 CXToken
&getTok(unsigned Idx
) {
7691 assert(Idx
< NumTokens
);
7694 const CXToken
&getTok(unsigned Idx
) const {
7695 assert(Idx
< NumTokens
);
7698 bool MoreTokens() const { return TokIdx
< NumTokens
; }
7699 unsigned NextToken() const { return TokIdx
; }
7700 void AdvanceToken() { ++TokIdx
; }
7701 SourceLocation
GetTokenLoc(unsigned tokI
) {
7702 return SourceLocation::getFromRawEncoding(getTok(tokI
).int_data
[1]);
7704 bool isFunctionMacroToken(unsigned tokI
) const {
7705 return getTok(tokI
).int_data
[3] != 0;
7707 SourceLocation
getFunctionMacroTokenLoc(unsigned tokI
) const {
7708 return SourceLocation::getFromRawEncoding(getTok(tokI
).int_data
[3]);
7711 void annotateAndAdvanceTokens(CXCursor
, RangeComparisonResult
, SourceRange
);
7712 bool annotateAndAdvanceFunctionMacroTokens(CXCursor
, RangeComparisonResult
,
7716 AnnotateTokensWorker(CXToken
*tokens
, CXCursor
*cursors
, unsigned numTokens
,
7717 CXTranslationUnit TU
, SourceRange RegionOfInterest
)
7718 : Tokens(tokens
), Cursors(cursors
), NumTokens(numTokens
), TokIdx(0),
7719 PreprocessingTokIdx(0),
7720 AnnotateVis(TU
, AnnotateTokensVisitor
, this,
7721 /*VisitPreprocessorLast=*/true,
7722 /*VisitIncludedEntities=*/false, RegionOfInterest
,
7723 /*VisitDeclsOnly=*/false,
7724 AnnotateTokensPostChildrenVisitor
),
7725 SrcMgr(cxtu::getASTUnit(TU
)->getSourceManager()),
7726 HasContextSensitiveKeywords(false) {}
7728 void VisitChildren(CXCursor C
) { AnnotateVis
.VisitChildren(C
); }
7729 enum CXChildVisitResult
Visit(CXCursor cursor
, CXCursor parent
);
7730 bool IsIgnoredChildCursor(CXCursor cursor
) const;
7731 PostChildrenActions
DetermineChildActions(CXCursor Cursor
) const;
7733 bool postVisitChildren(CXCursor cursor
);
7734 void HandlePostPonedChildCursors(const PostChildrenInfo
&Info
);
7735 void HandlePostPonedChildCursor(CXCursor Cursor
, unsigned StartTokenIndex
);
7737 void AnnotateTokens();
7739 /// Determine whether the annotator saw any cursors that have
7740 /// context-sensitive keywords.
7741 bool hasContextSensitiveKeywords() const {
7742 return HasContextSensitiveKeywords
;
7745 ~AnnotateTokensWorker() { assert(PostChildrenInfos
.empty()); }
7749 void AnnotateTokensWorker::AnnotateTokens() {
7750 // Walk the AST within the region of interest, annotating tokens
7752 AnnotateVis
.visitFileRegion();
7755 bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor
) const {
7756 if (PostChildrenInfos
.empty())
7759 for (const auto &ChildAction
: PostChildrenInfos
.back().ChildActions
) {
7760 if (ChildAction
.cursor
== cursor
&&
7761 ChildAction
.action
== PostChildrenAction::Ignore
) {
7769 const CXXOperatorCallExpr
*GetSubscriptOrCallOperator(CXCursor Cursor
) {
7770 if (!clang_isExpression(Cursor
.kind
))
7773 const Expr
*E
= getCursorExpr(Cursor
);
7774 if (const auto *OCE
= dyn_cast
<CXXOperatorCallExpr
>(E
)) {
7775 const OverloadedOperatorKind Kind
= OCE
->getOperator();
7776 if (Kind
== OO_Call
|| Kind
== OO_Subscript
)
7783 AnnotateTokensWorker::PostChildrenActions
7784 AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor
) const {
7785 PostChildrenActions actions
;
7787 // The DeclRefExpr of CXXOperatorCallExpr referring to the custom operator is
7788 // visited before the arguments to the operator call. For the Call and
7789 // Subscript operator the range of this DeclRefExpr includes the whole call
7790 // expression, so that all tokens in that range would be mapped to the
7791 // operator function, including the tokens of the arguments. To avoid that,
7792 // ensure to visit this DeclRefExpr as last node.
7793 if (const auto *OCE
= GetSubscriptOrCallOperator(Cursor
)) {
7794 const Expr
*Callee
= OCE
->getCallee();
7795 if (const ImplicitCastExpr
*ICE
= dyn_cast
<ImplicitCastExpr
>(Callee
)) {
7796 const Expr
*SubExpr
= ICE
->getSubExpr();
7797 if (const DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(SubExpr
)) {
7798 const Decl
*parentDecl
= getCursorDecl(Cursor
);
7799 CXTranslationUnit TU
= clang_Cursor_getTranslationUnit(Cursor
);
7801 // Visit the DeclRefExpr as last.
7802 CXCursor cxChild
= MakeCXCursor(DRE
, parentDecl
, TU
);
7803 actions
.push_back({cxChild
, PostChildrenAction::Postpone
});
7805 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7806 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7807 cxChild
= MakeCXCursor(ICE
, parentDecl
, TU
);
7808 actions
.push_back({cxChild
, PostChildrenAction::Ignore
});
7816 static inline void updateCursorAnnotation(CXCursor
&Cursor
,
7817 const CXCursor
&updateC
) {
7818 if (clang_isInvalid(updateC
.kind
) || !clang_isInvalid(Cursor
.kind
))
7823 /// It annotates and advances tokens with a cursor until the comparison
7824 //// between the cursor location and the source range is the same as
7825 /// \arg compResult.
7827 /// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7828 /// Pass RangeOverlap to annotate tokens inside a range.
7829 void AnnotateTokensWorker::annotateAndAdvanceTokens(
7830 CXCursor updateC
, RangeComparisonResult compResult
, SourceRange range
) {
7831 while (MoreTokens()) {
7832 const unsigned I
= NextToken();
7833 if (isFunctionMacroToken(I
))
7834 if (!annotateAndAdvanceFunctionMacroTokens(updateC
, compResult
, range
))
7837 SourceLocation TokLoc
= GetTokenLoc(I
);
7838 if (LocationCompare(SrcMgr
, TokLoc
, range
) == compResult
) {
7839 updateCursorAnnotation(Cursors
[I
], updateC
);
7847 /// Special annotation handling for macro argument tokens.
7848 /// \returns true if it advanced beyond all macro tokens, false otherwise.
7849 bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
7850 CXCursor updateC
, RangeComparisonResult compResult
, SourceRange range
) {
7851 assert(MoreTokens());
7852 assert(isFunctionMacroToken(NextToken()) &&
7853 "Should be called only for macro arg tokens");
7855 // This works differently than annotateAndAdvanceTokens; because expanded
7856 // macro arguments can have arbitrary translation-unit source order, we do not
7857 // advance the token index one by one until a token fails the range test.
7858 // We only advance once past all of the macro arg tokens if all of them
7859 // pass the range test. If one of them fails we keep the token index pointing
7860 // at the start of the macro arg tokens so that the failing token will be
7861 // annotated by a subsequent annotation try.
7863 bool atLeastOneCompFail
= false;
7865 unsigned I
= NextToken();
7866 for (; I
< NumTokens
&& isFunctionMacroToken(I
); ++I
) {
7867 SourceLocation TokLoc
= getFunctionMacroTokenLoc(I
);
7868 if (TokLoc
.isFileID())
7869 continue; // not macro arg token, it's parens or comma.
7870 if (LocationCompare(SrcMgr
, TokLoc
, range
) == compResult
) {
7871 if (clang_isInvalid(clang_getCursorKind(Cursors
[I
])))
7872 Cursors
[I
] = updateC
;
7874 atLeastOneCompFail
= true;
7877 if (atLeastOneCompFail
)
7880 TokIdx
= I
; // All of the tokens were handled, advance beyond all of them.
7884 enum CXChildVisitResult
AnnotateTokensWorker::Visit(CXCursor cursor
,
7886 SourceRange cursorRange
= getRawCursorExtent(cursor
);
7887 if (cursorRange
.isInvalid())
7888 return CXChildVisit_Recurse
;
7890 if (IsIgnoredChildCursor(cursor
))
7891 return CXChildVisit_Continue
;
7893 if (!HasContextSensitiveKeywords
) {
7894 // Objective-C properties can have context-sensitive keywords.
7895 if (cursor
.kind
== CXCursor_ObjCPropertyDecl
) {
7896 if (const ObjCPropertyDecl
*Property
=
7897 dyn_cast_or_null
<ObjCPropertyDecl
>(getCursorDecl(cursor
)))
7898 HasContextSensitiveKeywords
=
7899 Property
->getPropertyAttributesAsWritten() != 0;
7901 // Objective-C methods can have context-sensitive keywords.
7902 else if (cursor
.kind
== CXCursor_ObjCInstanceMethodDecl
||
7903 cursor
.kind
== CXCursor_ObjCClassMethodDecl
) {
7904 if (const ObjCMethodDecl
*Method
=
7905 dyn_cast_or_null
<ObjCMethodDecl
>(getCursorDecl(cursor
))) {
7906 if (Method
->getObjCDeclQualifier())
7907 HasContextSensitiveKeywords
= true;
7909 for (const auto *P
: Method
->parameters()) {
7910 if (P
->getObjCDeclQualifier()) {
7911 HasContextSensitiveKeywords
= true;
7918 // C++ methods can have context-sensitive keywords.
7919 else if (cursor
.kind
== CXCursor_CXXMethod
) {
7920 if (const CXXMethodDecl
*Method
=
7921 dyn_cast_or_null
<CXXMethodDecl
>(getCursorDecl(cursor
))) {
7922 if (Method
->hasAttr
<FinalAttr
>() || Method
->hasAttr
<OverrideAttr
>())
7923 HasContextSensitiveKeywords
= true;
7926 // C++ classes can have context-sensitive keywords.
7927 else if (cursor
.kind
== CXCursor_StructDecl
||
7928 cursor
.kind
== CXCursor_ClassDecl
||
7929 cursor
.kind
== CXCursor_ClassTemplate
||
7930 cursor
.kind
== CXCursor_ClassTemplatePartialSpecialization
) {
7931 if (const Decl
*D
= getCursorDecl(cursor
))
7932 if (D
->hasAttr
<FinalAttr
>())
7933 HasContextSensitiveKeywords
= true;
7937 // Don't override a property annotation with its getter/setter method.
7938 if (cursor
.kind
== CXCursor_ObjCInstanceMethodDecl
&&
7939 parent
.kind
== CXCursor_ObjCPropertyDecl
)
7940 return CXChildVisit_Continue
;
7942 if (clang_isPreprocessing(cursor
.kind
)) {
7943 // Items in the preprocessing record are kept separate from items in
7944 // declarations, so we keep a separate token index.
7945 unsigned SavedTokIdx
= TokIdx
;
7946 TokIdx
= PreprocessingTokIdx
;
7948 // Skip tokens up until we catch up to the beginning of the preprocessing
7950 while (MoreTokens()) {
7951 const unsigned I
= NextToken();
7952 SourceLocation TokLoc
= GetTokenLoc(I
);
7953 switch (LocationCompare(SrcMgr
, TokLoc
, cursorRange
)) {
7964 // Look at all of the tokens within this range.
7965 while (MoreTokens()) {
7966 const unsigned I
= NextToken();
7967 SourceLocation TokLoc
= GetTokenLoc(I
);
7968 switch (LocationCompare(SrcMgr
, TokLoc
, cursorRange
)) {
7970 llvm_unreachable("Infeasible");
7974 // For macro expansions, just note where the beginning of the macro
7975 // expansion occurs.
7976 if (cursor
.kind
== CXCursor_MacroExpansion
) {
7977 if (TokLoc
== cursorRange
.getBegin())
7978 Cursors
[I
] = cursor
;
7982 // We may have already annotated macro names inside macro definitions.
7983 if (Cursors
[I
].kind
!= CXCursor_MacroExpansion
)
7984 Cursors
[I
] = cursor
;
7991 // Save the preprocessing token index; restore the non-preprocessing
7993 PreprocessingTokIdx
= TokIdx
;
7994 TokIdx
= SavedTokIdx
;
7995 return CXChildVisit_Recurse
;
7998 if (cursorRange
.isInvalid())
7999 return CXChildVisit_Continue
;
8001 unsigned BeforeReachingCursorIdx
= NextToken();
8002 const enum CXCursorKind cursorK
= clang_getCursorKind(cursor
);
8003 const enum CXCursorKind K
= clang_getCursorKind(parent
);
8004 const CXCursor updateC
=
8005 (clang_isInvalid(K
) || K
== CXCursor_TranslationUnit
||
8006 // Attributes are annotated out-of-order, skip tokens until we reach it.
8007 clang_isAttribute(cursor
.kind
))
8008 ? clang_getNullCursor()
8011 annotateAndAdvanceTokens(updateC
, RangeBefore
, cursorRange
);
8013 // Avoid having the cursor of an expression "overwrite" the annotation of the
8014 // variable declaration that it belongs to.
8015 // This can happen for C++ constructor expressions whose range generally
8016 // include the variable declaration, e.g.:
8017 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
8018 if (clang_isExpression(cursorK
) && MoreTokens()) {
8019 const Expr
*E
= getCursorExpr(cursor
);
8020 if (const Decl
*D
= getCursorDecl(cursor
)) {
8021 const unsigned I
= NextToken();
8022 if (E
->getBeginLoc().isValid() && D
->getLocation().isValid() &&
8023 E
->getBeginLoc() == D
->getLocation() &&
8024 E
->getBeginLoc() == GetTokenLoc(I
)) {
8025 updateCursorAnnotation(Cursors
[I
], updateC
);
8031 // Before recursing into the children keep some state that we are going
8032 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
8033 // extra work after the child nodes are visited.
8034 // Note that we don't call VisitChildren here to avoid traversing statements
8035 // code-recursively which can blow the stack.
8037 PostChildrenInfo Info
;
8038 Info
.Cursor
= cursor
;
8039 Info
.CursorRange
= cursorRange
;
8040 Info
.BeforeReachingCursorIdx
= BeforeReachingCursorIdx
;
8041 Info
.BeforeChildrenTokenIdx
= NextToken();
8042 Info
.ChildActions
= DetermineChildActions(cursor
);
8043 PostChildrenInfos
.push_back(Info
);
8045 return CXChildVisit_Recurse
;
8048 bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor
) {
8049 if (PostChildrenInfos
.empty())
8051 const PostChildrenInfo
&Info
= PostChildrenInfos
.back();
8052 if (!clang_equalCursors(Info
.Cursor
, cursor
))
8055 HandlePostPonedChildCursors(Info
);
8057 const unsigned BeforeChildren
= Info
.BeforeChildrenTokenIdx
;
8058 const unsigned AfterChildren
= NextToken();
8059 SourceRange cursorRange
= Info
.CursorRange
;
8061 // Scan the tokens that are at the end of the cursor, but are not captured
8062 // but the child cursors.
8063 annotateAndAdvanceTokens(cursor
, RangeOverlap
, cursorRange
);
8065 // Scan the tokens that are at the beginning of the cursor, but are not
8066 // capture by the child cursors.
8067 for (unsigned I
= BeforeChildren
; I
!= AfterChildren
; ++I
) {
8068 if (!clang_isInvalid(clang_getCursorKind(Cursors
[I
])))
8071 Cursors
[I
] = cursor
;
8074 // Attributes are annotated out-of-order, rewind TokIdx to when we first
8075 // encountered the attribute cursor.
8076 if (clang_isAttribute(cursor
.kind
))
8077 TokIdx
= Info
.BeforeReachingCursorIdx
;
8079 PostChildrenInfos
.pop_back();
8083 void AnnotateTokensWorker::HandlePostPonedChildCursors(
8084 const PostChildrenInfo
&Info
) {
8085 for (const auto &ChildAction
: Info
.ChildActions
) {
8086 if (ChildAction
.action
== PostChildrenAction::Postpone
) {
8087 HandlePostPonedChildCursor(ChildAction
.cursor
,
8088 Info
.BeforeChildrenTokenIdx
);
8093 void AnnotateTokensWorker::HandlePostPonedChildCursor(
8094 CXCursor Cursor
, unsigned StartTokenIndex
) {
8095 unsigned I
= StartTokenIndex
;
8097 // The bracket tokens of a Call or Subscript operator are mapped to
8098 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
8099 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
8100 for (unsigned RefNameRangeNr
= 0; I
< NumTokens
; RefNameRangeNr
++) {
8101 const CXSourceRange CXRefNameRange
= clang_getCursorReferenceNameRange(
8102 Cursor
, CXNameRange_WantQualifier
, RefNameRangeNr
);
8103 if (clang_Range_isNull(CXRefNameRange
))
8104 break; // All ranges handled.
8106 SourceRange RefNameRange
= cxloc::translateCXSourceRange(CXRefNameRange
);
8107 while (I
< NumTokens
) {
8108 const SourceLocation TokenLocation
= GetTokenLoc(I
);
8109 if (!TokenLocation
.isValid())
8112 // Adapt the end range, because LocationCompare() reports
8113 // RangeOverlap even for the not-inclusive end location.
8114 const SourceLocation fixedEnd
=
8115 RefNameRange
.getEnd().getLocWithOffset(-1);
8116 RefNameRange
= SourceRange(RefNameRange
.getBegin(), fixedEnd
);
8118 const RangeComparisonResult ComparisonResult
=
8119 LocationCompare(SrcMgr
, TokenLocation
, RefNameRange
);
8121 if (ComparisonResult
== RangeOverlap
) {
8122 Cursors
[I
++] = Cursor
;
8123 } else if (ComparisonResult
== RangeBefore
) {
8124 ++I
; // Not relevant token, check next one.
8125 } else if (ComparisonResult
== RangeAfter
) {
8126 break; // All tokens updated for current range, check next.
8132 static enum CXChildVisitResult
AnnotateTokensVisitor(CXCursor cursor
,
8134 CXClientData client_data
) {
8135 return static_cast<AnnotateTokensWorker
*>(client_data
)
8136 ->Visit(cursor
, parent
);
8139 static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor
,
8140 CXClientData client_data
) {
8141 return static_cast<AnnotateTokensWorker
*>(client_data
)
8142 ->postVisitChildren(cursor
);
8147 /// Uses the macro expansions in the preprocessing record to find
8148 /// and mark tokens that are macro arguments. This info is used by the
8149 /// AnnotateTokensWorker.
8150 class MarkMacroArgTokensVisitor
{
8157 MarkMacroArgTokensVisitor(SourceManager
&SM
, CXToken
*tokens
,
8159 : SM(SM
), Tokens(tokens
), NumTokens(numTokens
), CurIdx(0) {}
8161 CXChildVisitResult
visit(CXCursor cursor
, CXCursor parent
) {
8162 if (cursor
.kind
!= CXCursor_MacroExpansion
)
8163 return CXChildVisit_Continue
;
8165 SourceRange macroRange
= getCursorMacroExpansion(cursor
).getSourceRange();
8166 if (macroRange
.getBegin() == macroRange
.getEnd())
8167 return CXChildVisit_Continue
; // it's not a function macro.
8169 for (; CurIdx
< NumTokens
; ++CurIdx
) {
8170 if (!SM
.isBeforeInTranslationUnit(getTokenLoc(CurIdx
),
8171 macroRange
.getBegin()))
8175 if (CurIdx
== NumTokens
)
8176 return CXChildVisit_Break
;
8178 for (; CurIdx
< NumTokens
; ++CurIdx
) {
8179 SourceLocation tokLoc
= getTokenLoc(CurIdx
);
8180 if (!SM
.isBeforeInTranslationUnit(tokLoc
, macroRange
.getEnd()))
8183 setFunctionMacroTokenLoc(CurIdx
, SM
.getMacroArgExpandedLocation(tokLoc
));
8186 if (CurIdx
== NumTokens
)
8187 return CXChildVisit_Break
;
8189 return CXChildVisit_Continue
;
8193 CXToken
&getTok(unsigned Idx
) {
8194 assert(Idx
< NumTokens
);
8197 const CXToken
&getTok(unsigned Idx
) const {
8198 assert(Idx
< NumTokens
);
8202 SourceLocation
getTokenLoc(unsigned tokI
) {
8203 return SourceLocation::getFromRawEncoding(getTok(tokI
).int_data
[1]);
8206 void setFunctionMacroTokenLoc(unsigned tokI
, SourceLocation loc
) {
8207 // The third field is reserved and currently not used. Use it here
8208 // to mark macro arg expanded tokens with their expanded locations.
8209 getTok(tokI
).int_data
[3] = loc
.getRawEncoding();
8213 } // end anonymous namespace
8215 static CXChildVisitResult
8216 MarkMacroArgTokensVisitorDelegate(CXCursor cursor
, CXCursor parent
,
8217 CXClientData client_data
) {
8218 return static_cast<MarkMacroArgTokensVisitor
*>(client_data
)
8219 ->visit(cursor
, parent
);
8222 /// Used by \c annotatePreprocessorTokens.
8223 /// \returns true if lexing was finished, false otherwise.
8224 static bool lexNext(Lexer
&Lex
, Token
&Tok
, unsigned &NextIdx
,
8225 unsigned NumTokens
) {
8226 if (NextIdx
>= NumTokens
)
8230 Lex
.LexFromRawLexer(Tok
);
8231 return Tok
.is(tok::eof
);
8234 static void annotatePreprocessorTokens(CXTranslationUnit TU
,
8235 SourceRange RegionOfInterest
,
8236 CXCursor
*Cursors
, CXToken
*Tokens
,
8237 unsigned NumTokens
) {
8238 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
8240 Preprocessor
&PP
= CXXUnit
->getPreprocessor();
8241 SourceManager
&SourceMgr
= CXXUnit
->getSourceManager();
8242 std::pair
<FileID
, unsigned> BeginLocInfo
=
8243 SourceMgr
.getDecomposedSpellingLoc(RegionOfInterest
.getBegin());
8244 std::pair
<FileID
, unsigned> EndLocInfo
=
8245 SourceMgr
.getDecomposedSpellingLoc(RegionOfInterest
.getEnd());
8247 if (BeginLocInfo
.first
!= EndLocInfo
.first
)
8251 bool Invalid
= false;
8252 Buffer
= SourceMgr
.getBufferData(BeginLocInfo
.first
, &Invalid
);
8253 if (Buffer
.empty() || Invalid
)
8256 Lexer
Lex(SourceMgr
.getLocForStartOfFile(BeginLocInfo
.first
),
8257 CXXUnit
->getASTContext().getLangOpts(), Buffer
.begin(),
8258 Buffer
.data() + BeginLocInfo
.second
, Buffer
.end());
8259 Lex
.SetCommentRetentionState(true);
8261 unsigned NextIdx
= 0;
8262 // Lex tokens in raw mode until we hit the end of the range, to avoid
8263 // entering #includes or expanding macros.
8266 if (lexNext(Lex
, Tok
, NextIdx
, NumTokens
))
8268 unsigned TokIdx
= NextIdx
- 1;
8269 assert(Tok
.getLocation() ==
8270 SourceLocation::getFromRawEncoding(Tokens
[TokIdx
].int_data
[1]));
8273 if (Tok
.is(tok::hash
) && Tok
.isAtStartOfLine()) {
8274 // We have found a preprocessing directive. Annotate the tokens
8277 // FIXME: Some simple tests here could identify macro definitions and
8278 // #undefs, to provide specific cursor kinds for those.
8280 SourceLocation BeginLoc
= Tok
.getLocation();
8281 if (lexNext(Lex
, Tok
, NextIdx
, NumTokens
))
8284 MacroInfo
*MI
= nullptr;
8285 if (Tok
.is(tok::raw_identifier
) && Tok
.getRawIdentifier() == "define") {
8286 if (lexNext(Lex
, Tok
, NextIdx
, NumTokens
))
8289 if (Tok
.is(tok::raw_identifier
)) {
8290 IdentifierInfo
&II
=
8291 PP
.getIdentifierTable().get(Tok
.getRawIdentifier());
8292 SourceLocation MappedTokLoc
=
8293 CXXUnit
->mapLocationToPreamble(Tok
.getLocation());
8294 MI
= getMacroInfo(II
, MappedTokLoc
, TU
);
8298 bool finished
= false;
8300 if (lexNext(Lex
, Tok
, NextIdx
, NumTokens
)) {
8304 // If we are in a macro definition, check if the token was ever a
8305 // macro name and annotate it if that's the case.
8307 SourceLocation SaveLoc
= Tok
.getLocation();
8308 Tok
.setLocation(CXXUnit
->mapLocationToPreamble(SaveLoc
));
8309 MacroDefinitionRecord
*MacroDef
=
8310 checkForMacroInMacroDefinition(MI
, Tok
, TU
);
8311 Tok
.setLocation(SaveLoc
);
8313 Cursors
[NextIdx
- 1] =
8314 MakeMacroExpansionCursor(MacroDef
, Tok
.getLocation(), TU
);
8316 } while (!Tok
.isAtStartOfLine());
8318 unsigned LastIdx
= finished
? NextIdx
- 1 : NextIdx
- 2;
8319 assert(TokIdx
<= LastIdx
);
8320 SourceLocation EndLoc
=
8321 SourceLocation::getFromRawEncoding(Tokens
[LastIdx
].int_data
[1]);
8323 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc
, EndLoc
), TU
);
8325 for (; TokIdx
<= LastIdx
; ++TokIdx
)
8326 updateCursorAnnotation(Cursors
[TokIdx
], Cursor
);
8335 // This gets run a separate thread to avoid stack blowout.
8336 static void clang_annotateTokensImpl(CXTranslationUnit TU
, ASTUnit
*CXXUnit
,
8337 CXToken
*Tokens
, unsigned NumTokens
,
8338 CXCursor
*Cursors
) {
8339 CIndexer
*CXXIdx
= TU
->CIdx
;
8340 if (CXXIdx
->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing
))
8341 setThreadBackgroundPriority();
8343 // Determine the region of interest, which contains all of the tokens.
8344 SourceRange RegionOfInterest
;
8345 RegionOfInterest
.setBegin(
8346 cxloc::translateSourceLocation(clang_getTokenLocation(TU
, Tokens
[0])));
8347 RegionOfInterest
.setEnd(cxloc::translateSourceLocation(
8348 clang_getTokenLocation(TU
, Tokens
[NumTokens
- 1])));
8350 // Relex the tokens within the source range to look for preprocessing
8352 annotatePreprocessorTokens(TU
, RegionOfInterest
, Cursors
, Tokens
, NumTokens
);
8354 // If begin location points inside a macro argument, set it to the expansion
8355 // location so we can have the full context when annotating semantically.
8357 SourceManager
&SM
= CXXUnit
->getSourceManager();
8358 SourceLocation Loc
=
8359 SM
.getMacroArgExpandedLocation(RegionOfInterest
.getBegin());
8360 if (Loc
.isMacroID())
8361 RegionOfInterest
.setBegin(SM
.getExpansionLoc(Loc
));
8364 if (CXXUnit
->getPreprocessor().getPreprocessingRecord()) {
8365 // Search and mark tokens that are macro argument expansions.
8366 MarkMacroArgTokensVisitor
Visitor(CXXUnit
->getSourceManager(), Tokens
,
8368 CursorVisitor
MacroArgMarker(
8369 TU
, MarkMacroArgTokensVisitorDelegate
, &Visitor
,
8370 /*VisitPreprocessorLast=*/true,
8371 /*VisitIncludedEntities=*/false, RegionOfInterest
);
8372 MacroArgMarker
.visitPreprocessedEntitiesInRegion();
8375 // Annotate all of the source locations in the region of interest that map to
8376 // a specific cursor.
8377 AnnotateTokensWorker
W(Tokens
, Cursors
, NumTokens
, TU
, RegionOfInterest
);
8379 // FIXME: We use a ridiculous stack size here because the data-recursion
8380 // algorithm uses a large stack frame than the non-data recursive version,
8381 // and AnnotationTokensWorker currently transforms the data-recursion
8382 // algorithm back into a traditional recursion by explicitly calling
8383 // VisitChildren(). We will need to remove this explicit recursive call.
8386 // If we ran into any entities that involve context-sensitive keywords,
8387 // take another pass through the tokens to mark them as such.
8388 if (W
.hasContextSensitiveKeywords()) {
8389 for (unsigned I
= 0; I
!= NumTokens
; ++I
) {
8390 if (clang_getTokenKind(Tokens
[I
]) != CXToken_Identifier
)
8393 if (Cursors
[I
].kind
== CXCursor_ObjCPropertyDecl
) {
8394 IdentifierInfo
*II
= static_cast<IdentifierInfo
*>(Tokens
[I
].ptr_data
);
8395 if (const ObjCPropertyDecl
*Property
=
8396 dyn_cast_or_null
<ObjCPropertyDecl
>(getCursorDecl(Cursors
[I
]))) {
8397 if (Property
->getPropertyAttributesAsWritten() != 0 &&
8398 llvm::StringSwitch
<bool>(II
->getName())
8399 .Case("readonly", true)
8400 .Case("assign", true)
8401 .Case("unsafe_unretained", true)
8402 .Case("readwrite", true)
8403 .Case("retain", true)
8405 .Case("nonatomic", true)
8406 .Case("atomic", true)
8407 .Case("getter", true)
8408 .Case("setter", true)
8409 .Case("strong", true)
8411 .Case("class", true)
8413 Tokens
[I
].int_data
[0] = CXToken_Keyword
;
8418 if (Cursors
[I
].kind
== CXCursor_ObjCInstanceMethodDecl
||
8419 Cursors
[I
].kind
== CXCursor_ObjCClassMethodDecl
) {
8420 IdentifierInfo
*II
= static_cast<IdentifierInfo
*>(Tokens
[I
].ptr_data
);
8421 if (llvm::StringSwitch
<bool>(II
->getName())
8424 .Case("inout", true)
8425 .Case("oneway", true)
8426 .Case("bycopy", true)
8427 .Case("byref", true)
8429 Tokens
[I
].int_data
[0] = CXToken_Keyword
;
8433 if (Cursors
[I
].kind
== CXCursor_CXXFinalAttr
||
8434 Cursors
[I
].kind
== CXCursor_CXXOverrideAttr
) {
8435 Tokens
[I
].int_data
[0] = CXToken_Keyword
;
8442 void clang_annotateTokens(CXTranslationUnit TU
, CXToken
*Tokens
,
8443 unsigned NumTokens
, CXCursor
*Cursors
) {
8444 if (isNotUsableTU(TU
)) {
8448 if (NumTokens
== 0 || !Tokens
|| !Cursors
) {
8449 LOG_FUNC_SECTION
{ *Log
<< "<null input>"; }
8455 CXSourceLocation bloc
= clang_getTokenLocation(TU
, Tokens
[0]);
8456 CXSourceLocation eloc
= clang_getTokenLocation(TU
, Tokens
[NumTokens
- 1]);
8457 *Log
<< clang_getRange(bloc
, eloc
);
8460 // Any token we don't specifically annotate will have a NULL cursor.
8461 CXCursor C
= clang_getNullCursor();
8462 for (unsigned I
= 0; I
!= NumTokens
; ++I
)
8465 ASTUnit
*CXXUnit
= cxtu::getASTUnit(TU
);
8469 ASTUnit::ConcurrencyCheck
Check(*CXXUnit
);
8471 auto AnnotateTokensImpl
= [=]() {
8472 clang_annotateTokensImpl(TU
, CXXUnit
, Tokens
, NumTokens
, Cursors
);
8474 llvm::CrashRecoveryContext CRC
;
8475 if (!RunSafely(CRC
, AnnotateTokensImpl
, GetSafetyThreadStackSize() * 2)) {
8476 fprintf(stderr
, "libclang: crash detected while annotating tokens\n");
8480 //===----------------------------------------------------------------------===//
8481 // Operations for querying linkage of a cursor.
8482 //===----------------------------------------------------------------------===//
8484 CXLinkageKind
clang_getCursorLinkage(CXCursor cursor
) {
8485 if (!clang_isDeclaration(cursor
.kind
))
8486 return CXLinkage_Invalid
;
8488 const Decl
*D
= cxcursor::getCursorDecl(cursor
);
8489 if (const NamedDecl
*ND
= dyn_cast_or_null
<NamedDecl
>(D
))
8490 switch (ND
->getLinkageInternal()) {
8491 case Linkage::Invalid
:
8492 return CXLinkage_Invalid
;
8494 case Linkage::VisibleNone
:
8495 return CXLinkage_NoLinkage
;
8496 case Linkage::Internal
:
8497 return CXLinkage_Internal
;
8498 case Linkage::UniqueExternal
:
8499 return CXLinkage_UniqueExternal
;
8500 case Linkage::Module
:
8501 case Linkage::External
:
8502 return CXLinkage_External
;
8505 return CXLinkage_Invalid
;
8508 //===----------------------------------------------------------------------===//
8509 // Operations for querying visibility of a cursor.
8510 //===----------------------------------------------------------------------===//
8512 CXVisibilityKind
clang_getCursorVisibility(CXCursor cursor
) {
8513 if (!clang_isDeclaration(cursor
.kind
))
8514 return CXVisibility_Invalid
;
8516 const Decl
*D
= cxcursor::getCursorDecl(cursor
);
8517 if (const NamedDecl
*ND
= dyn_cast_or_null
<NamedDecl
>(D
))
8518 switch (ND
->getVisibility()) {
8519 case HiddenVisibility
:
8520 return CXVisibility_Hidden
;
8521 case ProtectedVisibility
:
8522 return CXVisibility_Protected
;
8523 case DefaultVisibility
:
8524 return CXVisibility_Default
;
8527 return CXVisibility_Invalid
;
8530 //===----------------------------------------------------------------------===//
8531 // Operations for querying language of a cursor.
8532 //===----------------------------------------------------------------------===//
8534 static CXLanguageKind
getDeclLanguage(const Decl
*D
) {
8536 return CXLanguage_C
;
8538 switch (D
->getKind()) {
8541 case Decl::ImplicitParam
:
8542 case Decl::ObjCAtDefsField
:
8543 case Decl::ObjCCategory
:
8544 case Decl::ObjCCategoryImpl
:
8545 case Decl::ObjCCompatibleAlias
:
8546 case Decl::ObjCImplementation
:
8547 case Decl::ObjCInterface
:
8548 case Decl::ObjCIvar
:
8549 case Decl::ObjCMethod
:
8550 case Decl::ObjCProperty
:
8551 case Decl::ObjCPropertyImpl
:
8552 case Decl::ObjCProtocol
:
8553 case Decl::ObjCTypeParam
:
8554 return CXLanguage_ObjC
;
8555 case Decl::CXXConstructor
:
8556 case Decl::CXXConversion
:
8557 case Decl::CXXDestructor
:
8558 case Decl::CXXMethod
:
8559 case Decl::CXXRecord
:
8560 case Decl::ClassTemplate
:
8561 case Decl::ClassTemplatePartialSpecialization
:
8562 case Decl::ClassTemplateSpecialization
:
8564 case Decl::FriendTemplate
:
8565 case Decl::FunctionTemplate
:
8566 case Decl::LinkageSpec
:
8567 case Decl::Namespace
:
8568 case Decl::NamespaceAlias
:
8569 case Decl::NonTypeTemplateParm
:
8570 case Decl::StaticAssert
:
8571 case Decl::TemplateTemplateParm
:
8572 case Decl::TemplateTypeParm
:
8573 case Decl::UnresolvedUsingTypename
:
8574 case Decl::UnresolvedUsingValue
:
8576 case Decl::UsingDirective
:
8577 case Decl::UsingShadow
:
8578 return CXLanguage_CPlusPlus
;
8581 return CXLanguage_C
;
8584 static CXAvailabilityKind
getCursorAvailabilityForDecl(const Decl
*D
) {
8585 if (isa
<FunctionDecl
>(D
) && cast
<FunctionDecl
>(D
)->isDeleted())
8586 return CXAvailability_NotAvailable
;
8588 switch (D
->getAvailability()) {
8590 case AR_NotYetIntroduced
:
8591 if (const EnumConstantDecl
*EnumConst
= dyn_cast
<EnumConstantDecl
>(D
))
8592 return getCursorAvailabilityForDecl(
8593 cast
<Decl
>(EnumConst
->getDeclContext()));
8594 return CXAvailability_Available
;
8597 return CXAvailability_Deprecated
;
8599 case AR_Unavailable
:
8600 return CXAvailability_NotAvailable
;
8603 llvm_unreachable("Unknown availability kind!");
8606 enum CXAvailabilityKind
clang_getCursorAvailability(CXCursor cursor
) {
8607 if (clang_isDeclaration(cursor
.kind
))
8608 if (const Decl
*D
= cxcursor::getCursorDecl(cursor
))
8609 return getCursorAvailabilityForDecl(D
);
8611 return CXAvailability_Available
;
8614 static CXVersion
convertVersion(VersionTuple In
) {
8615 CXVersion Out
= {-1, -1, -1};
8619 Out
.Major
= In
.getMajor();
8621 std::optional
<unsigned> Minor
= In
.getMinor();
8627 std::optional
<unsigned> Subminor
= In
.getSubminor();
8629 Out
.Subminor
= *Subminor
;
8634 static void getCursorPlatformAvailabilityForDecl(
8635 const Decl
*D
, int *always_deprecated
, CXString
*deprecated_message
,
8636 int *always_unavailable
, CXString
*unavailable_message
,
8637 SmallVectorImpl
<AvailabilityAttr
*> &AvailabilityAttrs
) {
8638 bool HadAvailAttr
= false;
8639 for (auto A
: D
->attrs()) {
8640 if (DeprecatedAttr
*Deprecated
= dyn_cast
<DeprecatedAttr
>(A
)) {
8641 HadAvailAttr
= true;
8642 if (always_deprecated
)
8643 *always_deprecated
= 1;
8644 if (deprecated_message
) {
8645 clang_disposeString(*deprecated_message
);
8646 *deprecated_message
= cxstring::createDup(Deprecated
->getMessage());
8651 if (UnavailableAttr
*Unavailable
= dyn_cast
<UnavailableAttr
>(A
)) {
8652 HadAvailAttr
= true;
8653 if (always_unavailable
)
8654 *always_unavailable
= 1;
8655 if (unavailable_message
) {
8656 clang_disposeString(*unavailable_message
);
8657 *unavailable_message
= cxstring::createDup(Unavailable
->getMessage());
8662 if (AvailabilityAttr
*Avail
= dyn_cast
<AvailabilityAttr
>(A
)) {
8663 AvailabilityAttrs
.push_back(Avail
);
8664 HadAvailAttr
= true;
8669 if (const EnumConstantDecl
*EnumConst
= dyn_cast
<EnumConstantDecl
>(D
))
8670 return getCursorPlatformAvailabilityForDecl(
8671 cast
<Decl
>(EnumConst
->getDeclContext()), always_deprecated
,
8672 deprecated_message
, always_unavailable
, unavailable_message
,
8675 // If no availability attributes are found, inherit the attribute from the
8676 // containing decl or the class or category interface decl.
8677 if (AvailabilityAttrs
.empty()) {
8678 const ObjCContainerDecl
*CD
= nullptr;
8679 const DeclContext
*DC
= D
->getDeclContext();
8681 if (auto *IMD
= dyn_cast
<ObjCImplementationDecl
>(D
))
8682 CD
= IMD
->getClassInterface();
8683 else if (auto *CatD
= dyn_cast
<ObjCCategoryDecl
>(D
))
8684 CD
= CatD
->getClassInterface();
8685 else if (auto *IMD
= dyn_cast
<ObjCCategoryImplDecl
>(D
))
8686 CD
= IMD
->getCategoryDecl();
8687 else if (auto *ID
= dyn_cast
<ObjCInterfaceDecl
>(DC
))
8689 else if (auto *CatD
= dyn_cast
<ObjCCategoryDecl
>(DC
))
8691 else if (auto *IMD
= dyn_cast
<ObjCImplementationDecl
>(DC
))
8692 CD
= IMD
->getClassInterface();
8693 else if (auto *IMD
= dyn_cast
<ObjCCategoryImplDecl
>(DC
))
8694 CD
= IMD
->getCategoryDecl();
8695 else if (auto *PD
= dyn_cast
<ObjCProtocolDecl
>(DC
))
8699 getCursorPlatformAvailabilityForDecl(
8700 CD
, always_deprecated
, deprecated_message
, always_unavailable
,
8701 unavailable_message
, AvailabilityAttrs
);
8706 AvailabilityAttrs
, [](AvailabilityAttr
*LHS
, AvailabilityAttr
*RHS
) {
8707 return LHS
->getPlatform()->getName() < RHS
->getPlatform()->getName();
8709 ASTContext
&Ctx
= D
->getASTContext();
8710 auto It
= std::unique(
8711 AvailabilityAttrs
.begin(), AvailabilityAttrs
.end(),
8712 [&Ctx
](AvailabilityAttr
*LHS
, AvailabilityAttr
*RHS
) {
8713 if (LHS
->getPlatform() != RHS
->getPlatform())
8716 if (LHS
->getIntroduced() == RHS
->getIntroduced() &&
8717 LHS
->getDeprecated() == RHS
->getDeprecated() &&
8718 LHS
->getObsoleted() == RHS
->getObsoleted() &&
8719 LHS
->getMessage() == RHS
->getMessage() &&
8720 LHS
->getReplacement() == RHS
->getReplacement())
8723 if ((!LHS
->getIntroduced().empty() && !RHS
->getIntroduced().empty()) ||
8724 (!LHS
->getDeprecated().empty() && !RHS
->getDeprecated().empty()) ||
8725 (!LHS
->getObsoleted().empty() && !RHS
->getObsoleted().empty()))
8728 if (LHS
->getIntroduced().empty() && !RHS
->getIntroduced().empty())
8729 LHS
->setIntroduced(Ctx
, RHS
->getIntroduced());
8731 if (LHS
->getDeprecated().empty() && !RHS
->getDeprecated().empty()) {
8732 LHS
->setDeprecated(Ctx
, RHS
->getDeprecated());
8733 if (LHS
->getMessage().empty())
8734 LHS
->setMessage(Ctx
, RHS
->getMessage());
8735 if (LHS
->getReplacement().empty())
8736 LHS
->setReplacement(Ctx
, RHS
->getReplacement());
8739 if (LHS
->getObsoleted().empty() && !RHS
->getObsoleted().empty()) {
8740 LHS
->setObsoleted(Ctx
, RHS
->getObsoleted());
8741 if (LHS
->getMessage().empty())
8742 LHS
->setMessage(Ctx
, RHS
->getMessage());
8743 if (LHS
->getReplacement().empty())
8744 LHS
->setReplacement(Ctx
, RHS
->getReplacement());
8749 AvailabilityAttrs
.erase(It
, AvailabilityAttrs
.end());
8752 int clang_getCursorPlatformAvailability(CXCursor cursor
, int *always_deprecated
,
8753 CXString
*deprecated_message
,
8754 int *always_unavailable
,
8755 CXString
*unavailable_message
,
8756 CXPlatformAvailability
*availability
,
8757 int availability_size
) {
8758 if (always_deprecated
)
8759 *always_deprecated
= 0;
8760 if (deprecated_message
)
8761 *deprecated_message
= cxstring::createEmpty();
8762 if (always_unavailable
)
8763 *always_unavailable
= 0;
8764 if (unavailable_message
)
8765 *unavailable_message
= cxstring::createEmpty();
8767 if (!clang_isDeclaration(cursor
.kind
))
8770 const Decl
*D
= cxcursor::getCursorDecl(cursor
);
8774 SmallVector
<AvailabilityAttr
*, 8> AvailabilityAttrs
;
8775 getCursorPlatformAvailabilityForDecl(D
, always_deprecated
, deprecated_message
,
8776 always_unavailable
, unavailable_message
,
8778 for (const auto &Avail
: llvm::enumerate(
8779 llvm::ArrayRef(AvailabilityAttrs
).take_front(availability_size
))) {
8780 availability
[Avail
.index()].Platform
=
8781 cxstring::createDup(Avail
.value()->getPlatform()->getName());
8782 availability
[Avail
.index()].Introduced
=
8783 convertVersion(Avail
.value()->getIntroduced());
8784 availability
[Avail
.index()].Deprecated
=
8785 convertVersion(Avail
.value()->getDeprecated());
8786 availability
[Avail
.index()].Obsoleted
=
8787 convertVersion(Avail
.value()->getObsoleted());
8788 availability
[Avail
.index()].Unavailable
= Avail
.value()->getUnavailable();
8789 availability
[Avail
.index()].Message
=
8790 cxstring::createDup(Avail
.value()->getMessage());
8793 return AvailabilityAttrs
.size();
8796 void clang_disposeCXPlatformAvailability(CXPlatformAvailability
*availability
) {
8797 clang_disposeString(availability
->Platform
);
8798 clang_disposeString(availability
->Message
);
8801 CXLanguageKind
clang_getCursorLanguage(CXCursor cursor
) {
8802 if (clang_isDeclaration(cursor
.kind
))
8803 return getDeclLanguage(cxcursor::getCursorDecl(cursor
));
8805 return CXLanguage_Invalid
;
8808 CXTLSKind
clang_getCursorTLSKind(CXCursor cursor
) {
8809 const Decl
*D
= cxcursor::getCursorDecl(cursor
);
8810 if (const VarDecl
*VD
= dyn_cast
<VarDecl
>(D
)) {
8811 switch (VD
->getTLSKind()) {
8812 case VarDecl::TLS_None
:
8814 case VarDecl::TLS_Dynamic
:
8815 return CXTLS_Dynamic
;
8816 case VarDecl::TLS_Static
:
8817 return CXTLS_Static
;
8824 /// If the given cursor is the "templated" declaration
8825 /// describing a class or function template, return the class or
8826 /// function template.
8827 static const Decl
*maybeGetTemplateCursor(const Decl
*D
) {
8831 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
))
8832 if (FunctionTemplateDecl
*FunTmpl
= FD
->getDescribedFunctionTemplate())
8835 if (const CXXRecordDecl
*RD
= dyn_cast
<CXXRecordDecl
>(D
))
8836 if (ClassTemplateDecl
*ClassTmpl
= RD
->getDescribedClassTemplate())
8842 enum CX_StorageClass
clang_Cursor_getStorageClass(CXCursor C
) {
8843 StorageClass sc
= SC_None
;
8844 const Decl
*D
= getCursorDecl(C
);
8846 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
8847 sc
= FD
->getStorageClass();
8848 } else if (const VarDecl
*VD
= dyn_cast
<VarDecl
>(D
)) {
8849 sc
= VD
->getStorageClass();
8851 return CX_SC_Invalid
;
8854 return CX_SC_Invalid
;
8860 return CX_SC_Extern
;
8862 return CX_SC_Static
;
8863 case SC_PrivateExtern
:
8864 return CX_SC_PrivateExtern
;
8868 return CX_SC_Register
;
8870 llvm_unreachable("Unhandled storage class!");
8873 CXCursor
clang_getCursorSemanticParent(CXCursor cursor
) {
8874 if (clang_isDeclaration(cursor
.kind
)) {
8875 if (const Decl
*D
= getCursorDecl(cursor
)) {
8876 const DeclContext
*DC
= D
->getDeclContext();
8878 return clang_getNullCursor();
8880 return MakeCXCursor(maybeGetTemplateCursor(cast
<Decl
>(DC
)),
8881 getCursorTU(cursor
));
8885 if (clang_isStatement(cursor
.kind
) || clang_isExpression(cursor
.kind
)) {
8886 if (const Decl
*D
= getCursorDecl(cursor
))
8887 return MakeCXCursor(D
, getCursorTU(cursor
));
8890 return clang_getNullCursor();
8893 CXCursor
clang_getCursorLexicalParent(CXCursor cursor
) {
8894 if (clang_isDeclaration(cursor
.kind
)) {
8895 if (const Decl
*D
= getCursorDecl(cursor
)) {
8896 const DeclContext
*DC
= D
->getLexicalDeclContext();
8898 return clang_getNullCursor();
8900 return MakeCXCursor(maybeGetTemplateCursor(cast
<Decl
>(DC
)),
8901 getCursorTU(cursor
));
8905 // FIXME: Note that we can't easily compute the lexical context of a
8906 // statement or expression, so we return nothing.
8907 return clang_getNullCursor();
8910 CXFile
clang_getIncludedFile(CXCursor cursor
) {
8911 if (cursor
.kind
!= CXCursor_InclusionDirective
)
8914 const InclusionDirective
*ID
= getCursorInclusionDirective(cursor
);
8915 return cxfile::makeCXFile(ID
->getFile());
8918 unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C
, unsigned reserved
) {
8919 if (C
.kind
!= CXCursor_ObjCPropertyDecl
)
8920 return CXObjCPropertyAttr_noattr
;
8922 unsigned Result
= CXObjCPropertyAttr_noattr
;
8923 const auto *PD
= cast
<ObjCPropertyDecl
>(getCursorDecl(C
));
8924 ObjCPropertyAttribute::Kind Attr
= PD
->getPropertyAttributesAsWritten();
8926 #define SET_CXOBJCPROP_ATTR(A) \
8927 if (Attr & ObjCPropertyAttribute::kind_##A) \
8928 Result |= CXObjCPropertyAttr_##A
8929 SET_CXOBJCPROP_ATTR(readonly
);
8930 SET_CXOBJCPROP_ATTR(getter
);
8931 SET_CXOBJCPROP_ATTR(assign
);
8932 SET_CXOBJCPROP_ATTR(readwrite
);
8933 SET_CXOBJCPROP_ATTR(retain
);
8934 SET_CXOBJCPROP_ATTR(copy
);
8935 SET_CXOBJCPROP_ATTR(nonatomic
);
8936 SET_CXOBJCPROP_ATTR(setter
);
8937 SET_CXOBJCPROP_ATTR(atomic
);
8938 SET_CXOBJCPROP_ATTR(weak
);
8939 SET_CXOBJCPROP_ATTR(strong
);
8940 SET_CXOBJCPROP_ATTR(unsafe_unretained
);
8941 SET_CXOBJCPROP_ATTR(class);
8942 #undef SET_CXOBJCPROP_ATTR
8947 CXString
clang_Cursor_getObjCPropertyGetterName(CXCursor C
) {
8948 if (C
.kind
!= CXCursor_ObjCPropertyDecl
)
8949 return cxstring::createNull();
8951 const auto *PD
= cast
<ObjCPropertyDecl
>(getCursorDecl(C
));
8952 Selector sel
= PD
->getGetterName();
8954 return cxstring::createNull();
8956 return cxstring::createDup(sel
.getAsString());
8959 CXString
clang_Cursor_getObjCPropertySetterName(CXCursor C
) {
8960 if (C
.kind
!= CXCursor_ObjCPropertyDecl
)
8961 return cxstring::createNull();
8963 const auto *PD
= cast
<ObjCPropertyDecl
>(getCursorDecl(C
));
8964 Selector sel
= PD
->getSetterName();
8966 return cxstring::createNull();
8968 return cxstring::createDup(sel
.getAsString());
8971 unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C
) {
8972 if (!clang_isDeclaration(C
.kind
))
8973 return CXObjCDeclQualifier_None
;
8975 Decl::ObjCDeclQualifier QT
= Decl::OBJC_TQ_None
;
8976 const Decl
*D
= getCursorDecl(C
);
8977 if (const ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(D
))
8978 QT
= MD
->getObjCDeclQualifier();
8979 else if (const ParmVarDecl
*PD
= dyn_cast
<ParmVarDecl
>(D
))
8980 QT
= PD
->getObjCDeclQualifier();
8981 if (QT
== Decl::OBJC_TQ_None
)
8982 return CXObjCDeclQualifier_None
;
8984 unsigned Result
= CXObjCDeclQualifier_None
;
8985 if (QT
& Decl::OBJC_TQ_In
)
8986 Result
|= CXObjCDeclQualifier_In
;
8987 if (QT
& Decl::OBJC_TQ_Inout
)
8988 Result
|= CXObjCDeclQualifier_Inout
;
8989 if (QT
& Decl::OBJC_TQ_Out
)
8990 Result
|= CXObjCDeclQualifier_Out
;
8991 if (QT
& Decl::OBJC_TQ_Bycopy
)
8992 Result
|= CXObjCDeclQualifier_Bycopy
;
8993 if (QT
& Decl::OBJC_TQ_Byref
)
8994 Result
|= CXObjCDeclQualifier_Byref
;
8995 if (QT
& Decl::OBJC_TQ_Oneway
)
8996 Result
|= CXObjCDeclQualifier_Oneway
;
9001 unsigned clang_Cursor_isObjCOptional(CXCursor C
) {
9002 if (!clang_isDeclaration(C
.kind
))
9005 const Decl
*D
= getCursorDecl(C
);
9006 if (const ObjCPropertyDecl
*PD
= dyn_cast
<ObjCPropertyDecl
>(D
))
9007 return PD
->getPropertyImplementation() == ObjCPropertyDecl::Optional
;
9008 if (const ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(D
))
9009 return MD
->getImplementationControl() ==
9010 ObjCImplementationControl::Optional
;
9015 unsigned clang_Cursor_isVariadic(CXCursor C
) {
9016 if (!clang_isDeclaration(C
.kind
))
9019 const Decl
*D
= getCursorDecl(C
);
9020 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
))
9021 return FD
->isVariadic();
9022 if (const ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(D
))
9023 return MD
->isVariadic();
9028 unsigned clang_Cursor_isExternalSymbol(CXCursor C
, CXString
*language
,
9029 CXString
*definedIn
,
9030 unsigned *isGenerated
) {
9031 if (!clang_isDeclaration(C
.kind
))
9034 const Decl
*D
= getCursorDecl(C
);
9036 if (auto *attr
= D
->getExternalSourceSymbolAttr()) {
9038 *language
= cxstring::createDup(attr
->getLanguage());
9040 *definedIn
= cxstring::createDup(attr
->getDefinedIn());
9042 *isGenerated
= attr
->getGeneratedDeclaration();
9048 enum CX_BinaryOperatorKind
clang_Cursor_getBinaryOpcode(CXCursor C
) {
9049 if (C
.kind
!= CXCursor_BinaryOperator
&&
9050 C
.kind
!= CXCursor_CompoundAssignOperator
) {
9051 return CX_BO_Invalid
;
9054 const Expr
*D
= getCursorExpr(C
);
9055 if (const auto *BinOp
= dyn_cast
<BinaryOperator
>(D
)) {
9056 switch (BinOp
->getOpcode()) {
9057 #define BINARY_OPERATION(Name, Spelling) \
9059 return CX_BO_##Name;
9060 #include "clang/AST/OperationKinds.def"
9064 return CX_BO_Invalid
;
9067 CXString
clang_Cursor_getBinaryOpcodeStr(enum CX_BinaryOperatorKind Op
) {
9068 if (Op
> CX_BO_LAST
)
9069 return cxstring::createEmpty();
9071 return cxstring::createDup(
9072 // BinaryOperator::getOpcodeStr has no case for CX_BO_Invalid,
9074 BinaryOperator::getOpcodeStr(static_cast<BinaryOperatorKind
>(Op
- 1)));
9077 CXSourceRange
clang_Cursor_getCommentRange(CXCursor C
) {
9078 if (!clang_isDeclaration(C
.kind
))
9079 return clang_getNullRange();
9081 const Decl
*D
= getCursorDecl(C
);
9082 ASTContext
&Context
= getCursorContext(C
);
9083 const RawComment
*RC
= Context
.getRawCommentForAnyRedecl(D
);
9085 return clang_getNullRange();
9087 return cxloc::translateSourceRange(Context
, RC
->getSourceRange());
9090 CXString
clang_Cursor_getRawCommentText(CXCursor C
) {
9091 if (!clang_isDeclaration(C
.kind
))
9092 return cxstring::createNull();
9094 const Decl
*D
= getCursorDecl(C
);
9095 ASTContext
&Context
= getCursorContext(C
);
9096 const RawComment
*RC
= Context
.getRawCommentForAnyRedecl(D
);
9098 RC
? RC
->getRawText(Context
.getSourceManager()) : StringRef();
9100 // Don't duplicate the string because RawText points directly into source
9102 return cxstring::createRef(RawText
);
9105 CXString
clang_Cursor_getBriefCommentText(CXCursor C
) {
9106 if (!clang_isDeclaration(C
.kind
))
9107 return cxstring::createNull();
9109 const Decl
*D
= getCursorDecl(C
);
9110 const ASTContext
&Context
= getCursorContext(C
);
9111 const RawComment
*RC
= Context
.getRawCommentForAnyRedecl(D
);
9114 StringRef BriefText
= RC
->getBriefText(Context
);
9116 // Don't duplicate the string because RawComment ensures that this memory
9117 // will not go away.
9118 return cxstring::createRef(BriefText
);
9121 return cxstring::createNull();
9124 CXModule
clang_Cursor_getModule(CXCursor C
) {
9125 if (C
.kind
== CXCursor_ModuleImportDecl
) {
9126 if (const ImportDecl
*ImportD
=
9127 dyn_cast_or_null
<ImportDecl
>(getCursorDecl(C
)))
9128 return ImportD
->getImportedModule();
9134 CXModule
clang_getModuleForFile(CXTranslationUnit TU
, CXFile File
) {
9135 if (isNotUsableTU(TU
)) {
9141 FileEntryRef FE
= *cxfile::getFileEntryRef(File
);
9143 ASTUnit
&Unit
= *cxtu::getASTUnit(TU
);
9144 HeaderSearch
&HS
= Unit
.getPreprocessor().getHeaderSearchInfo();
9145 ModuleMap::KnownHeader Header
= HS
.findModuleForHeader(FE
);
9147 return Header
.getModule();
9150 CXFile
clang_Module_getASTFile(CXModule CXMod
) {
9153 Module
*Mod
= static_cast<Module
*>(CXMod
);
9154 return cxfile::makeCXFile(Mod
->getASTFile());
9157 CXModule
clang_Module_getParent(CXModule CXMod
) {
9160 Module
*Mod
= static_cast<Module
*>(CXMod
);
9164 CXString
clang_Module_getName(CXModule CXMod
) {
9166 return cxstring::createEmpty();
9167 Module
*Mod
= static_cast<Module
*>(CXMod
);
9168 return cxstring::createDup(Mod
->Name
);
9171 CXString
clang_Module_getFullName(CXModule CXMod
) {
9173 return cxstring::createEmpty();
9174 Module
*Mod
= static_cast<Module
*>(CXMod
);
9175 return cxstring::createDup(Mod
->getFullModuleName());
9178 int clang_Module_isSystem(CXModule CXMod
) {
9181 Module
*Mod
= static_cast<Module
*>(CXMod
);
9182 return Mod
->IsSystem
;
9185 unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU
,
9187 if (isNotUsableTU(TU
)) {
9193 Module
*Mod
= static_cast<Module
*>(CXMod
);
9194 FileManager
&FileMgr
= cxtu::getASTUnit(TU
)->getFileManager();
9195 ArrayRef
<FileEntryRef
> TopHeaders
= Mod
->getTopHeaders(FileMgr
);
9196 return TopHeaders
.size();
9199 CXFile
clang_Module_getTopLevelHeader(CXTranslationUnit TU
, CXModule CXMod
,
9201 if (isNotUsableTU(TU
)) {
9207 Module
*Mod
= static_cast<Module
*>(CXMod
);
9208 FileManager
&FileMgr
= cxtu::getASTUnit(TU
)->getFileManager();
9210 ArrayRef
<FileEntryRef
> TopHeaders
= Mod
->getTopHeaders(FileMgr
);
9211 if (Index
< TopHeaders
.size())
9212 return cxfile::makeCXFile(TopHeaders
[Index
]);
9217 //===----------------------------------------------------------------------===//
9218 // C++ AST instrospection.
9219 //===----------------------------------------------------------------------===//
9221 unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C
) {
9222 if (!clang_isDeclaration(C
.kind
))
9225 const Decl
*D
= cxcursor::getCursorDecl(C
);
9226 const CXXConstructorDecl
*Constructor
=
9227 D
? dyn_cast_or_null
<CXXConstructorDecl
>(D
->getAsFunction()) : nullptr;
9228 return (Constructor
&& Constructor
->isDefaultConstructor()) ? 1 : 0;
9231 unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C
) {
9232 if (!clang_isDeclaration(C
.kind
))
9235 const Decl
*D
= cxcursor::getCursorDecl(C
);
9236 const CXXConstructorDecl
*Constructor
=
9237 D
? dyn_cast_or_null
<CXXConstructorDecl
>(D
->getAsFunction()) : nullptr;
9238 return (Constructor
&& Constructor
->isCopyConstructor()) ? 1 : 0;
9241 unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C
) {
9242 if (!clang_isDeclaration(C
.kind
))
9245 const Decl
*D
= cxcursor::getCursorDecl(C
);
9246 const CXXConstructorDecl
*Constructor
=
9247 D
? dyn_cast_or_null
<CXXConstructorDecl
>(D
->getAsFunction()) : nullptr;
9248 return (Constructor
&& Constructor
->isMoveConstructor()) ? 1 : 0;
9251 unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C
) {
9252 if (!clang_isDeclaration(C
.kind
))
9255 const Decl
*D
= cxcursor::getCursorDecl(C
);
9256 const CXXConstructorDecl
*Constructor
=
9257 D
? dyn_cast_or_null
<CXXConstructorDecl
>(D
->getAsFunction()) : nullptr;
9258 // Passing 'false' excludes constructors marked 'explicit'.
9259 return (Constructor
&& Constructor
->isConvertingConstructor(false)) ? 1 : 0;
9262 unsigned clang_CXXField_isMutable(CXCursor C
) {
9263 if (!clang_isDeclaration(C
.kind
))
9266 if (const auto D
= cxcursor::getCursorDecl(C
))
9267 if (const auto FD
= dyn_cast_or_null
<FieldDecl
>(D
))
9268 return FD
->isMutable() ? 1 : 0;
9272 unsigned clang_CXXMethod_isPureVirtual(CXCursor C
) {
9273 if (!clang_isDeclaration(C
.kind
))
9276 const Decl
*D
= cxcursor::getCursorDecl(C
);
9277 const CXXMethodDecl
*Method
=
9278 D
? dyn_cast_or_null
<CXXMethodDecl
>(D
->getAsFunction()) : nullptr;
9279 return (Method
&& Method
->isPureVirtual()) ? 1 : 0;
9282 unsigned clang_CXXMethod_isConst(CXCursor C
) {
9283 if (!clang_isDeclaration(C
.kind
))
9286 const Decl
*D
= cxcursor::getCursorDecl(C
);
9287 const CXXMethodDecl
*Method
=
9288 D
? dyn_cast_or_null
<CXXMethodDecl
>(D
->getAsFunction()) : nullptr;
9289 return (Method
&& Method
->getMethodQualifiers().hasConst()) ? 1 : 0;
9292 unsigned clang_CXXMethod_isDefaulted(CXCursor C
) {
9293 if (!clang_isDeclaration(C
.kind
))
9296 const Decl
*D
= cxcursor::getCursorDecl(C
);
9297 const CXXMethodDecl
*Method
=
9298 D
? dyn_cast_or_null
<CXXMethodDecl
>(D
->getAsFunction()) : nullptr;
9299 return (Method
&& Method
->isDefaulted()) ? 1 : 0;
9302 unsigned clang_CXXMethod_isDeleted(CXCursor C
) {
9303 if (!clang_isDeclaration(C
.kind
))
9306 const Decl
*D
= cxcursor::getCursorDecl(C
);
9307 const CXXMethodDecl
*Method
=
9308 D
? dyn_cast_if_present
<CXXMethodDecl
>(D
->getAsFunction()) : nullptr;
9309 return (Method
&& Method
->isDeleted()) ? 1 : 0;
9312 unsigned clang_CXXMethod_isStatic(CXCursor C
) {
9313 if (!clang_isDeclaration(C
.kind
))
9316 const Decl
*D
= cxcursor::getCursorDecl(C
);
9317 const CXXMethodDecl
*Method
=
9318 D
? dyn_cast_or_null
<CXXMethodDecl
>(D
->getAsFunction()) : nullptr;
9319 return (Method
&& Method
->isStatic()) ? 1 : 0;
9322 unsigned clang_CXXMethod_isVirtual(CXCursor C
) {
9323 if (!clang_isDeclaration(C
.kind
))
9326 const Decl
*D
= cxcursor::getCursorDecl(C
);
9327 const CXXMethodDecl
*Method
=
9328 D
? dyn_cast_or_null
<CXXMethodDecl
>(D
->getAsFunction()) : nullptr;
9329 return (Method
&& Method
->isVirtual()) ? 1 : 0;
9332 unsigned clang_CXXMethod_isCopyAssignmentOperator(CXCursor C
) {
9333 if (!clang_isDeclaration(C
.kind
))
9336 const Decl
*D
= cxcursor::getCursorDecl(C
);
9337 const CXXMethodDecl
*Method
=
9338 D
? dyn_cast_or_null
<CXXMethodDecl
>(D
->getAsFunction()) : nullptr;
9340 return (Method
&& Method
->isCopyAssignmentOperator()) ? 1 : 0;
9343 unsigned clang_CXXMethod_isMoveAssignmentOperator(CXCursor C
) {
9344 if (!clang_isDeclaration(C
.kind
))
9347 const Decl
*D
= cxcursor::getCursorDecl(C
);
9348 const CXXMethodDecl
*Method
=
9349 D
? dyn_cast_or_null
<CXXMethodDecl
>(D
->getAsFunction()) : nullptr;
9351 return (Method
&& Method
->isMoveAssignmentOperator()) ? 1 : 0;
9354 unsigned clang_CXXMethod_isExplicit(CXCursor C
) {
9355 if (!clang_isDeclaration(C
.kind
))
9358 const Decl
*D
= cxcursor::getCursorDecl(C
);
9359 const FunctionDecl
*FD
= D
->getAsFunction();
9364 if (const auto *Ctor
= dyn_cast
<CXXConstructorDecl
>(FD
))
9365 return Ctor
->isExplicit();
9367 if (const auto *Conv
= dyn_cast
<CXXConversionDecl
>(FD
))
9368 return Conv
->isExplicit();
9373 unsigned clang_CXXRecord_isAbstract(CXCursor C
) {
9374 if (!clang_isDeclaration(C
.kind
))
9377 const auto *D
= cxcursor::getCursorDecl(C
);
9378 const auto *RD
= dyn_cast_or_null
<CXXRecordDecl
>(D
);
9380 RD
= RD
->getDefinition();
9381 return (RD
&& RD
->isAbstract()) ? 1 : 0;
9384 unsigned clang_EnumDecl_isScoped(CXCursor C
) {
9385 if (!clang_isDeclaration(C
.kind
))
9388 const Decl
*D
= cxcursor::getCursorDecl(C
);
9389 auto *Enum
= dyn_cast_or_null
<EnumDecl
>(D
);
9390 return (Enum
&& Enum
->isScoped()) ? 1 : 0;
9393 //===----------------------------------------------------------------------===//
9394 // Attribute introspection.
9395 //===----------------------------------------------------------------------===//
9397 CXType
clang_getIBOutletCollectionType(CXCursor C
) {
9398 if (C
.kind
!= CXCursor_IBOutletCollectionAttr
)
9399 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C
));
9401 const IBOutletCollectionAttr
*A
=
9402 cast
<IBOutletCollectionAttr
>(cxcursor::getCursorAttr(C
));
9404 return cxtype::MakeCXType(A
->getInterface(), cxcursor::getCursorTU(C
));
9407 //===----------------------------------------------------------------------===//
9408 // Inspecting memory usage.
9409 //===----------------------------------------------------------------------===//
9411 typedef std::vector
<CXTUResourceUsageEntry
> MemUsageEntries
;
9413 static inline void createCXTUResourceUsageEntry(MemUsageEntries
&entries
,
9414 enum CXTUResourceUsageKind k
,
9415 unsigned long amount
) {
9416 CXTUResourceUsageEntry entry
= {k
, amount
};
9417 entries
.push_back(entry
);
9420 const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind
) {
9421 const char *str
= "";
9423 case CXTUResourceUsage_AST
:
9424 str
= "ASTContext: expressions, declarations, and types";
9426 case CXTUResourceUsage_Identifiers
:
9427 str
= "ASTContext: identifiers";
9429 case CXTUResourceUsage_Selectors
:
9430 str
= "ASTContext: selectors";
9432 case CXTUResourceUsage_GlobalCompletionResults
:
9433 str
= "Code completion: cached global results";
9435 case CXTUResourceUsage_SourceManagerContentCache
:
9436 str
= "SourceManager: content cache allocator";
9438 case CXTUResourceUsage_AST_SideTables
:
9439 str
= "ASTContext: side tables";
9441 case CXTUResourceUsage_SourceManager_Membuffer_Malloc
:
9442 str
= "SourceManager: malloc'ed memory buffers";
9444 case CXTUResourceUsage_SourceManager_Membuffer_MMap
:
9445 str
= "SourceManager: mmap'ed memory buffers";
9447 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc
:
9448 str
= "ExternalASTSource: malloc'ed memory buffers";
9450 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap
:
9451 str
= "ExternalASTSource: mmap'ed memory buffers";
9453 case CXTUResourceUsage_Preprocessor
:
9454 str
= "Preprocessor: malloc'ed memory";
9456 case CXTUResourceUsage_PreprocessingRecord
:
9457 str
= "Preprocessor: PreprocessingRecord";
9459 case CXTUResourceUsage_SourceManager_DataStructures
:
9460 str
= "SourceManager: data structures and tables";
9462 case CXTUResourceUsage_Preprocessor_HeaderSearch
:
9463 str
= "Preprocessor: header search tables";
9469 CXTUResourceUsage
clang_getCXTUResourceUsage(CXTranslationUnit TU
) {
9470 if (isNotUsableTU(TU
)) {
9472 CXTUResourceUsage usage
= {(void *)nullptr, 0, nullptr};
9476 ASTUnit
*astUnit
= cxtu::getASTUnit(TU
);
9477 std::unique_ptr
<MemUsageEntries
> entries(new MemUsageEntries());
9478 ASTContext
&astContext
= astUnit
->getASTContext();
9480 // How much memory is used by AST nodes and types?
9481 createCXTUResourceUsageEntry(
9482 *entries
, CXTUResourceUsage_AST
,
9483 (unsigned long)astContext
.getASTAllocatedMemory());
9485 // How much memory is used by identifiers?
9486 createCXTUResourceUsageEntry(
9487 *entries
, CXTUResourceUsage_Identifiers
,
9488 (unsigned long)astContext
.Idents
.getAllocator().getTotalMemory());
9490 // How much memory is used for selectors?
9491 createCXTUResourceUsageEntry(
9492 *entries
, CXTUResourceUsage_Selectors
,
9493 (unsigned long)astContext
.Selectors
.getTotalMemory());
9495 // How much memory is used by ASTContext's side tables?
9496 createCXTUResourceUsageEntry(
9497 *entries
, CXTUResourceUsage_AST_SideTables
,
9498 (unsigned long)astContext
.getSideTableAllocatedMemory());
9500 // How much memory is used for caching global code completion results?
9501 unsigned long completionBytes
= 0;
9502 if (GlobalCodeCompletionAllocator
*completionAllocator
=
9503 astUnit
->getCachedCompletionAllocator().get()) {
9504 completionBytes
= completionAllocator
->getTotalMemory();
9506 createCXTUResourceUsageEntry(
9507 *entries
, CXTUResourceUsage_GlobalCompletionResults
, completionBytes
);
9509 // How much memory is being used by SourceManager's content cache?
9510 createCXTUResourceUsageEntry(
9511 *entries
, CXTUResourceUsage_SourceManagerContentCache
,
9512 (unsigned long)astContext
.getSourceManager().getContentCacheSize());
9514 // How much memory is being used by the MemoryBuffer's in SourceManager?
9515 const SourceManager::MemoryBufferSizes
&srcBufs
=
9516 astUnit
->getSourceManager().getMemoryBufferSizes();
9518 createCXTUResourceUsageEntry(*entries
,
9519 CXTUResourceUsage_SourceManager_Membuffer_Malloc
,
9520 (unsigned long)srcBufs
.malloc_bytes
);
9521 createCXTUResourceUsageEntry(*entries
,
9522 CXTUResourceUsage_SourceManager_Membuffer_MMap
,
9523 (unsigned long)srcBufs
.mmap_bytes
);
9524 createCXTUResourceUsageEntry(
9525 *entries
, CXTUResourceUsage_SourceManager_DataStructures
,
9526 (unsigned long)astContext
.getSourceManager().getDataStructureSizes());
9528 // How much memory is being used by the ExternalASTSource?
9529 if (ExternalASTSource
*esrc
= astContext
.getExternalSource()) {
9530 const ExternalASTSource::MemoryBufferSizes
&sizes
=
9531 esrc
->getMemoryBufferSizes();
9533 createCXTUResourceUsageEntry(
9534 *entries
, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc
,
9535 (unsigned long)sizes
.malloc_bytes
);
9536 createCXTUResourceUsageEntry(
9537 *entries
, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap
,
9538 (unsigned long)sizes
.mmap_bytes
);
9541 // How much memory is being used by the Preprocessor?
9542 Preprocessor
&pp
= astUnit
->getPreprocessor();
9543 createCXTUResourceUsageEntry(*entries
, CXTUResourceUsage_Preprocessor
,
9544 pp
.getTotalMemory());
9546 if (PreprocessingRecord
*pRec
= pp
.getPreprocessingRecord()) {
9547 createCXTUResourceUsageEntry(*entries
,
9548 CXTUResourceUsage_PreprocessingRecord
,
9549 pRec
->getTotalMemory());
9552 createCXTUResourceUsageEntry(*entries
,
9553 CXTUResourceUsage_Preprocessor_HeaderSearch
,
9554 pp
.getHeaderSearchInfo().getTotalMemory());
9556 CXTUResourceUsage usage
= {(void *)entries
.get(), (unsigned)entries
->size(),
9557 !entries
->empty() ? &(*entries
)[0] : nullptr};
9558 (void)entries
.release();
9562 void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage
) {
9564 delete (MemUsageEntries
*)usage
.data
;
9567 CXSourceRangeList
*clang_getSkippedRanges(CXTranslationUnit TU
, CXFile file
) {
9568 CXSourceRangeList
*skipped
= new CXSourceRangeList
;
9570 skipped
->ranges
= nullptr;
9572 if (isNotUsableTU(TU
)) {
9580 ASTUnit
*astUnit
= cxtu::getASTUnit(TU
);
9581 PreprocessingRecord
*ppRec
=
9582 astUnit
->getPreprocessor().getPreprocessingRecord();
9586 ASTContext
&Ctx
= astUnit
->getASTContext();
9587 SourceManager
&sm
= Ctx
.getSourceManager();
9588 FileEntryRef fileEntry
= *cxfile::getFileEntryRef(file
);
9589 FileID wantedFileID
= sm
.translateFile(fileEntry
);
9590 bool isMainFile
= wantedFileID
== sm
.getMainFileID();
9592 const std::vector
<SourceRange
> &SkippedRanges
= ppRec
->getSkippedRanges();
9593 std::vector
<SourceRange
> wantedRanges
;
9594 for (std::vector
<SourceRange
>::const_iterator i
= SkippedRanges
.begin(),
9595 ei
= SkippedRanges
.end();
9597 if (sm
.getFileID(i
->getBegin()) == wantedFileID
||
9598 sm
.getFileID(i
->getEnd()) == wantedFileID
)
9599 wantedRanges
.push_back(*i
);
9600 else if (isMainFile
&& (astUnit
->isInPreambleFileID(i
->getBegin()) ||
9601 astUnit
->isInPreambleFileID(i
->getEnd())))
9602 wantedRanges
.push_back(*i
);
9605 skipped
->count
= wantedRanges
.size();
9606 skipped
->ranges
= new CXSourceRange
[skipped
->count
];
9607 for (unsigned i
= 0, ei
= skipped
->count
; i
!= ei
; ++i
)
9608 skipped
->ranges
[i
] = cxloc::translateSourceRange(Ctx
, wantedRanges
[i
]);
9613 CXSourceRangeList
*clang_getAllSkippedRanges(CXTranslationUnit TU
) {
9614 CXSourceRangeList
*skipped
= new CXSourceRangeList
;
9616 skipped
->ranges
= nullptr;
9618 if (isNotUsableTU(TU
)) {
9623 ASTUnit
*astUnit
= cxtu::getASTUnit(TU
);
9624 PreprocessingRecord
*ppRec
=
9625 astUnit
->getPreprocessor().getPreprocessingRecord();
9629 ASTContext
&Ctx
= astUnit
->getASTContext();
9631 const std::vector
<SourceRange
> &SkippedRanges
= ppRec
->getSkippedRanges();
9633 skipped
->count
= SkippedRanges
.size();
9634 skipped
->ranges
= new CXSourceRange
[skipped
->count
];
9635 for (unsigned i
= 0, ei
= skipped
->count
; i
!= ei
; ++i
)
9636 skipped
->ranges
[i
] = cxloc::translateSourceRange(Ctx
, SkippedRanges
[i
]);
9641 void clang_disposeSourceRangeList(CXSourceRangeList
*ranges
) {
9643 delete[] ranges
->ranges
;
9648 void clang::PrintLibclangResourceUsage(CXTranslationUnit TU
) {
9649 CXTUResourceUsage Usage
= clang_getCXTUResourceUsage(TU
);
9650 for (unsigned I
= 0; I
!= Usage
.numEntries
; ++I
)
9651 fprintf(stderr
, " %s: %lu\n",
9652 clang_getTUResourceUsageName(Usage
.entries
[I
].kind
),
9653 Usage
.entries
[I
].amount
);
9655 clang_disposeCXTUResourceUsage(Usage
);
9658 CXCursor
clang_Cursor_getVarDeclInitializer(CXCursor cursor
) {
9659 const Decl
*const D
= getCursorDecl(cursor
);
9661 return clang_getNullCursor();
9662 const auto *const VD
= dyn_cast
<VarDecl
>(D
);
9664 return clang_getNullCursor();
9665 const Expr
*const Init
= VD
->getInit();
9667 return clang_getNullCursor();
9669 return cxcursor::MakeCXCursor(Init
, VD
, cxcursor::getCursorTU(cursor
));
9672 int clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor
) {
9673 const Decl
*const D
= getCursorDecl(cursor
);
9676 const auto *const VD
= dyn_cast
<VarDecl
>(D
);
9680 return VD
->hasGlobalStorage();
9683 int clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor
) {
9684 const Decl
*const D
= getCursorDecl(cursor
);
9687 const auto *const VD
= dyn_cast
<VarDecl
>(D
);
9691 return VD
->hasExternalStorage();
9694 //===----------------------------------------------------------------------===//
9695 // Misc. utility functions.
9696 //===----------------------------------------------------------------------===//
9698 /// Default to using our desired 8 MB stack size on "safety" threads.
9699 static unsigned SafetyStackThreadSize
= DesiredStackSize
;
9703 bool RunSafely(llvm::CrashRecoveryContext
&CRC
, llvm::function_ref
<void()> Fn
,
9706 Size
= GetSafetyThreadStackSize();
9707 if (Size
&& !getenv("LIBCLANG_NOTHREADS"))
9708 return CRC
.RunSafelyOnThread(Fn
, Size
);
9709 return CRC
.RunSafely(Fn
);
9712 unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize
; }
9714 void SetSafetyThreadStackSize(unsigned Value
) { SafetyStackThreadSize
= Value
; }
9716 } // namespace clang
9718 void clang::setThreadBackgroundPriority() {
9719 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
9722 #if LLVM_ENABLE_THREADS
9723 // The function name setThreadBackgroundPriority is for historical reasons;
9724 // Low is more appropriate.
9725 llvm::set_thread_priority(llvm::ThreadPriority::Low
);
9729 void cxindex::printDiagsToStderr(ASTUnit
*Unit
) {
9733 for (ASTUnit::stored_diag_iterator D
= Unit
->stored_diag_begin(),
9734 DEnd
= Unit
->stored_diag_end();
9736 CXStoredDiagnostic
Diag(*D
, Unit
->getLangOpts());
9738 clang_formatDiagnostic(&Diag
, clang_defaultDiagnosticDisplayOptions());
9739 fprintf(stderr
, "%s\n", clang_getCString(Msg
));
9740 clang_disposeString(Msg
);
9743 // On Windows, force a flush, since there may be multiple copies of
9744 // stderr and stdout in the file system, all with different buffers
9745 // but writing to the same device.
9750 MacroInfo
*cxindex::getMacroInfo(const IdentifierInfo
&II
,
9751 SourceLocation MacroDefLoc
,
9752 CXTranslationUnit TU
) {
9753 if (MacroDefLoc
.isInvalid() || !TU
)
9755 if (!II
.hadMacroDefinition())
9758 ASTUnit
*Unit
= cxtu::getASTUnit(TU
);
9759 Preprocessor
&PP
= Unit
->getPreprocessor();
9760 MacroDirective
*MD
= PP
.getLocalMacroDirectiveHistory(&II
);
9762 for (MacroDirective::DefInfo Def
= MD
->getDefinition(); Def
;
9763 Def
= Def
.getPreviousDefinition()) {
9764 if (MacroDefLoc
== Def
.getMacroInfo()->getDefinitionLoc())
9765 return Def
.getMacroInfo();
9772 const MacroInfo
*cxindex::getMacroInfo(const MacroDefinitionRecord
*MacroDef
,
9773 CXTranslationUnit TU
) {
9774 if (!MacroDef
|| !TU
)
9776 const IdentifierInfo
*II
= MacroDef
->getName();
9780 return getMacroInfo(*II
, MacroDef
->getLocation(), TU
);
9783 MacroDefinitionRecord
*
9784 cxindex::checkForMacroInMacroDefinition(const MacroInfo
*MI
, const Token
&Tok
,
9785 CXTranslationUnit TU
) {
9788 if (Tok
.isNot(tok::raw_identifier
))
9791 if (MI
->getNumTokens() == 0)
9793 SourceRange
DefRange(MI
->getReplacementToken(0).getLocation(),
9794 MI
->getDefinitionEndLoc());
9795 ASTUnit
*Unit
= cxtu::getASTUnit(TU
);
9797 // Check that the token is inside the definition and not its argument list.
9798 SourceManager
&SM
= Unit
->getSourceManager();
9799 if (SM
.isBeforeInTranslationUnit(Tok
.getLocation(), DefRange
.getBegin()))
9801 if (SM
.isBeforeInTranslationUnit(DefRange
.getEnd(), Tok
.getLocation()))
9804 Preprocessor
&PP
= Unit
->getPreprocessor();
9805 PreprocessingRecord
*PPRec
= PP
.getPreprocessingRecord();
9809 IdentifierInfo
&II
= PP
.getIdentifierTable().get(Tok
.getRawIdentifier());
9810 if (!II
.hadMacroDefinition())
9813 // Check that the identifier is not one of the macro arguments.
9814 if (llvm::is_contained(MI
->params(), &II
))
9817 MacroDirective
*InnerMD
= PP
.getLocalMacroDirectiveHistory(&II
);
9821 return PPRec
->findMacroDefinition(InnerMD
->getMacroInfo());
9824 MacroDefinitionRecord
*
9825 cxindex::checkForMacroInMacroDefinition(const MacroInfo
*MI
, SourceLocation Loc
,
9826 CXTranslationUnit TU
) {
9827 if (Loc
.isInvalid() || !MI
|| !TU
)
9830 if (MI
->getNumTokens() == 0)
9832 ASTUnit
*Unit
= cxtu::getASTUnit(TU
);
9833 Preprocessor
&PP
= Unit
->getPreprocessor();
9834 if (!PP
.getPreprocessingRecord())
9836 Loc
= Unit
->getSourceManager().getSpellingLoc(Loc
);
9838 if (PP
.getRawToken(Loc
, Tok
))
9841 return checkForMacroInMacroDefinition(MI
, Tok
, TU
);
9844 CXString
clang_getClangVersion() {
9845 return cxstring::createDup(getClangFullVersion());
9848 Logger
&cxindex::Logger::operator<<(CXTranslationUnit TU
) {
9850 if (ASTUnit
*Unit
= cxtu::getASTUnit(TU
)) {
9851 LogOS
<< '<' << Unit
->getMainFileName() << '>';
9852 if (Unit
->isMainFileAST())
9853 LogOS
<< " (" << Unit
->getASTFileName() << ')';
9857 LogOS
<< "<NULL TU>";
9862 Logger
&cxindex::Logger::operator<<(FileEntryRef FE
) {
9863 *this << FE
.getName();
9867 Logger
&cxindex::Logger::operator<<(CXCursor cursor
) {
9868 CXString cursorName
= clang_getCursorDisplayName(cursor
);
9869 *this << cursorName
<< "@" << clang_getCursorLocation(cursor
);
9870 clang_disposeString(cursorName
);
9874 Logger
&cxindex::Logger::operator<<(CXSourceLocation Loc
) {
9876 unsigned Line
, Column
;
9877 clang_getFileLocation(Loc
, &File
, &Line
, &Column
, nullptr);
9878 CXString FileName
= clang_getFileName(File
);
9879 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName
), Line
, Column
);
9880 clang_disposeString(FileName
);
9884 Logger
&cxindex::Logger::operator<<(CXSourceRange range
) {
9885 CXSourceLocation BLoc
= clang_getRangeStart(range
);
9886 CXSourceLocation ELoc
= clang_getRangeEnd(range
);
9889 unsigned BLine
, BColumn
;
9890 clang_getFileLocation(BLoc
, &BFile
, &BLine
, &BColumn
, nullptr);
9893 unsigned ELine
, EColumn
;
9894 clang_getFileLocation(ELoc
, &EFile
, &ELine
, &EColumn
, nullptr);
9896 CXString BFileName
= clang_getFileName(BFile
);
9897 if (BFile
== EFile
) {
9898 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName
),
9899 BLine
, BColumn
, ELine
, EColumn
);
9901 CXString EFileName
= clang_getFileName(EFile
);
9902 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName
), BLine
,
9904 << llvm::format("%s:%d:%d]", clang_getCString(EFileName
), ELine
,
9906 clang_disposeString(EFileName
);
9908 clang_disposeString(BFileName
);
9912 Logger
&cxindex::Logger::operator<<(CXString Str
) {
9913 *this << clang_getCString(Str
);
9917 Logger
&cxindex::Logger::operator<<(const llvm::format_object_base
&Fmt
) {
9922 static llvm::ManagedStatic
<std::mutex
> LoggingMutex
;
9924 cxindex::Logger::~Logger() {
9925 std::lock_guard
<std::mutex
> L(*LoggingMutex
);
9927 static llvm::TimeRecord sBeginTR
= llvm::TimeRecord::getCurrentTime();
9929 raw_ostream
&OS
= llvm::errs();
9930 OS
<< "[libclang:" << Name
<< ':';
9932 #ifdef USE_DARWIN_THREADS
9933 // TODO: Portability.
9934 mach_port_t tid
= pthread_mach_thread_np(pthread_self());
9938 llvm::TimeRecord TR
= llvm::TimeRecord::getCurrentTime();
9939 OS
<< llvm::format("%7.4f] ", TR
.getWallTime() - sBeginTR
.getWallTime());
9943 llvm::sys::PrintStackTrace(OS
);
9944 OS
<< "--------------------------------------------------\n";
9948 CXString
clang_getBinaryOperatorKindSpelling(enum CXBinaryOperatorKind kind
) {
9949 return cxstring::createRef(
9950 BinaryOperator::getOpcodeStr(static_cast<BinaryOperatorKind
>(kind
- 1)));
9953 enum CXBinaryOperatorKind
clang_getCursorBinaryOperatorKind(CXCursor cursor
) {
9954 if (clang_isExpression(cursor
.kind
)) {
9955 const Expr
*expr
= getCursorExpr(cursor
);
9957 if (const auto *op
= dyn_cast
<BinaryOperator
>(expr
))
9958 return static_cast<CXBinaryOperatorKind
>(op
->getOpcode() + 1);
9960 if (const auto *op
= dyn_cast
<CXXRewrittenBinaryOperator
>(expr
))
9961 return static_cast<CXBinaryOperatorKind
>(op
->getOpcode() + 1);
9964 return CXBinaryOperator_Invalid
;
9967 CXString
clang_getUnaryOperatorKindSpelling(enum CXUnaryOperatorKind kind
) {
9968 return cxstring::createRef(
9969 UnaryOperator::getOpcodeStr(static_cast<UnaryOperatorKind
>(kind
- 1)));
9972 enum CXUnaryOperatorKind
clang_getCursorUnaryOperatorKind(CXCursor cursor
) {
9973 if (clang_isExpression(cursor
.kind
)) {
9974 const Expr
*expr
= getCursorExpr(cursor
);
9976 if (const auto *op
= dyn_cast
<UnaryOperator
>(expr
))
9977 return static_cast<CXUnaryOperatorKind
>(op
->getOpcode() + 1);
9980 return CXUnaryOperator_Invalid
;