Bug Summary

File:build/source/clang/tools/libclang/CIndex.cpp
Warning:line 9079, column 15
Value stored to 'str' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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