Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220222111401+cfd6ba89fd9f/clang/tools/libclang/CIndex.cpp
Warning:line 8321, column 18
Called C++ object pointer is null

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