blob: 589d38fa615a31524f2910d255f02f1f83a2712c [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Guy Benyei11169dd2012-12-18 14:30:41 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the main API hooks in the Clang-C Source Indexing
10// library.
11//
12//===----------------------------------------------------------------------===//
13
Guy Benyei11169dd2012-12-18 14:30:41 +000014#include "CIndexDiagnostic.h"
Mehdi Amini9670f842016-07-18 19:02:11 +000015#include "CIndexer.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000016#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000017#include "CXCursor.h"
18#include "CXSourceLocation.h"
19#include "CXString.h"
20#include "CXTranslationUnit.h"
21#include "CXType.h"
22#include "CursorVisitor.h"
Jan Korousf7d23762019-09-12 22:55:55 +000023#include "clang-c/FatalErrorHandler.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Puyan Lotfi9721fbf2020-04-23 02:20:56 -040025#include "clang/AST/DeclObjCCommon.h"
Jan Korous7e36ecd2019-09-05 20:33:52 +000026#include "clang/AST/Mangle.h"
Alexey Bataev95598342020-02-10 15:49:05 -050027#include "clang/AST/OpenMPClause.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000028#include "clang/AST/StmtVisitor.h"
29#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000030#include "clang/Basic/DiagnosticCategories.h"
31#include "clang/Basic/DiagnosticIDs.h"
Richard Smith0a7b2972018-07-03 21:34:13 +000032#include "clang/Basic/Stack.h"
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +000033#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Basic/Version.h"
35#include "clang/Frontend/ASTUnit.h"
36#include "clang/Frontend/CompilerInstance.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000037#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000038#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"
Alp Toker1d257e12014-06-04 03:28:55 +000045#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000046#include "llvm/Support/Compiler.h"
47#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000048#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000049#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000050#include "llvm/Support/MemoryBuffer.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/Program.h"
52#include "llvm/Support/SaveAndRestore.h"
53#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000054#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000055#include "llvm/Support/Threading.h"
56#include "llvm/Support/Timer.h"
57#include "llvm/Support/raw_ostream.h"
Benjamin Kramer762bc332019-08-07 14:44:40 +000058#include <mutex>
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
David Blaikieea4395e2017-01-06 19:49:01 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,
74 std::unique_ptr<ASTUnit> AU) {
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000076 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000077 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000078 CXTranslationUnit D = new CXTranslationUnitImpl();
79 D->CIdx = CIdx;
David Blaikieea4395e2017-01-06 19:49:01 +000080 D->TheASTUnit = AU.release();
Dmitri Gribenko74895212013-02-03 13:52:47 +000081 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000082 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000083 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000084 D->CommentToXML = nullptr;
Alex Lorenz690f0e22017-12-07 20:37:50 +000085 D->ParsingOptions = 0;
86 D->Arguments = {};
Guy Benyei11169dd2012-12-18 14:30:41 +000087 return D;
88}
89
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000090bool cxtu::isASTReadError(ASTUnit *AU) {
91 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
92 DEnd = AU->stored_diag_end();
93 D != DEnd; ++D) {
94 if (D->getLevel() >= DiagnosticsEngine::Error &&
95 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
96 diag::DiagCat_AST_Deserialization_Issue)
97 return true;
98 }
99 return false;
100}
101
Guy Benyei11169dd2012-12-18 14:30:41 +0000102cxtu::CXTUOwner::~CXTUOwner() {
103 if (TU)
104 clang_disposeTranslationUnit(TU);
105}
106
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000107/// Compare two source ranges to determine their relative position in
Guy Benyei11169dd2012-12-18 14:30:41 +0000108/// the translation unit.
Michael Kruse7520cf02020-03-25 09:26:14 -0500109static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1,
Guy Benyei11169dd2012-12-18 14:30:41 +0000110 SourceRange R2) {
111 assert(R1.isValid() && "First range is invalid?");
112 assert(R2.isValid() && "Second range is invalid?");
113 if (R1.getEnd() != R2.getBegin() &&
114 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
115 return RangeBefore;
116 if (R2.getEnd() != R1.getBegin() &&
117 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
118 return RangeAfter;
119 return RangeOverlap;
120}
121
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000122/// Determine if a source location falls within, before, or after a
Guy Benyei11169dd2012-12-18 14:30:41 +0000123/// a given source range.
124static RangeComparisonResult LocationCompare(SourceManager &SM,
125 SourceLocation L, SourceRange R) {
126 assert(R.isValid() && "First range is invalid?");
127 assert(L.isValid() && "Second range is invalid?");
128 if (L == R.getBegin() || L == R.getEnd())
129 return RangeOverlap;
130 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
131 return RangeBefore;
132 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
133 return RangeAfter;
134 return RangeOverlap;
135}
136
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000137/// Translate a Clang source range into a CIndex source range.
Guy Benyei11169dd2012-12-18 14:30:41 +0000138///
139/// Clang internally represents ranges where the end location points to the
140/// start of the token at the end. However, for external clients it is more
141/// useful to have a CXSourceRange be a proper half-open interval. This routine
142/// does the appropriate translation.
143CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
144 const LangOptions &LangOpts,
145 const CharSourceRange &R) {
146 // We want the last character in this location, so we will adjust the
147 // location accordingly.
148 SourceLocation EndLoc = R.getEnd();
Richard Smithb5f81712018-04-30 05:25:48 +0000149 bool IsTokenRange = R.isTokenRange();
Michael Kruse7520cf02020-03-25 09:26:14 -0500150 if (EndLoc.isValid() && EndLoc.isMacroID() &&
151 !SM.isMacroArgExpansion(EndLoc)) {
Richard Smithb5f81712018-04-30 05:25:48 +0000152 CharSourceRange Expansion = SM.getExpansionRange(EndLoc);
153 EndLoc = Expansion.getEnd();
154 IsTokenRange = Expansion.isTokenRange();
155 }
156 if (IsTokenRange && EndLoc.isValid()) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500157 unsigned Length =
158 Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);
Guy Benyei11169dd2012-12-18 14:30:41 +0000159 EndLoc = EndLoc.getLocWithOffset(Length);
160 }
161
Bill Wendlingeade3622013-01-23 08:25:41 +0000162 CXSourceRange Result = {
Michael Kruse7520cf02020-03-25 09:26:14 -0500163 {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};
Guy Benyei11169dd2012-12-18 14:30:41 +0000164 return Result;
165}
166
167//===----------------------------------------------------------------------===//
168// Cursor visitor.
169//===----------------------------------------------------------------------===//
170
171static SourceRange getRawCursorExtent(CXCursor C);
172static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
173
Guy Benyei11169dd2012-12-18 14:30:41 +0000174RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
175 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
176}
177
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000178/// Visit the given cursor and, if requested by the visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +0000179/// its children.
180///
181/// \param Cursor the cursor to visit.
182///
183/// \param CheckedRegionOfInterest if true, then the caller already checked
184/// that this cursor is within the region of interest.
185///
186/// \returns true if the visitation should be aborted, false if it
187/// should continue.
188bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
189 if (clang_isInvalid(Cursor.kind))
190 return false;
191
192 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000193 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000194 if (!D) {
195 assert(0 && "Invalid declaration cursor");
196 return true; // abort.
197 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500198
Guy Benyei11169dd2012-12-18 14:30:41 +0000199 // Ignore implicit declarations, unless it's an objc method because
200 // currently we should report implicit methods for properties when indexing.
201 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
202 return false;
203 }
204
205 // If we have a range of interest, and this cursor doesn't intersect with it,
206 // we're done.
207 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
208 SourceRange Range = getRawCursorExtent(Cursor);
209 if (Range.isInvalid() || CompareRegionOfInterest(Range))
210 return false;
211 }
212
213 switch (Visitor(Cursor, Parent, ClientData)) {
214 case CXChildVisit_Break:
215 return true;
216
217 case CXChildVisit_Continue:
218 return false;
219
220 case CXChildVisit_Recurse: {
221 bool ret = VisitChildren(Cursor);
222 if (PostChildrenVisitor)
223 if (PostChildrenVisitor(Cursor, ClientData))
224 return true;
225 return ret;
226 }
227 }
228
229 llvm_unreachable("Invalid CXChildVisitResult!");
230}
231
232static bool visitPreprocessedEntitiesInRange(SourceRange R,
233 PreprocessingRecord &PPRec,
234 CursorVisitor &Visitor) {
235 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
236 FileID FID;
Michael Kruse7520cf02020-03-25 09:26:14 -0500237
Guy Benyei11169dd2012-12-18 14:30:41 +0000238 if (!Visitor.shouldVisitIncludedEntities()) {
239 // If the begin/end of the range lie in the same FileID, do the optimization
Michael Kruse7520cf02020-03-25 09:26:14 -0500240 // where we skip preprocessed entities that do not come from the same
241 // FileID.
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
243 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
244 FID = FileID();
245 }
246
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000247 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
248 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000249 PPRec, FID);
250}
251
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000252bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000253 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000254 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000255
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000256 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000257 SourceManager &SM = Unit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -0500258
259 std::pair<FileID, unsigned> Begin = SM.getDecomposedLoc(
260 SM.getFileLoc(RegionOfInterest.getBegin())),
261 End = SM.getDecomposedLoc(
262 SM.getFileLoc(RegionOfInterest.getEnd()));
Guy Benyei11169dd2012-12-18 14:30:41 +0000263
264 if (End.first != Begin.first) {
265 // If the end does not reside in the same file, try to recover by
266 // picking the end of the file of begin location.
267 End.first = Begin.first;
268 End.second = SM.getFileIDSize(Begin.first);
269 }
270
271 assert(Begin.first == End.first);
272 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000273 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -0500274
Guy Benyei11169dd2012-12-18 14:30:41 +0000275 FileID File = Begin.first;
276 unsigned Offset = Begin.second;
277 unsigned Length = End.second - Begin.second;
278
279 if (!VisitDeclsOnly && !VisitPreprocessorLast)
280 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000281 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000282
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 if (visitDeclsFromFileRegion(File, Offset, Length))
284 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000285
286 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000287 return visitPreprocessedEntitiesInRegion();
288
289 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000290}
291
292static bool isInLexicalContext(Decl *D, DeclContext *DC) {
293 if (!DC)
294 return false;
295
Michael Kruse7520cf02020-03-25 09:26:14 -0500296 for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;
297 DeclDC = DeclDC->getLexicalParent()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000298 if (DeclDC == DC)
299 return true;
300 }
301 return false;
302}
303
Michael Kruse7520cf02020-03-25 09:26:14 -0500304bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,
305 unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000306 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000307 SourceManager &SM = Unit->getSourceManager();
308 SourceRange Range = RegionOfInterest;
309
310 SmallVector<Decl *, 16> Decls;
311 Unit->findFileRegionDecls(File, Offset, Length, Decls);
312
313 // If we didn't find any file level decls for the file, try looking at the
314 // file that it was included from.
315 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
316 bool Invalid = false;
317 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
318 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000319 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000320
321 SourceLocation Outer;
322 if (SLEntry.isFile())
323 Outer = SLEntry.getFile().getIncludeLoc();
324 else
325 Outer = SLEntry.getExpansion().getExpansionLocStart();
326 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000327 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000328
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000329 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000330 Length = 0;
331 Unit->findFileRegionDecls(File, Offset, Length, Decls);
332 }
333
334 assert(!Decls.empty());
335
336 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000337 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000338 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
339 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000340 Decl *D = *DIt;
341 if (D->getSourceRange().isInvalid())
342 continue;
343
344 if (isInLexicalContext(D, CurDC))
345 continue;
346
347 CurDC = dyn_cast<DeclContext>(D);
348
349 if (TagDecl *TD = dyn_cast<TagDecl>(D))
350 if (!TD->isFreeStanding())
351 continue;
352
Michael Kruse7520cf02020-03-25 09:26:14 -0500353 RangeComparisonResult CompRes =
354 RangeCompare(SM, D->getSourceRange(), Range);
Guy Benyei11169dd2012-12-18 14:30:41 +0000355 if (CompRes == RangeBefore)
356 continue;
357 if (CompRes == RangeAfter)
358 break;
359
360 assert(CompRes == RangeOverlap);
361 VisitedAtLeastOnce = true;
362
363 if (isa<ObjCContainerDecl>(D)) {
364 FileDI_current = &DIt;
365 FileDE_current = DE;
366 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000367 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000368 }
369
370 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000371 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000372 }
373
374 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000375 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000376
377 // No Decls overlapped with the range. Move up the lexical context until there
378 // is a context that contains the range or we reach the translation unit
379 // level.
Michael Kruse7520cf02020-03-25 09:26:14 -0500380 DeclContext *DC = DIt == Decls.begin()
381 ? (*DIt)->getLexicalDeclContext()
382 : (*(DIt - 1))->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +0000383
384 while (DC && !DC->isTranslationUnit()) {
385 Decl *D = cast<Decl>(DC);
386 SourceRange CurDeclRange = D->getSourceRange();
387 if (CurDeclRange.isInvalid())
388 break;
389
390 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
392 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000393 }
394
395 DC = D->getLexicalDeclContext();
396 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000397
398 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000399}
400
401bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
402 if (!AU->getPreprocessor().getPreprocessingRecord())
403 return false;
404
Michael Kruse7520cf02020-03-25 09:26:14 -0500405 PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();
Guy Benyei11169dd2012-12-18 14:30:41 +0000406 SourceManager &SM = AU->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -0500407
Guy Benyei11169dd2012-12-18 14:30:41 +0000408 if (RegionOfInterest.isValid()) {
409 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
410 SourceLocation B = MappedRange.getBegin();
411 SourceLocation E = MappedRange.getEnd();
412
413 if (AU->isInPreambleFileID(B)) {
414 if (SM.isLoadedSourceLocation(E))
Michael Kruse7520cf02020-03-25 09:26:14 -0500415 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,
416 *this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000417
418 // Beginning of range lies in the preamble but it also extends beyond
419 // it into the main file. Split the range into 2 parts, one covering
420 // the preamble and another covering the main file. This allows subsequent
421 // calls to visitPreprocessedEntitiesInRange to accept a source range that
422 // lies in the same FileID, allowing it to skip preprocessed entities that
423 // do not come from the same FileID.
Michael Kruse7520cf02020-03-25 09:26:14 -0500424 bool breaked = visitPreprocessedEntitiesInRange(
425 SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);
426 if (breaked)
427 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000428 return visitPreprocessedEntitiesInRange(
Michael Kruse7520cf02020-03-25 09:26:14 -0500429 SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000430 }
431
432 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
433 }
434
Michael Kruse7520cf02020-03-25 09:26:14 -0500435 bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
436
Guy Benyei11169dd2012-12-18 14:30:41 +0000437 if (OnlyLocalDecls)
438 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
439 PPRec);
440
441 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
442}
443
Michael Kruse7520cf02020-03-25 09:26:14 -0500444template <typename InputIterator>
Guy Benyei11169dd2012-12-18 14:30:41 +0000445bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
446 InputIterator Last,
447 PreprocessingRecord &PPRec,
448 FileID FID) {
449 for (; First != Last; ++First) {
450 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
451 continue;
452
453 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000454 if (!PPE)
455 continue;
456
Guy Benyei11169dd2012-12-18 14:30:41 +0000457 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
458 if (Visit(MakeMacroExpansionCursor(ME, TU)))
459 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000460
Guy Benyei11169dd2012-12-18 14:30:41 +0000461 continue;
462 }
Richard Smith66a81862015-05-04 02:25:31 +0000463
464 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000465 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
466 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000467
Guy Benyei11169dd2012-12-18 14:30:41 +0000468 continue;
469 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500470
Guy Benyei11169dd2012-12-18 14:30:41 +0000471 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
472 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
473 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500474
Guy Benyei11169dd2012-12-18 14:30:41 +0000475 continue;
476 }
477 }
478
479 return false;
480}
481
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000482/// Visit the children of the given cursor.
Michael Kruse7520cf02020-03-25 09:26:14 -0500483///
Guy Benyei11169dd2012-12-18 14:30:41 +0000484/// \returns true if the visitation should be aborted, false if it
485/// should continue.
486bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500487 if (clang_isReference(Cursor.kind) &&
Guy Benyei11169dd2012-12-18 14:30:41 +0000488 Cursor.kind != CXCursor_CXXBaseSpecifier) {
489 // By definition, references have no children.
490 return false;
491 }
492
493 // Set the Parent field to Cursor, then back to its old value once we're
494 // done.
495 SetParentRAII SetParent(Parent, StmtParent, Cursor);
496
497 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000498 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000499 if (!D)
500 return false;
501
502 return VisitAttributes(D) || Visit(D);
503 }
504
505 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000506 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000507 return Visit(S);
508
509 return false;
510 }
511
512 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000513 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000514 return Visit(E);
515
516 return false;
517 }
518
519 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000520 CXTranslationUnit TU = getCursorTU(Cursor);
521 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -0500522
523 int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
Guy Benyei11169dd2012-12-18 14:30:41 +0000524 for (unsigned I = 0; I != 2; ++I) {
525 if (VisitOrder[I]) {
526 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
527 RegionOfInterest.isInvalid()) {
528 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -0500529 TLEnd = CXXUnit->top_level_end();
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 TL != TLEnd; ++TL) {
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000531 const Optional<bool> V = handleDeclForVisitation(*TL);
532 if (!V.hasValue())
533 continue;
534 return V.getValue();
Guy Benyei11169dd2012-12-18 14:30:41 +0000535 }
536 } else if (VisitDeclContext(
Michael Kruse7520cf02020-03-25 09:26:14 -0500537 CXXUnit->getASTContext().getTranslationUnitDecl()))
Guy Benyei11169dd2012-12-18 14:30:41 +0000538 return true;
539 continue;
540 }
541
542 // Walk the preprocessing record.
543 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
544 visitPreprocessedEntitiesInRegion();
545 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500546
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 return false;
548 }
549
550 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000551 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
553 return Visit(BaseTSInfo->getTypeLoc());
554 }
555 }
556 }
557
558 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000559 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -0500560 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000561 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000562 return Visit(cxcursor::MakeCursorObjCClassRef(
563 ObjT->getInterface(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000564 A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000565 }
566
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000567 // If pointing inside a macro definition, check if the token is an identifier
568 // that was ever defined as a macro. In such a case, create a "pseudo" macro
569 // expansion cursor for that token.
570 SourceLocation BeginLoc = RegionOfInterest.getBegin();
571 if (Cursor.kind == CXCursor_MacroDefinition &&
572 BeginLoc == RegionOfInterest.getEnd()) {
573 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000574 const MacroInfo *MI =
575 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000576 if (MacroDefinitionRecord *MacroDef =
577 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000578 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
579 }
580
Guy Benyei11169dd2012-12-18 14:30:41 +0000581 // Nothing to visit at the moment.
582 return false;
583}
584
585bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
586 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
587 if (Visit(TSInfo->getTypeLoc()))
Michael Kruse7520cf02020-03-25 09:26:14 -0500588 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 if (Stmt *Body = B->getBody())
591 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
592
593 return false;
594}
595
Ted Kremenek03325582013-02-21 01:29:01 +0000596Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000597 if (RegionOfInterest.isValid()) {
598 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
599 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000600 return None;
Michael Kruse7520cf02020-03-25 09:26:14 -0500601
Guy Benyei11169dd2012-12-18 14:30:41 +0000602 switch (CompareRegionOfInterest(Range)) {
603 case RangeBefore:
604 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000605 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000606
607 case RangeAfter:
608 // This declaration comes after the region of interest; we're done.
609 return false;
610
611 case RangeOverlap:
612 // This declaration overlaps the region of interest; visit it.
613 break;
614 }
615 }
616 return true;
617}
618
619bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
620 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
621
622 // FIXME: Eventually remove. This part of a hack to support proper
623 // iteration over all Decls contained lexically within an ObjC container.
Michael Kruse7520cf02020-03-25 09:26:14 -0500624 SaveAndRestore<DeclContext::decl_iterator *> DI_saved(DI_current, &I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000625 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
626
Michael Kruse7520cf02020-03-25 09:26:14 -0500627 for (; I != E; ++I) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000628 Decl *D = *I;
629 if (D->getLexicalDeclContext() != DC)
630 continue;
Adrian Prantl2073dd22019-11-04 14:28:14 -0800631 // Filter out synthesized property accessor redeclarations.
632 if (isa<ObjCImplDecl>(DC))
633 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
634 if (OMD->isSynthesizedAccessorStub())
635 continue;
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000636 const Optional<bool> V = handleDeclForVisitation(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000637 if (!V.hasValue())
638 continue;
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000639 return V.getValue();
Guy Benyei11169dd2012-12-18 14:30:41 +0000640 }
641 return false;
642}
643
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000644Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
645 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
646
647 // Ignore synthesized ivars here, otherwise if we have something like:
648 // @synthesize prop = _prop;
649 // and '_prop' is not declared, we will encounter a '_prop' ivar before
650 // encountering the 'prop' synthesize declaration and we will think that
651 // we passed the region-of-interest.
652 if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
653 if (ivarD->getSynthesize())
654 return None;
655 }
656
657 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
658 // declarations is a mismatch with the compiler semantics.
659 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
660 auto *ID = cast<ObjCInterfaceDecl>(D);
661 if (!ID->isThisDeclarationADefinition())
662 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
663
664 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
665 auto *PD = cast<ObjCProtocolDecl>(D);
666 if (!PD->isThisDeclarationADefinition())
667 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
668 }
669
670 const Optional<bool> V = shouldVisitCursor(Cursor);
671 if (!V.hasValue())
672 return None;
673 if (!V.getValue())
674 return false;
675 if (Visit(Cursor, true))
676 return true;
677 return None;
678}
679
Guy Benyei11169dd2012-12-18 14:30:41 +0000680bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
681 llvm_unreachable("Translation units are visited directly by Visit()");
682}
683
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000684bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500685 if (VisitTemplateParameters(D->getTemplateParameters()))
686 return true;
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000687
Michael Kruse7520cf02020-03-25 09:26:14 -0500688 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000689}
690
Guy Benyei11169dd2012-12-18 14:30:41 +0000691bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
692 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
693 return Visit(TSInfo->getTypeLoc());
694
695 return false;
696}
697
698bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
699 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
700 return Visit(TSInfo->getTypeLoc());
701
702 return false;
703}
704
Michael Kruse7520cf02020-03-25 09:26:14 -0500705bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }
Guy Benyei11169dd2012-12-18 14:30:41 +0000706
707bool CursorVisitor::VisitClassTemplateSpecializationDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -0500708 ClassTemplateSpecializationDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000709 bool ShouldVisitBody = false;
710 switch (D->getSpecializationKind()) {
711 case TSK_Undeclared:
712 case TSK_ImplicitInstantiation:
713 // Nothing to visit
714 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -0500715
Guy Benyei11169dd2012-12-18 14:30:41 +0000716 case TSK_ExplicitInstantiationDeclaration:
717 case TSK_ExplicitInstantiationDefinition:
718 break;
Michael Kruse7520cf02020-03-25 09:26:14 -0500719
Guy Benyei11169dd2012-12-18 14:30:41 +0000720 case TSK_ExplicitSpecialization:
721 ShouldVisitBody = true;
722 break;
723 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500724
Guy Benyei11169dd2012-12-18 14:30:41 +0000725 // Visit the template arguments used in the specialization.
726 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
727 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000728 if (TemplateSpecializationTypeLoc TSTLoc =
729 TL.getAs<TemplateSpecializationTypeLoc>()) {
730 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
731 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000732 return true;
733 }
734 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000735
736 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000737}
738
739bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -0500740 ClassTemplatePartialSpecializationDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000741 // FIXME: Visit the "outer" template parameter lists on the TagDecl
742 // before visiting these template parameters.
743 if (VisitTemplateParameters(D->getTemplateParameters()))
744 return true;
745
746 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000747 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
748 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
749 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000750 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
751 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 return VisitCXXRecordDecl(D);
754}
755
756bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Saar Razff1e0fc2020-01-15 02:48:42 +0200757 if (const auto *TC = D->getTypeConstraint())
758 if (Visit(MakeCXCursor(TC->getImmediatelyDeclaredConstraint(), StmtParent,
759 TU, RegionOfInterest)))
760 return true;
761
Guy Benyei11169dd2012-12-18 14:30:41 +0000762 // Visit the default argument.
763 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
764 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
765 if (Visit(DefArg->getTypeLoc()))
766 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500767
Guy Benyei11169dd2012-12-18 14:30:41 +0000768 return false;
769}
770
771bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
772 if (Expr *Init = D->getInitExpr())
773 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
774 return false;
775}
776
777bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000778 unsigned NumParamList = DD->getNumTemplateParameterLists();
779 for (unsigned i = 0; i < NumParamList; i++) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500780 TemplateParameterList *Params = DD->getTemplateParameterList(i);
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000781 if (VisitTemplateParameters(Params))
782 return true;
783 }
784
Guy Benyei11169dd2012-12-18 14:30:41 +0000785 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
786 if (Visit(TSInfo->getTypeLoc()))
787 return true;
788
789 // Visit the nested-name-specifier, if present.
790 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
791 if (VisitNestedNameSpecifierLoc(QualifierLoc))
792 return true;
793
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000794 return false;
795}
796
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000797static bool HasTrailingReturnType(FunctionDecl *ND) {
798 const QualType Ty = ND->getType();
799 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
800 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
801 return FT->hasTrailingReturn();
802 }
803
804 return false;
805}
806
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000807/// Compare two base or member initializers based on their source order.
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000808static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
809 CXXCtorInitializer *const *Y) {
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000810 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
811}
812
Guy Benyei11169dd2012-12-18 14:30:41 +0000813bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000814 unsigned NumParamList = ND->getNumTemplateParameterLists();
815 for (unsigned i = 0; i < NumParamList; i++) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500816 TemplateParameterList *Params = ND->getTemplateParameterList(i);
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000817 if (VisitTemplateParameters(Params))
818 return true;
819 }
820
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
822 // Visit the function declaration's syntactic components in the order
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000823 // written. This requires a bit of work.
824 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
825 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000826 const bool HasTrailingRT = HasTrailingReturnType(ND);
Michael Kruse7520cf02020-03-25 09:26:14 -0500827
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000828 // If we have a function declared directly (without the use of a typedef),
829 // visit just the return type. Otherwise, just visit the function's type
830 // now.
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000831 if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
832 Visit(FTL.getReturnLoc())) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000833 (!FTL && Visit(TL)))
834 return true;
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000835
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000836 // Visit the nested-name-specifier, if present.
837 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
838 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +0000839 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500840
Guy Benyei11169dd2012-12-18 14:30:41 +0000841 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000842 if (!isa<CXXDestructorDecl>(ND))
843 if (VisitDeclarationNameInfo(ND->getNameInfo()))
844 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500845
Guy Benyei11169dd2012-12-18 14:30:41 +0000846 // FIXME: Visit explicitly-specified template arguments!
Michael Kruse7520cf02020-03-25 09:26:14 -0500847
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000848 // Visit the function parameters, if we have a function type.
849 if (FTL && VisitFunctionTypeLoc(FTL, true))
850 return true;
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000851
852 // Visit the function's trailing return type.
853 if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
854 return true;
855
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000856 // FIXME: Attributes?
857 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500858
Guy Benyei11169dd2012-12-18 14:30:41 +0000859 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
860 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
861 // Find the initializers that were written in the source.
862 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000863 for (auto *I : Constructor->inits()) {
864 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000865 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -0500866
Aaron Ballman0ad78302014-03-13 17:34:31 +0000867 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000868 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500869
Guy Benyei11169dd2012-12-18 14:30:41 +0000870 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000871 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
872 &CompareCXXCtorInitializers);
Michael Kruse7520cf02020-03-25 09:26:14 -0500873
Guy Benyei11169dd2012-12-18 14:30:41 +0000874 // Visit the initializers in source order
875 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
876 CXXCtorInitializer *Init = WrittenInits[I];
877 if (Init->isAnyMemberInitializer()) {
878 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
879 Init->getMemberLocation(), TU)))
880 return true;
881 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
882 if (Visit(TInfo->getTypeLoc()))
883 return true;
884 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500885
Guy Benyei11169dd2012-12-18 14:30:41 +0000886 // Visit the initializer value.
887 if (Expr *Initializer = Init->getInit())
888 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
889 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500890 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000891 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500892
Guy Benyei11169dd2012-12-18 14:30:41 +0000893 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
894 return true;
895 }
896
897 return false;
898}
899
900bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
901 if (VisitDeclaratorDecl(D))
902 return true;
903
904 if (Expr *BitWidth = D->getBitWidth())
905 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
906
Benjamin Kramer99f97592017-11-15 12:20:41 +0000907 if (Expr *Init = D->getInClassInitializer())
908 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
909
Guy Benyei11169dd2012-12-18 14:30:41 +0000910 return false;
911}
912
913bool CursorVisitor::VisitVarDecl(VarDecl *D) {
914 if (VisitDeclaratorDecl(D))
915 return true;
916
917 if (Expr *Init = D->getInit())
918 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
919
920 return false;
921}
922
923bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
924 if (VisitDeclaratorDecl(D))
925 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500926
Guy Benyei11169dd2012-12-18 14:30:41 +0000927 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
928 if (Expr *DefArg = D->getDefaultArgument())
929 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
Michael Kruse7520cf02020-03-25 09:26:14 -0500930
931 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000932}
933
934bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
935 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
936 // before visiting these template parameters.
937 if (VisitTemplateParameters(D->getTemplateParameters()))
938 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500939
940 auto *FD = D->getTemplatedDecl();
Jonathan Coe578ac7a2017-10-16 23:43:02 +0000941 return VisitAttributes(FD) || VisitFunctionDecl(FD);
Guy Benyei11169dd2012-12-18 14:30:41 +0000942}
943
944bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
945 // FIXME: Visit the "outer" template parameter lists on the TagDecl
946 // before visiting these template parameters.
947 if (VisitTemplateParameters(D->getTemplateParameters()))
948 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500949
950 auto *CD = D->getTemplatedDecl();
Jonathan Coe578ac7a2017-10-16 23:43:02 +0000951 return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
Guy Benyei11169dd2012-12-18 14:30:41 +0000952}
953
954bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
955 if (VisitTemplateParameters(D->getTemplateParameters()))
956 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500957
Guy Benyei11169dd2012-12-18 14:30:41 +0000958 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
959 VisitTemplateArgumentLoc(D->getDefaultArgument()))
960 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500961
Guy Benyei11169dd2012-12-18 14:30:41 +0000962 return false;
963}
964
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000965bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
966 // Visit the bound, if it's explicit.
967 if (D->hasExplicitBound()) {
968 if (auto TInfo = D->getTypeSourceInfo()) {
969 if (Visit(TInfo->getTypeLoc()))
970 return true;
971 }
972 }
973
974 return false;
975}
976
Guy Benyei11169dd2012-12-18 14:30:41 +0000977bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000978 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000979 if (Visit(TSInfo->getTypeLoc()))
980 return true;
981
David Majnemer59f77922016-06-24 04:05:48 +0000982 for (const auto *P : ND->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +0000983 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000984 return true;
985 }
986
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000987 return ND->isThisDeclarationADefinition() &&
988 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000989}
990
991template <typename DeclIt>
992static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
993 SourceManager &SM, SourceLocation EndLoc,
994 SmallVectorImpl<Decl *> &Decls) {
995 DeclIt next = *DI_current;
996 while (++next != DE_current) {
997 Decl *D_next = *next;
998 if (!D_next)
999 break;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001000 SourceLocation L = D_next->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00001001 if (!L.isValid())
1002 break;
1003 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
1004 *DI_current = next;
1005 Decls.push_back(D_next);
1006 continue;
1007 }
1008 break;
1009 }
1010}
1011
Guy Benyei11169dd2012-12-18 14:30:41 +00001012bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
1013 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
1014 // an @implementation can lexically contain Decls that are not properly
1015 // nested in the AST. When we identify such cases, we need to retrofit
1016 // this nesting here.
1017 if (!DI_current && !FileDI_current)
1018 return VisitDeclContext(D);
1019
1020 // Scan the Decls that immediately come after the container
1021 // in the current DeclContext. If any fall within the
1022 // container's lexical region, stash them into a vector
1023 // for later processing.
1024 SmallVector<Decl *, 24> DeclsInContainer;
1025 SourceLocation EndLoc = D->getSourceRange().getEnd();
1026 SourceManager &SM = AU->getSourceManager();
1027 if (EndLoc.isValid()) {
1028 if (DI_current) {
1029 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
1030 DeclsInContainer);
1031 } else {
1032 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
1033 DeclsInContainer);
1034 }
1035 }
1036
1037 // The common case.
1038 if (DeclsInContainer.empty())
1039 return VisitDeclContext(D);
1040
1041 // Get all the Decls in the DeclContext, and sort them with the
1042 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001043 for (auto *SubDecl : D->decls()) {
1044 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001045 SubDecl->getBeginLoc().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001046 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001047 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001048 }
1049
1050 // Now sort the Decls so that they appear in lexical order.
Michael Kruse7520cf02020-03-25 09:26:14 -05001051 llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {
1052 SourceLocation L_A = A->getBeginLoc();
1053 SourceLocation L_B = B->getBeginLoc();
1054 return L_A != L_B
1055 ? SM.isBeforeInTranslationUnit(L_A, L_B)
1056 : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());
1057 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001058
1059 // Now visit the decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05001060 for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),
1061 E = DeclsInContainer.end();
1062 I != E; ++I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001063 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001064 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001065 if (!V.hasValue())
1066 continue;
1067 if (!V.getValue())
1068 return false;
1069 if (Visit(Cursor, true))
1070 return true;
1071 }
1072 return false;
1073}
1074
1075bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1076 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1077 TU)))
1078 return true;
1079
Douglas Gregore9d95f12015-07-07 03:57:35 +00001080 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1081 return true;
1082
Guy Benyei11169dd2012-12-18 14:30:41 +00001083 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1084 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001085 E = ND->protocol_end();
1086 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001087 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1088 return true;
1089
1090 return VisitObjCContainerDecl(ND);
1091}
1092
1093bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1094 if (!PID->isThisDeclarationADefinition())
1095 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001096
Guy Benyei11169dd2012-12-18 14:30:41 +00001097 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1098 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001099 E = PID->protocol_end();
1100 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001101 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1102 return true;
1103
1104 return VisitObjCContainerDecl(PID);
1105}
1106
1107bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1108 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1109 return true;
1110
1111 // FIXME: This implements a workaround with @property declarations also being
1112 // installed in the DeclContext for the @interface. Eventually this code
1113 // should be removed.
1114 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1115 if (!CDecl || !CDecl->IsClassExtension())
1116 return false;
1117
1118 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1119 if (!ID)
1120 return false;
1121
1122 IdentifierInfo *PropertyId = PD->getIdentifier();
Michael Kruse7520cf02020-03-25 09:26:14 -05001123 ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
1124 cast<DeclContext>(ID), PropertyId, PD->getQueryKind());
Guy Benyei11169dd2012-12-18 14:30:41 +00001125
1126 if (!prevDecl)
1127 return false;
1128
1129 // Visit synthesized methods since they will be skipped when visiting
1130 // the @interface.
1131 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1132 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1133 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1134 return true;
1135
1136 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1137 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1138 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1139 return true;
1140
1141 return false;
1142}
1143
Douglas Gregore9d95f12015-07-07 03:57:35 +00001144bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1145 if (!typeParamList)
1146 return false;
1147
1148 for (auto *typeParam : *typeParamList) {
1149 // Visit the type parameter.
1150 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1151 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001152 }
1153
1154 return false;
1155}
1156
Guy Benyei11169dd2012-12-18 14:30:41 +00001157bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1158 if (!D->isThisDeclarationADefinition()) {
1159 // Forward declaration is treated like a reference.
1160 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1161 }
1162
Douglas Gregore9d95f12015-07-07 03:57:35 +00001163 // Objective-C type parameters.
1164 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1165 return true;
1166
Guy Benyei11169dd2012-12-18 14:30:41 +00001167 // Issue callbacks for super class.
Michael Kruse7520cf02020-03-25 09:26:14 -05001168 if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
1169 D->getSuperClass(), D->getSuperClassLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001170 return true;
1171
Douglas Gregore9d95f12015-07-07 03:57:35 +00001172 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1173 if (Visit(SuperClassTInfo->getTypeLoc()))
1174 return true;
1175
Guy Benyei11169dd2012-12-18 14:30:41 +00001176 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1177 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001178 E = D->protocol_end();
1179 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001180 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1181 return true;
1182
1183 return VisitObjCContainerDecl(D);
1184}
1185
1186bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1187 return VisitObjCContainerDecl(D);
1188}
1189
1190bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1191 // 'ID' could be null when dealing with invalid code.
1192 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1193 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1194 return true;
1195
1196 return VisitObjCImplDecl(D);
1197}
1198
1199bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1200#if 0
1201 // Issue callbacks for super class.
1202 // FIXME: No source location information!
1203 if (D->getSuperClass() &&
1204 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1205 D->getSuperClassLoc(),
1206 TU)))
1207 return true;
1208#endif
1209
1210 return VisitObjCImplDecl(D);
1211}
1212
1213bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1214 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1215 if (PD->isIvarNameSpecified())
1216 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001217
Guy Benyei11169dd2012-12-18 14:30:41 +00001218 return false;
1219}
1220
1221bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1222 return VisitDeclContext(D);
1223}
1224
1225bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1226 // Visit nested-name-specifier.
1227 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1228 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1229 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001230
1231 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001232 D->getTargetNameLoc(), TU));
1233}
1234
1235bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1236 // Visit nested-name-specifier.
1237 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1238 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1239 return true;
1240 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001241
Guy Benyei11169dd2012-12-18 14:30:41 +00001242 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1243 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001244
Guy Benyei11169dd2012-12-18 14:30:41 +00001245 return VisitDeclarationNameInfo(D->getNameInfo());
1246}
1247
1248bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1249 // Visit nested-name-specifier.
1250 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1251 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1252 return true;
1253
1254 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1255 D->getIdentLocation(), TU));
1256}
1257
1258bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1259 // Visit nested-name-specifier.
1260 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1261 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1262 return true;
1263 }
1264
1265 return VisitDeclarationNameInfo(D->getNameInfo());
1266}
1267
1268bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -05001269 UnresolvedUsingTypenameDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001270 // Visit nested-name-specifier.
1271 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1272 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1273 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001274
Guy Benyei11169dd2012-12-18 14:30:41 +00001275 return false;
1276}
1277
Olivier Goffart81978012016-06-09 16:15:55 +00001278bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
1279 if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
1280 return true;
Richard Trieuf3b77662016-09-13 01:37:01 +00001281 if (StringLiteral *Message = D->getMessage())
1282 if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
1283 return true;
Olivier Goffart81978012016-06-09 16:15:55 +00001284 return false;
1285}
1286
Olivier Goffartd211c642016-11-04 06:29:27 +00001287bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {
1288 if (NamedDecl *FriendD = D->getFriendDecl()) {
1289 if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))
1290 return true;
1291 } else if (TypeSourceInfo *TI = D->getFriendType()) {
1292 if (Visit(TI->getTypeLoc()))
1293 return true;
1294 }
1295 return false;
1296}
1297
Milian Wolff4597e3b2020-05-02 22:17:59 +02001298bool CursorVisitor::VisitDecompositionDecl(DecompositionDecl *D) {
1299 for (auto *B : D->bindings()) {
1300 if (Visit(MakeCXCursor(B, TU, RegionOfInterest)))
1301 return true;
1302 }
1303 return VisitVarDecl(D);
1304}
1305
Guy Benyei11169dd2012-12-18 14:30:41 +00001306bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1307 switch (Name.getName().getNameKind()) {
1308 case clang::DeclarationName::Identifier:
1309 case clang::DeclarationName::CXXLiteralOperatorName:
Richard Smith35845152017-02-07 01:37:30 +00001310 case clang::DeclarationName::CXXDeductionGuideName:
Guy Benyei11169dd2012-12-18 14:30:41 +00001311 case clang::DeclarationName::CXXOperatorName:
1312 case clang::DeclarationName::CXXUsingDirective:
1313 return false;
Richard Smith35845152017-02-07 01:37:30 +00001314
Guy Benyei11169dd2012-12-18 14:30:41 +00001315 case clang::DeclarationName::CXXConstructorName:
1316 case clang::DeclarationName::CXXDestructorName:
1317 case clang::DeclarationName::CXXConversionFunctionName:
1318 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1319 return Visit(TSInfo->getTypeLoc());
1320 return false;
1321
1322 case clang::DeclarationName::ObjCZeroArgSelector:
1323 case clang::DeclarationName::ObjCOneArgSelector:
1324 case clang::DeclarationName::ObjCMultiArgSelector:
1325 // FIXME: Per-identifier location info?
1326 return false;
1327 }
1328
1329 llvm_unreachable("Invalid DeclarationName::Kind!");
1330}
1331
Michael Kruse7520cf02020-03-25 09:26:14 -05001332bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
Guy Benyei11169dd2012-12-18 14:30:41 +00001333 SourceRange Range) {
1334 // FIXME: This whole routine is a hack to work around the lack of proper
1335 // source information in nested-name-specifiers (PR5791). Since we do have
1336 // a beginning source location, we can visit the first component of the
1337 // nested-name-specifier, if it's a single-token component.
1338 if (!NNS)
1339 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001340
Guy Benyei11169dd2012-12-18 14:30:41 +00001341 // Get the first component in the nested-name-specifier.
1342 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1343 NNS = Prefix;
Michael Kruse7520cf02020-03-25 09:26:14 -05001344
Guy Benyei11169dd2012-12-18 14:30:41 +00001345 switch (NNS->getKind()) {
1346 case NestedNameSpecifier::Namespace:
Michael Kruse7520cf02020-03-25 09:26:14 -05001347 return Visit(
1348 MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001349
1350 case NestedNameSpecifier::NamespaceAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05001351 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001352 Range.getBegin(), TU));
1353
1354 case NestedNameSpecifier::TypeSpec: {
1355 // If the type has a form where we know that the beginning of the source
1356 // range matches up with a reference cursor. Visit the appropriate reference
1357 // cursor.
1358 const Type *T = NNS->getAsType();
1359 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1360 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1361 if (const TagType *Tag = dyn_cast<TagType>(T))
1362 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001363 if (const TemplateSpecializationType *TST =
1364 dyn_cast<TemplateSpecializationType>(T))
Guy Benyei11169dd2012-12-18 14:30:41 +00001365 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1366 break;
1367 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001368
Guy Benyei11169dd2012-12-18 14:30:41 +00001369 case NestedNameSpecifier::TypeSpecWithTemplate:
1370 case NestedNameSpecifier::Global:
1371 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001372 case NestedNameSpecifier::Super:
Michael Kruse7520cf02020-03-25 09:26:14 -05001373 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001374 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001375
Guy Benyei11169dd2012-12-18 14:30:41 +00001376 return false;
1377}
1378
Michael Kruse7520cf02020-03-25 09:26:14 -05001379bool CursorVisitor::VisitNestedNameSpecifierLoc(
1380 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001381 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1382 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1383 Qualifiers.push_back(Qualifier);
Michael Kruse7520cf02020-03-25 09:26:14 -05001384
Guy Benyei11169dd2012-12-18 14:30:41 +00001385 while (!Qualifiers.empty()) {
1386 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1387 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1388 switch (NNS->getKind()) {
1389 case NestedNameSpecifier::Namespace:
Michael Kruse7520cf02020-03-25 09:26:14 -05001390 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1391 Q.getLocalBeginLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001392 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001393
Guy Benyei11169dd2012-12-18 14:30:41 +00001394 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001395
Guy Benyei11169dd2012-12-18 14:30:41 +00001396 case NestedNameSpecifier::NamespaceAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05001397 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1398 Q.getLocalBeginLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001399 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001400
Guy Benyei11169dd2012-12-18 14:30:41 +00001401 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001402
Guy Benyei11169dd2012-12-18 14:30:41 +00001403 case NestedNameSpecifier::TypeSpec:
1404 case NestedNameSpecifier::TypeSpecWithTemplate:
1405 if (Visit(Q.getTypeLoc()))
1406 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001407
Guy Benyei11169dd2012-12-18 14:30:41 +00001408 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001409
Guy Benyei11169dd2012-12-18 14:30:41 +00001410 case NestedNameSpecifier::Global:
1411 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001412 case NestedNameSpecifier::Super:
Michael Kruse7520cf02020-03-25 09:26:14 -05001413 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001414 }
1415 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001416
Guy Benyei11169dd2012-12-18 14:30:41 +00001417 return false;
1418}
1419
1420bool CursorVisitor::VisitTemplateParameters(
Michael Kruse7520cf02020-03-25 09:26:14 -05001421 const TemplateParameterList *Params) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001422 if (!Params)
1423 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001424
Guy Benyei11169dd2012-12-18 14:30:41 +00001425 for (TemplateParameterList::const_iterator P = Params->begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001426 PEnd = Params->end();
Guy Benyei11169dd2012-12-18 14:30:41 +00001427 P != PEnd; ++P) {
1428 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1429 return true;
1430 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001431
Guy Benyei11169dd2012-12-18 14:30:41 +00001432 return false;
1433}
1434
1435bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1436 switch (Name.getKind()) {
1437 case TemplateName::Template:
1438 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1439
1440 case TemplateName::OverloadedTemplate:
1441 // Visit the overloaded template set.
1442 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1443 return true;
1444
1445 return false;
1446
Richard Smithb23c5e82019-05-09 03:31:27 +00001447 case TemplateName::AssumedTemplate:
1448 // FIXME: Visit DeclarationName?
1449 return false;
1450
Guy Benyei11169dd2012-12-18 14:30:41 +00001451 case TemplateName::DependentTemplate:
1452 // FIXME: Visit nested-name-specifier.
1453 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001454
Guy Benyei11169dd2012-12-18 14:30:41 +00001455 case TemplateName::QualifiedTemplate:
1456 // FIXME: Visit nested-name-specifier.
1457 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001458 Name.getAsQualifiedTemplateName()->getDecl(), Loc, TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001459
1460 case TemplateName::SubstTemplateTemplateParm:
1461 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001462 Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));
1463
Guy Benyei11169dd2012-12-18 14:30:41 +00001464 case TemplateName::SubstTemplateTemplateParmPack:
1465 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001466 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
1467 TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001468 }
1469
1470 llvm_unreachable("Invalid TemplateName::Kind!");
1471}
1472
1473bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1474 switch (TAL.getArgument().getKind()) {
1475 case TemplateArgument::Null:
1476 case TemplateArgument::Integral:
1477 case TemplateArgument::Pack:
1478 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001479
Guy Benyei11169dd2012-12-18 14:30:41 +00001480 case TemplateArgument::Type:
1481 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1482 return Visit(TSInfo->getTypeLoc());
1483 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001484
Guy Benyei11169dd2012-12-18 14:30:41 +00001485 case TemplateArgument::Declaration:
1486 if (Expr *E = TAL.getSourceDeclExpression())
1487 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1488 return false;
1489
1490 case TemplateArgument::NullPtr:
1491 if (Expr *E = TAL.getSourceNullPtrExpression())
1492 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1493 return false;
1494
1495 case TemplateArgument::Expression:
1496 if (Expr *E = TAL.getSourceExpression())
1497 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1498 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001499
Guy Benyei11169dd2012-12-18 14:30:41 +00001500 case TemplateArgument::Template:
1501 case TemplateArgument::TemplateExpansion:
1502 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1503 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001504
1505 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001506 TAL.getTemplateNameLoc());
1507 }
1508
1509 llvm_unreachable("Invalid TemplateArgument::Kind!");
1510}
1511
1512bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1513 return VisitDeclContext(D);
1514}
1515
1516bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1517 return Visit(TL.getUnqualifiedLoc());
1518}
1519
1520bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1521 ASTContext &Context = AU->getASTContext();
1522
1523 // Some builtin types (such as Objective-C's "id", "sel", and
1524 // "Class") have associated declarations. Create cursors for those.
1525 QualType VisitType;
1526 switch (TL.getTypePtr()->getKind()) {
1527
1528 case BuiltinType::Void:
1529 case BuiltinType::NullPtr:
1530 case BuiltinType::Dependent:
Michael Kruse7520cf02020-03-25 09:26:14 -05001531#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
Alexey Bader954ba212016-04-08 13:40:33 +00001532 case BuiltinType::Id:
Alexey Baderb62f1442016-04-13 08:33:41 +00001533#include "clang/Basic/OpenCLImageTypes.def"
Michael Kruse7520cf02020-03-25 09:26:14 -05001534#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
Andrew Savonichev3fee3512018-11-08 11:25:41 +00001535#include "clang/Basic/OpenCLExtensionTypes.def"
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001536 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001537 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001538 case BuiltinType::OCLClkEvent:
1539 case BuiltinType::OCLQueue:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001540 case BuiltinType::OCLReserveID:
Michael Kruse7520cf02020-03-25 09:26:14 -05001541#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
Richard Sandifordeb485fb2019-08-09 08:52:54 +00001542#include "clang/Basic/AArch64SVEACLETypes.def"
Guy Benyei11169dd2012-12-18 14:30:41 +00001543#define BUILTIN_TYPE(Id, SingletonId)
1544#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1545#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1546#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1547#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1548#include "clang/AST/BuiltinTypes.def"
1549 break;
1550
1551 case BuiltinType::ObjCId:
1552 VisitType = Context.getObjCIdType();
1553 break;
1554
1555 case BuiltinType::ObjCClass:
1556 VisitType = Context.getObjCClassType();
1557 break;
1558
1559 case BuiltinType::ObjCSel:
1560 VisitType = Context.getObjCSelType();
1561 break;
1562 }
1563
1564 if (!VisitType.isNull()) {
1565 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Michael Kruse7520cf02020-03-25 09:26:14 -05001566 return Visit(
1567 MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001568 }
1569
1570 return false;
1571}
1572
1573bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1574 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1575}
1576
1577bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1578 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1579}
1580
1581bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1582 if (TL.isDefinition())
1583 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1584
1585 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1586}
1587
1588bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1589 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1590}
1591
1592bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001593 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001594}
1595
Manman Rene6be26c2016-09-13 17:25:08 +00001596bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001597 if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
Manman Rene6be26c2016-09-13 17:25:08 +00001598 return true;
1599 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1600 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1601 TU)))
1602 return true;
1603 }
1604
1605 return false;
1606}
1607
Guy Benyei11169dd2012-12-18 14:30:41 +00001608bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1609 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1610 return true;
1611
Douglas Gregore9d95f12015-07-07 03:57:35 +00001612 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1613 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1614 return true;
1615 }
1616
Guy Benyei11169dd2012-12-18 14:30:41 +00001617 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1618 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1619 TU)))
1620 return true;
1621 }
1622
1623 return false;
1624}
1625
1626bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1627 return Visit(TL.getPointeeLoc());
1628}
1629
1630bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1631 return Visit(TL.getInnerLoc());
1632}
1633
Leonard Chanc72aaf62019-05-07 03:20:17 +00001634bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
1635 return Visit(TL.getInnerLoc());
1636}
1637
Guy Benyei11169dd2012-12-18 14:30:41 +00001638bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1639 return Visit(TL.getPointeeLoc());
1640}
1641
1642bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1643 return Visit(TL.getPointeeLoc());
1644}
1645
1646bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1647 return Visit(TL.getPointeeLoc());
1648}
1649
1650bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1651 return Visit(TL.getPointeeLoc());
1652}
1653
1654bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1655 return Visit(TL.getPointeeLoc());
1656}
1657
1658bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1659 return Visit(TL.getModifiedLoc());
1660}
1661
Michael Kruse7520cf02020-03-25 09:26:14 -05001662bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
Guy Benyei11169dd2012-12-18 14:30:41 +00001663 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001664 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001665 return true;
1666
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001667 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1668 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001669 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1670 return true;
1671
1672 return false;
1673}
1674
1675bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1676 if (Visit(TL.getElementLoc()))
1677 return true;
1678
1679 if (Expr *Size = TL.getSizeExpr())
1680 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1681
1682 return false;
1683}
1684
Reid Kleckner8a365022013-06-24 17:51:48 +00001685bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1686 return Visit(TL.getOriginalLoc());
1687}
1688
Reid Kleckner0503a872013-12-05 01:23:43 +00001689bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1690 return Visit(TL.getOriginalLoc());
1691}
1692
Richard Smith600b5262017-01-26 20:40:47 +00001693bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
1694 DeducedTemplateSpecializationTypeLoc TL) {
Michael Kruse7520cf02020-03-25 09:26:14 -05001695 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Richard Smith600b5262017-01-26 20:40:47 +00001696 TL.getTemplateNameLoc()))
1697 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001698
Richard Smith600b5262017-01-26 20:40:47 +00001699 return false;
1700}
1701
Guy Benyei11169dd2012-12-18 14:30:41 +00001702bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001703 TemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001704 // Visit the template name.
Michael Kruse7520cf02020-03-25 09:26:14 -05001705 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001706 TL.getTemplateNameLoc()))
1707 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001708
Guy Benyei11169dd2012-12-18 14:30:41 +00001709 // Visit the template arguments.
1710 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1711 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1712 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001713
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 return false;
1715}
1716
1717bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1718 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1719}
1720
1721bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1722 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1723 return Visit(TSInfo->getTypeLoc());
1724
1725 return false;
1726}
1727
1728bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1729 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1730 return Visit(TSInfo->getTypeLoc());
1731
1732 return false;
1733}
1734
1735bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001736 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001737}
1738
1739bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001740 DependentTemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001741 // Visit the nested-name-specifier, if there is one.
Michael Kruse7520cf02020-03-25 09:26:14 -05001742 if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001743 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001744
Guy Benyei11169dd2012-12-18 14:30:41 +00001745 // Visit the template arguments.
1746 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1747 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1748 return true;
1749
1750 return false;
1751}
1752
1753bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1754 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1755 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001756
Guy Benyei11169dd2012-12-18 14:30:41 +00001757 return Visit(TL.getNamedTypeLoc());
1758}
1759
1760bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1761 return Visit(TL.getPatternLoc());
1762}
1763
1764bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1765 if (Expr *E = TL.getUnderlyingExpr())
1766 return Visit(MakeCXCursor(E, StmtParent, TU));
1767
1768 return false;
1769}
1770
1771bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1772 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1773}
1774
1775bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1776 return Visit(TL.getValueLoc());
1777}
1778
Xiuli Pan9c14e282016-01-09 12:53:17 +00001779bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1780 return Visit(TL.getValueLoc());
1781}
1782
Michael Kruse7520cf02020-03-25 09:26:14 -05001783#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1784 bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1785 return Visit##PARENT##Loc(TL); \
1786 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001787
1788DEFAULT_TYPELOC_IMPL(Complex, Type)
1789DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1790DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1791DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1792DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
Andrew Gozillon572bbb02017-10-02 06:25:51 +00001793DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
Erich Keanef702b022018-07-13 19:46:04 +00001794DEFAULT_TYPELOC_IMPL(DependentVector, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001795DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1796DEFAULT_TYPELOC_IMPL(Vector, Type)
1797DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
Florian Hahn10658692020-05-11 17:45:51 +01001798DEFAULT_TYPELOC_IMPL(ConstantMatrix, MatrixType)
1799DEFAULT_TYPELOC_IMPL(DependentSizedMatrix, MatrixType)
Guy Benyei11169dd2012-12-18 14:30:41 +00001800DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1801DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1802DEFAULT_TYPELOC_IMPL(Record, TagType)
1803DEFAULT_TYPELOC_IMPL(Enum, TagType)
1804DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1805DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1806DEFAULT_TYPELOC_IMPL(Auto, Type)
Erich Keane5f0903e2020-04-17 10:44:19 -07001807DEFAULT_TYPELOC_IMPL(ExtInt, Type)
1808DEFAULT_TYPELOC_IMPL(DependentExtInt, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001809
1810bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1811 // Visit the nested-name-specifier, if present.
1812 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1813 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1814 return true;
1815
1816 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001817 for (const auto &I : D->bases()) {
1818 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001819 return true;
1820 }
1821 }
1822
1823 return VisitTagDecl(D);
1824}
1825
1826bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001827 for (const auto *I : D->attrs())
Michael Wu40ff1052018-08-03 05:20:23 +00001828 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1829 !I->isImplicit()) &&
1830 Visit(MakeCXCursor(I, D, TU)))
Michael Kruse7520cf02020-03-25 09:26:14 -05001831 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00001832
1833 return false;
1834}
1835
1836//===----------------------------------------------------------------------===//
1837// Data-recursive visitor methods.
1838//===----------------------------------------------------------------------===//
1839
1840namespace {
Michael Kruse7520cf02020-03-25 09:26:14 -05001841#define DEF_JOB(NAME, DATA, KIND) \
1842 class NAME : public VisitorJob { \
1843 public: \
1844 NAME(const DATA *d, CXCursor parent) \
1845 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1846 static bool classof(const VisitorJob *VJ) { \
1847 return VJ->getKind() == KIND; \
1848 } \
1849 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1850 };
Guy Benyei11169dd2012-12-18 14:30:41 +00001851
1852DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1853DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1854DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1855DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001856DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1857DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1858DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1859#undef DEF_JOB
1860
James Y Knight04ec5bf2015-12-24 02:59:37 +00001861class ExplicitTemplateArgsVisit : public VisitorJob {
1862public:
1863 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1864 const TemplateArgumentLoc *End, CXCursor parent)
1865 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1866 End) {}
1867 static bool classof(const VisitorJob *VJ) {
1868 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1869 }
1870 const TemplateArgumentLoc *begin() const {
1871 return static_cast<const TemplateArgumentLoc *>(data[0]);
1872 }
1873 const TemplateArgumentLoc *end() {
1874 return static_cast<const TemplateArgumentLoc *>(data[1]);
1875 }
1876};
Guy Benyei11169dd2012-12-18 14:30:41 +00001877class DeclVisit : public VisitorJob {
1878public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001879 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1880 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1881 isFirst ? (void *)1 : (void *)nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 static bool classof(const VisitorJob *VJ) {
1883 return VJ->getKind() == DeclVisitKind;
1884 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001886 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001887};
1888class TypeLocVisit : public VisitorJob {
1889public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001890 TypeLocVisit(TypeLoc tl, CXCursor parent)
1891 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1892 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001893
1894 static bool classof(const VisitorJob *VJ) {
1895 return VJ->getKind() == TypeLocVisitKind;
1896 }
1897
Michael Kruse7520cf02020-03-25 09:26:14 -05001898 TypeLoc get() const {
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 }
1902};
1903
1904class LabelRefVisit : public VisitorJob {
1905public:
1906 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001907 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1908 labelLoc.getPtrEncoding()) {}
1909
Guy Benyei11169dd2012-12-18 14:30:41 +00001910 static bool classof(const VisitorJob *VJ) {
1911 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1912 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913 const LabelDecl *get() const {
1914 return static_cast<const LabelDecl *>(data[0]);
1915 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001916 SourceLocation getLoc() const {
1917 return SourceLocation::getFromPtrEncoding(data[1]);
1918 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001919};
Michael Kruse7520cf02020-03-25 09:26:14 -05001920
Guy Benyei11169dd2012-12-18 14:30:41 +00001921class NestedNameSpecifierLocVisit : public VisitorJob {
1922public:
1923 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001924 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1925 Qualifier.getNestedNameSpecifier(),
1926 Qualifier.getOpaqueData()) {}
1927
Guy Benyei11169dd2012-12-18 14:30:41 +00001928 static bool classof(const VisitorJob *VJ) {
1929 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1930 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001931
Guy Benyei11169dd2012-12-18 14:30:41 +00001932 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001933 return NestedNameSpecifierLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001934 const_cast<NestedNameSpecifier *>(
1935 static_cast<const NestedNameSpecifier *>(data[0])),
1936 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 }
1938};
Michael Kruse7520cf02020-03-25 09:26:14 -05001939
Guy Benyei11169dd2012-12-18 14:30:41 +00001940class DeclarationNameInfoVisit : public VisitorJob {
1941public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001942 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001943 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001944 static bool classof(const VisitorJob *VJ) {
1945 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1946 }
1947 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001948 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001949 switch (S->getStmtClass()) {
1950 default:
1951 llvm_unreachable("Unhandled Stmt");
1952 case clang::Stmt::MSDependentExistsStmtClass:
1953 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1954 case Stmt::CXXDependentScopeMemberExprClass:
1955 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1956 case Stmt::DependentScopeDeclRefExprClass:
1957 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001958 case Stmt::OMPCriticalDirectiveClass:
1959 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001960 }
1961 }
1962};
1963class MemberRefVisit : public VisitorJob {
1964public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001966 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1967 L.getPtrEncoding()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001968 static bool classof(const VisitorJob *VJ) {
1969 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1970 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971 const FieldDecl *get() const {
1972 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001973 }
1974 SourceLocation getLoc() const {
Michael Kruse7520cf02020-03-25 09:26:14 -05001975 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 }
1977};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001980 VisitorWorkList &WL;
1981 CXCursor Parent;
Michael Kruse7520cf02020-03-25 09:26:14 -05001982
Guy Benyei11169dd2012-12-18 14:30:41 +00001983public:
1984 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001985 : WL(wl), Parent(parent) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001986
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001987 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1988 void VisitBlockExpr(const BlockExpr *B);
1989 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1990 void VisitCompoundStmt(const CompoundStmt *S);
Michael Kruse7520cf02020-03-25 09:26:14 -05001991 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
1992 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1994 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1995 void VisitCXXNewExpr(const CXXNewExpr *E);
1996 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1997 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1998 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1999 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
2000 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
2001 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
2002 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
2003 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002004 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002005 void VisitDeclRefExpr(const DeclRefExpr *D);
2006 void VisitDeclStmt(const DeclStmt *S);
2007 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
2008 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
2009 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
2010 void VisitForStmt(const ForStmt *FS);
2011 void VisitGotoStmt(const GotoStmt *GS);
2012 void VisitIfStmt(const IfStmt *If);
2013 void VisitInitListExpr(const InitListExpr *IE);
2014 void VisitMemberExpr(const MemberExpr *M);
2015 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2016 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2017 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2018 void VisitOverloadExpr(const OverloadExpr *E);
2019 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2020 void VisitStmt(const Stmt *S);
2021 void VisitSwitchStmt(const SwitchStmt *S);
2022 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002023 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2024 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2025 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2026 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2027 void VisitVAArgExpr(const VAArgExpr *E);
2028 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2029 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2030 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2031 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002032 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00002033 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002034 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002035 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002036 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00002037 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002038 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002039 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002040 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00002041 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002042 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002043 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002044 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
cchen47d60942019-12-05 13:43:48 -05002045 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002046 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002047 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00002048 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002049 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00002050 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002051 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002052 void
2053 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00002054 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00002055 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataevc112e942020-02-28 09:52:15 -05002056 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002057 void VisitOMPScanDirective(const OMPScanDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002058 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00002059 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002060 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00002061 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00002062 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00002063 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002064 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002065 void
2066 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00002067 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00002068 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002069 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Alexey Bataev60e51c42019-10-10 20:13:02 +00002070 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002071 void
2072 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002073 void VisitOMPParallelMasterTaskLoopDirective(
2074 const OMPParallelMasterTaskLoopDirective *D);
Alexey Bataev14a388f2019-10-25 10:27:13 -04002075 void VisitOMPParallelMasterTaskLoopSimdDirective(
2076 const OMPParallelMasterTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002077 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002078 void VisitOMPDistributeParallelForDirective(
2079 const OMPDistributeParallelForDirective *D);
Kelvin Li4a39add2016-07-05 05:00:15 +00002080 void VisitOMPDistributeParallelForSimdDirective(
2081 const OMPDistributeParallelForSimdDirective *D);
Kelvin Li787f3fc2016-07-06 04:45:38 +00002082 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
Kelvin Lia579b912016-07-14 02:54:56 +00002083 void VisitOMPTargetParallelForSimdDirective(
2084 const OMPTargetParallelForSimdDirective *D);
Kelvin Li986330c2016-07-20 22:57:10 +00002085 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
Kelvin Li02532872016-08-05 14:37:37 +00002086 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
Kelvin Li4e325f72016-10-25 12:50:55 +00002087 void VisitOMPTeamsDistributeSimdDirective(
2088 const OMPTeamsDistributeSimdDirective *D);
Kelvin Li579e41c2016-11-30 23:51:03 +00002089 void VisitOMPTeamsDistributeParallelForSimdDirective(
2090 const OMPTeamsDistributeParallelForSimdDirective *D);
Kelvin Li7ade93f2016-12-09 03:24:30 +00002091 void VisitOMPTeamsDistributeParallelForDirective(
2092 const OMPTeamsDistributeParallelForDirective *D);
Kelvin Libf594a52016-12-17 05:48:59 +00002093 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
Kelvin Li83c451e2016-12-25 04:52:54 +00002094 void VisitOMPTargetTeamsDistributeDirective(
2095 const OMPTargetTeamsDistributeDirective *D);
Kelvin Li80e8f562016-12-29 22:16:30 +00002096 void VisitOMPTargetTeamsDistributeParallelForDirective(
2097 const OMPTargetTeamsDistributeParallelForDirective *D);
Kelvin Li1851df52017-01-03 05:23:48 +00002098 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2099 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
Kelvin Lida681182017-01-10 18:08:18 +00002100 void VisitOMPTargetTeamsDistributeSimdDirective(
2101 const OMPTargetTeamsDistributeSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102
Guy Benyei11169dd2012-12-18 14:30:41 +00002103private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00002106 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2107 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2109 void AddStmt(const Stmt *S);
2110 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002113 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002114};
Michael Kruse7520cf02020-03-25 09:26:14 -05002115} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00002116
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002117void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 // 'S' should always be non-null, since it comes from the
2119 // statement we are visiting.
2120 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2121}
2122
Michael Kruse7520cf02020-03-25 09:26:14 -05002123void EnqueueVisitor::AddNestedNameSpecifierLoc(
2124 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 if (Qualifier)
2126 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2127}
2128
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 if (S)
2131 WL.push_back(StmtVisit(S, Parent));
2132}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002133void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002134 if (D)
2135 WL.push_back(DeclVisit(D, Parent, isFirst));
2136}
James Y Knight04ec5bf2015-12-24 02:59:37 +00002137void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2138 unsigned NumTemplateArgs) {
2139 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 if (D)
2143 WL.push_back(MemberRefVisit(D, L, Parent));
2144}
2145void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2146 if (TI)
2147 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002151 for (const Stmt *SubStmt : S->children()) {
2152 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 }
2154 if (size == WL.size())
2155 return;
2156 // Now reverse the entries we just added. This will match the DFS
2157 // ordering performed by the worklist.
2158 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2159 std::reverse(I, E);
2160}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002161namespace {
2162class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2163 EnqueueVisitor *Visitor;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002164 /// Process clauses with list of variables.
Michael Kruse7520cf02020-03-25 09:26:14 -05002165 template <typename T> void VisitOMPClauseList(T *Node);
2166
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002167public:
Michael Kruse7520cf02020-03-25 09:26:14 -05002168 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
Johannes Doerfert419a5592020-03-30 19:58:40 -05002169#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2170#include "llvm/Frontend/OpenMP/OMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002171 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002172 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002173};
2174
Alexey Bataev3392d762016-02-16 11:18:12 +00002175void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2176 const OMPClauseWithPreInit *C) {
2177 Visitor->AddStmt(C->getPreInitStmt());
2178}
2179
Alexey Bataev005248a2016-02-25 05:25:57 +00002180void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2181 const OMPClauseWithPostUpdate *C) {
Alexey Bataev37e594c2016-03-04 07:21:16 +00002182 VisitOMPClauseWithPreInit(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002183 Visitor->AddStmt(C->getPostUpdateExpr());
2184}
2185
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002186void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00002187 VisitOMPClauseWithPreInit(C);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002188 Visitor->AddStmt(C->getCondition());
2189}
2190
Alexey Bataev3778b602014-07-17 07:32:53 +00002191void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2192 Visitor->AddStmt(C->getCondition());
2193}
2194
Alexey Bataev568a8332014-03-06 06:15:19 +00002195void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00002196 VisitOMPClauseWithPreInit(C);
Alexey Bataev568a8332014-03-06 06:15:19 +00002197 Visitor->AddStmt(C->getNumThreads());
2198}
2199
Alexey Bataev62c87d22014-03-21 04:51:18 +00002200void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2201 Visitor->AddStmt(C->getSafelen());
2202}
2203
Alexey Bataev66b15b52015-08-21 11:14:16 +00002204void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2205 Visitor->AddStmt(C->getSimdlen());
2206}
2207
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002208void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2209 Visitor->AddStmt(C->getAllocator());
2210}
2211
Alexander Musman8bd31e62014-05-27 15:12:19 +00002212void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2213 Visitor->AddStmt(C->getNumForLoops());
2214}
2215
Michael Kruse7520cf02020-03-25 09:26:14 -05002216void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
Alexey Bataev756c1962013-09-24 03:17:45 +00002217
Michael Kruse7520cf02020-03-25 09:26:14 -05002218void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002219
Alexey Bataev56dafe82014-06-20 07:16:17 +00002220void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002221 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002222 Visitor->AddStmt(C->getChunkSize());
2223}
2224
Alexey Bataev10e775f2015-07-30 11:36:16 +00002225void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2226 Visitor->AddStmt(C->getNumForLoops());
2227}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002228
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002229void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2230 Visitor->AddStmt(C->getEventHandler());
2231}
2232
Alexey Bataev236070f2014-06-20 11:19:47 +00002233void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2234
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002235void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2236
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002237void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2238
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002239void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2240
Alexey Bataevdea47612014-07-23 07:46:59 +00002241void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2242
Alexey Bataev67a4f222014-07-23 10:25:33 +00002243void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2244
Alexey Bataev459dec02014-07-24 06:46:57 +00002245void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2246
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002247void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2248
Alexey Bataevea9166b2020-02-06 16:30:23 -05002249void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2250
Alexey Bataev04a830f2020-02-10 14:30:39 -05002251void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2252
Alexey Bataev95598342020-02-10 15:49:05 -05002253void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2254
Alexey Bataev9a8defc2020-02-11 11:10:43 -05002255void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2256
Alexey Bataev346265e2015-09-25 10:37:12 +00002257void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2258
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002259void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2260
Alexey Bataevb825de12015-12-07 10:51:44 +00002261void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2262
Alexey Bataev375437a2020-03-02 14:21:20 -05002263void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {}
2264
Kelvin Li1408f912018-09-26 04:28:39 +00002265void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2266 const OMPUnifiedAddressClause *) {}
2267
Patrick Lyster4a370b92018-10-01 13:47:43 +00002268void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2269 const OMPUnifiedSharedMemoryClause *) {}
2270
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00002271void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2272 const OMPReverseOffloadClause *) {}
2273
Patrick Lyster3fe9e392018-10-11 14:41:10 +00002274void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2275 const OMPDynamicAllocatorsClause *) {}
2276
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002277void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2278 const OMPAtomicDefaultMemOrderClause *) {}
2279
Michael Wonge710d542015-08-07 16:16:36 +00002280void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2281 Visitor->AddStmt(C->getDevice());
2282}
2283
Kelvin Li099bb8c2015-11-24 20:50:12 +00002284void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00002285 VisitOMPClauseWithPreInit(C);
Kelvin Li099bb8c2015-11-24 20:50:12 +00002286 Visitor->AddStmt(C->getNumTeams());
2287}
2288
Michael Kruse7520cf02020-03-25 09:26:14 -05002289void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2290 const OMPThreadLimitClause *C) {
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00002291 VisitOMPClauseWithPreInit(C);
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002292 Visitor->AddStmt(C->getThreadLimit());
2293}
2294
Alexey Bataeva0569352015-12-01 10:17:31 +00002295void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2296 Visitor->AddStmt(C->getPriority());
2297}
2298
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002299void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2300 Visitor->AddStmt(C->getGrainsize());
2301}
2302
Alexey Bataev382967a2015-12-08 12:06:20 +00002303void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2304 Visitor->AddStmt(C->getNumTasks());
2305}
2306
Alexey Bataev28c75412015-12-15 08:19:24 +00002307void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2308 Visitor->AddStmt(C->getHint());
2309}
2310
Michael Kruse7520cf02020-03-25 09:26:14 -05002311template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002312 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002313 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002314 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002315}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002316
Alexey Bataev06dea732020-03-20 09:41:22 -04002317void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2318 VisitOMPClauseList(C);
2319}
Alexey Bataev63828a32020-03-23 10:41:08 -04002320void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2321 VisitOMPClauseList(C);
2322}
Alexey Bataeve04483e2019-03-27 14:14:31 +00002323void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2324 VisitOMPClauseList(C);
2325 Visitor->AddStmt(C->getAllocator());
2326}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002327void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002328 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002329 for (const auto *E : C->private_copies()) {
2330 Visitor->AddStmt(E);
2331 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002332}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002333void OMPClauseEnqueue::VisitOMPFirstprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002334 const OMPFirstprivateClause *C) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002335 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002336 VisitOMPClauseWithPreInit(C);
2337 for (const auto *E : C->private_copies()) {
2338 Visitor->AddStmt(E);
2339 }
2340 for (const auto *E : C->inits()) {
2341 Visitor->AddStmt(E);
2342 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002343}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002344void OMPClauseEnqueue::VisitOMPLastprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002345 const OMPLastprivateClause *C) {
Alexander Musman1bb328c2014-06-04 13:06:39 +00002346 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002347 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002348 for (auto *E : C->private_copies()) {
2349 Visitor->AddStmt(E);
2350 }
2351 for (auto *E : C->source_exprs()) {
2352 Visitor->AddStmt(E);
2353 }
2354 for (auto *E : C->destination_exprs()) {
2355 Visitor->AddStmt(E);
2356 }
2357 for (auto *E : C->assignment_ops()) {
2358 Visitor->AddStmt(E);
2359 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002360}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002361void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002362 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002363}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002364void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2365 VisitOMPClauseList(C);
Alexey Bataev61205072016-03-02 04:57:40 +00002366 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002367 for (auto *E : C->privates()) {
2368 Visitor->AddStmt(E);
2369 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002370 for (auto *E : C->lhs_exprs()) {
2371 Visitor->AddStmt(E);
2372 }
2373 for (auto *E : C->rhs_exprs()) {
2374 Visitor->AddStmt(E);
2375 }
2376 for (auto *E : C->reduction_ops()) {
2377 Visitor->AddStmt(E);
2378 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002379}
Alexey Bataev169d96a2017-07-18 20:17:46 +00002380void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2381 const OMPTaskReductionClause *C) {
2382 VisitOMPClauseList(C);
2383 VisitOMPClauseWithPostUpdate(C);
2384 for (auto *E : C->privates()) {
2385 Visitor->AddStmt(E);
2386 }
2387 for (auto *E : C->lhs_exprs()) {
2388 Visitor->AddStmt(E);
2389 }
2390 for (auto *E : C->rhs_exprs()) {
2391 Visitor->AddStmt(E);
2392 }
2393 for (auto *E : C->reduction_ops()) {
2394 Visitor->AddStmt(E);
2395 }
2396}
Alexey Bataevfa312f32017-07-21 18:48:21 +00002397void OMPClauseEnqueue::VisitOMPInReductionClause(
2398 const OMPInReductionClause *C) {
2399 VisitOMPClauseList(C);
2400 VisitOMPClauseWithPostUpdate(C);
2401 for (auto *E : C->privates()) {
2402 Visitor->AddStmt(E);
2403 }
2404 for (auto *E : C->lhs_exprs()) {
2405 Visitor->AddStmt(E);
2406 }
2407 for (auto *E : C->rhs_exprs()) {
2408 Visitor->AddStmt(E);
2409 }
2410 for (auto *E : C->reduction_ops()) {
2411 Visitor->AddStmt(E);
2412 }
Alexey Bataev88202be2017-07-27 13:20:36 +00002413 for (auto *E : C->taskgroup_descriptors())
2414 Visitor->AddStmt(E);
Alexey Bataevfa312f32017-07-21 18:48:21 +00002415}
Alexander Musman8dba6642014-04-22 13:09:42 +00002416void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2417 VisitOMPClauseList(C);
Alexey Bataev78849fb2016-03-09 09:49:00 +00002418 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002419 for (const auto *E : C->privates()) {
2420 Visitor->AddStmt(E);
2421 }
Alexander Musman3276a272015-03-21 10:12:56 +00002422 for (const auto *E : C->inits()) {
2423 Visitor->AddStmt(E);
2424 }
2425 for (const auto *E : C->updates()) {
2426 Visitor->AddStmt(E);
2427 }
2428 for (const auto *E : C->finals()) {
2429 Visitor->AddStmt(E);
2430 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002431 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002432 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002433}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002434void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2435 VisitOMPClauseList(C);
2436 Visitor->AddStmt(C->getAlignment());
2437}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002438void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2439 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002440 for (auto *E : C->source_exprs()) {
2441 Visitor->AddStmt(E);
2442 }
2443 for (auto *E : C->destination_exprs()) {
2444 Visitor->AddStmt(E);
2445 }
2446 for (auto *E : C->assignment_ops()) {
2447 Visitor->AddStmt(E);
2448 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002449}
Michael Kruse7520cf02020-03-25 09:26:14 -05002450void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2451 const OMPCopyprivateClause *C) {
Alexey Bataevbae9a792014-06-27 10:37:06 +00002452 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002453 for (auto *E : C->source_exprs()) {
2454 Visitor->AddStmt(E);
2455 }
2456 for (auto *E : C->destination_exprs()) {
2457 Visitor->AddStmt(E);
2458 }
2459 for (auto *E : C->assignment_ops()) {
2460 Visitor->AddStmt(E);
2461 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002462}
Alexey Bataev6125da92014-07-21 11:26:11 +00002463void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2464 VisitOMPClauseList(C);
2465}
Alexey Bataevc112e942020-02-28 09:52:15 -05002466void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2467 Visitor->AddStmt(C->getDepobj());
2468}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002469void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2470 VisitOMPClauseList(C);
2471}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002472void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2473 VisitOMPClauseList(C);
2474}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002475void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2476 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002477 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002478 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002479}
Alexey Bataev3392d762016-02-16 11:18:12 +00002480void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2481 const OMPDefaultmapClause * /*C*/) {}
Samuel Antao661c0902016-05-26 17:39:58 +00002482void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2483 VisitOMPClauseList(C);
2484}
Samuel Antaoec172c62016-05-26 17:49:04 +00002485void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2486 VisitOMPClauseList(C);
2487}
Michael Kruse7520cf02020-03-25 09:26:14 -05002488void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2489 const OMPUseDevicePtrClause *C) {
Carlo Bertolli2404b172016-07-13 15:37:16 +00002490 VisitOMPClauseList(C);
2491}
Michael Kruse7520cf02020-03-25 09:26:14 -05002492void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2493 const OMPIsDevicePtrClause *C) {
Carlo Bertolli70594e92016-07-13 17:16:49 +00002494 VisitOMPClauseList(C);
2495}
Alexey Bataevb6e70842019-12-16 15:54:17 -05002496void OMPClauseEnqueue::VisitOMPNontemporalClause(
2497 const OMPNontemporalClause *C) {
2498 VisitOMPClauseList(C);
Alexey Bataev0860db92019-12-19 10:01:10 -05002499 for (const auto *E : C->private_refs())
2500 Visitor->AddStmt(E);
Alexey Bataevb6e70842019-12-16 15:54:17 -05002501}
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002502void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
Alexey Bataevb5be1c52020-04-21 13:21:00 -04002503void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
2504 const OMPUsesAllocatorsClause *C) {
2505 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
2506 const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);
2507 Visitor->AddStmt(D.Allocator);
2508 Visitor->AddStmt(D.AllocatorTraits);
2509 }
2510}
Michael Kruse7520cf02020-03-25 09:26:14 -05002511} // namespace
Alexey Bataev756c1962013-09-24 03:17:45 +00002512
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002513void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2514 unsigned size = WL.size();
2515 OMPClauseEnqueue Visitor(this);
2516 Visitor.Visit(S);
2517 if (size == WL.size())
2518 return;
2519 // Now reverse the entries we just added. This will match the DFS
2520 // ordering performed by the worklist.
2521 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2522 std::reverse(I, E);
2523}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002524void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002525 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2526}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002527void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002528 AddDecl(B->getBlockDecl());
2529}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002530void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002531 EnqueueChildren(E);
2532 AddTypeLoc(E->getTypeSourceInfo());
2533}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002534void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002535 for (auto &I : llvm::reverse(S->body()))
2536 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002537}
Michael Kruse7520cf02020-03-25 09:26:14 -05002538void EnqueueVisitor::VisitMSDependentExistsStmt(
2539 const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002540 AddStmt(S->getSubStmt());
2541 AddDeclarationNameInfo(S);
2542 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2543 AddNestedNameSpecifierLoc(QualifierLoc);
2544}
2545
Michael Kruse7520cf02020-03-25 09:26:14 -05002546void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2547 const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002548 if (E->hasExplicitTemplateArgs())
2549 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002550 AddDeclarationNameInfo(E);
2551 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2552 AddNestedNameSpecifierLoc(QualifierLoc);
2553 if (!E->isImplicitAccess())
2554 AddStmt(E->getBase());
2555}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002556void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002557 // Enqueue the initializer , if any.
2558 AddStmt(E->getInitializer());
2559 // Enqueue the array size, if any.
Richard Smithb9fb1212019-05-06 03:47:15 +00002560 AddStmt(E->getArraySize().getValueOr(nullptr));
Guy Benyei11169dd2012-12-18 14:30:41 +00002561 // Enqueue the allocated type.
2562 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2563 // Enqueue the placement arguments.
2564 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002565 AddStmt(E->getPlacementArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002566}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002567void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002568 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002569 AddStmt(CE->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002570 AddStmt(CE->getCallee());
2571 AddStmt(CE->getArg(0));
2572}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002573void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002574 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002575 // Visit the name of the type being destroyed.
2576 AddTypeLoc(E->getDestroyedTypeInfo());
2577 // Visit the scope type that looks disturbingly like the nested-name-specifier
2578 // but isn't.
2579 AddTypeLoc(E->getScopeTypeInfo());
2580 // Visit the nested-name-specifier.
2581 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2582 AddNestedNameSpecifierLoc(QualifierLoc);
2583 // Visit base expression.
2584 AddStmt(E->getBase());
2585}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002586void EnqueueVisitor::VisitCXXScalarValueInitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002587 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002588 AddTypeLoc(E->getTypeSourceInfo());
2589}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002590void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002591 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002592 EnqueueChildren(E);
2593 AddTypeLoc(E->getTypeSourceInfo());
2594}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002595void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002596 EnqueueChildren(E);
2597 if (E->isTypeOperand())
2598 AddTypeLoc(E->getTypeOperandSourceInfo());
2599}
2600
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002601void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002602 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002603 EnqueueChildren(E);
2604 AddTypeLoc(E->getTypeSourceInfo());
2605}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002606void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 EnqueueChildren(E);
2608 if (E->isTypeOperand())
2609 AddTypeLoc(E->getTypeOperandSourceInfo());
2610}
2611
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002612void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002613 EnqueueChildren(S);
2614 AddDecl(S->getExceptionDecl());
2615}
2616
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002617void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002618 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002619 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002620 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002621}
2622
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002623void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002624 if (DR->hasExplicitTemplateArgs())
2625 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002626 WL.push_back(DeclRefExprParts(DR, Parent));
2627}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002628void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002629 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002630 if (E->hasExplicitTemplateArgs())
2631 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002632 AddDeclarationNameInfo(E);
2633 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2634}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002635void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002636 unsigned size = WL.size();
2637 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002638 for (const auto *D : S->decls()) {
2639 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002640 isFirst = false;
2641 }
2642 if (size == WL.size())
2643 return;
2644 // Now reverse the entries we just added. This will match the DFS
2645 // ordering performed by the worklist.
2646 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2647 std::reverse(I, E);
2648}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002649void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002650 AddStmt(E->getInit());
David Majnemerf7e36092016-06-23 00:15:04 +00002651 for (const DesignatedInitExpr::Designator &D :
2652 llvm::reverse(E->designators())) {
2653 if (D.isFieldDesignator()) {
2654 if (FieldDecl *Field = D.getField())
2655 AddMemberRef(Field, D.getFieldLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00002656 continue;
2657 }
David Majnemerf7e36092016-06-23 00:15:04 +00002658 if (D.isArrayDesignator()) {
2659 AddStmt(E->getArrayIndex(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002660 continue;
2661 }
David Majnemerf7e36092016-06-23 00:15:04 +00002662 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2663 AddStmt(E->getArrayRangeEnd(D));
2664 AddStmt(E->getArrayRangeStart(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002665 }
2666}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002667void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002668 EnqueueChildren(E);
2669 AddTypeLoc(E->getTypeInfoAsWritten());
2670}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002671void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002672 AddStmt(FS->getBody());
2673 AddStmt(FS->getInc());
2674 AddStmt(FS->getCond());
2675 AddDecl(FS->getConditionVariable());
2676 AddStmt(FS->getInit());
2677}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002678void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002679 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2680}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002681void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002682 AddStmt(If->getElse());
2683 AddStmt(If->getThen());
2684 AddStmt(If->getCond());
Milian Wolff08e18122020-05-02 22:18:09 +02002685 AddStmt(If->getInit());
Guy Benyei11169dd2012-12-18 14:30:41 +00002686 AddDecl(If->getConditionVariable());
2687}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002688void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002689 // We care about the syntactic form of the initializer list, only.
2690 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2691 IE = Syntactic;
2692 EnqueueChildren(IE);
2693}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002694void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002695 WL.push_back(MemberExprParts(M, Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002696
Guy Benyei11169dd2012-12-18 14:30:41 +00002697 // If the base of the member access expression is an implicit 'this', don't
2698 // visit it.
2699 // FIXME: If we ever want to show these implicit accesses, this will be
2700 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002701 if (M->isImplicitAccess())
2702 return;
2703
2704 // Ignore base anonymous struct/union fields, otherwise they will shadow the
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00002705 // real field that we are interested in.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002706 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2707 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2708 if (FD->isAnonymousStructOrUnion()) {
2709 AddStmt(SubME->getBase());
2710 return;
2711 }
2712 }
2713 }
2714
2715 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002716}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002717void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002718 AddTypeLoc(E->getEncodedTypeSourceInfo());
2719}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002720void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002721 EnqueueChildren(M);
2722 AddTypeLoc(M->getClassReceiverTypeInfo());
2723}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002724void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002725 // Visit the components of the offsetof expression.
2726 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Michael Kruse7520cf02020-03-25 09:26:14 -05002727 const OffsetOfNode &Node = E->getComponent(I - 1);
Guy Benyei11169dd2012-12-18 14:30:41 +00002728 switch (Node.getKind()) {
2729 case OffsetOfNode::Array:
2730 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2731 break;
2732 case OffsetOfNode::Field:
2733 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2734 break;
2735 case OffsetOfNode::Identifier:
2736 case OffsetOfNode::Base:
2737 continue;
2738 }
2739 }
2740 // Visit the type into which we're computing the offset.
2741 AddTypeLoc(E->getTypeSourceInfo());
2742}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002743void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002744 if (E->hasExplicitTemplateArgs())
2745 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002746 WL.push_back(OverloadExprParts(E, Parent));
2747}
2748void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002749 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002750 EnqueueChildren(E);
2751 if (E->isArgumentType())
2752 AddTypeLoc(E->getArgumentTypeInfo());
2753}
Michael Kruse7520cf02020-03-25 09:26:14 -05002754void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002755void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002756 AddStmt(S->getBody());
2757 AddStmt(S->getCond());
2758 AddDecl(S->getConditionVariable());
2759}
2760
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002761void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002762 AddStmt(W->getBody());
2763 AddStmt(W->getCond());
2764 AddDecl(W->getConditionVariable());
2765}
2766
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002767void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002768 for (unsigned I = E->getNumArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002769 AddTypeLoc(E->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002770}
2771
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002772void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002773 AddTypeLoc(E->getQueriedTypeSourceInfo());
2774}
2775
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002776void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002777 EnqueueChildren(E);
2778}
2779
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002780void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002781 VisitOverloadExpr(U);
2782 if (!U->isImplicitAccess())
2783 AddStmt(U->getBase());
2784}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002785void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002786 AddStmt(E->getSubExpr());
2787 AddTypeLoc(E->getWrittenTypeInfo());
2788}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002789void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002790 WL.push_back(SizeOfPackExprParts(E, Parent));
2791}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002792void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002793 // If the opaque value has a source expression, just transparently
2794 // visit that. This is useful for (e.g.) pseudo-object expressions.
2795 if (Expr *SourceExpr = E->getSourceExpr())
2796 return Visit(SourceExpr);
2797}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002798void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002799 AddStmt(E->getBody());
2800 WL.push_back(LambdaExprParts(E, Parent));
2801}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002802void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002803 // Treat the expression like its syntactic form.
2804 Visit(E->getSyntacticForm());
2805}
2806
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002807void EnqueueVisitor::VisitOMPExecutableDirective(
Michael Kruse7520cf02020-03-25 09:26:14 -05002808 const OMPExecutableDirective *D) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002809 EnqueueChildren(D);
2810 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2811 E = D->clauses().end();
2812 I != E; ++I)
2813 EnqueueChildren(*I);
2814}
2815
Alexander Musman3aaab662014-08-19 11:27:13 +00002816void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2817 VisitOMPExecutableDirective(D);
2818}
2819
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002820void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2821 VisitOMPExecutableDirective(D);
2822}
2823
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002824void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002825 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002826}
2827
Alexey Bataevf29276e2014-06-18 04:14:57 +00002828void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002829 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002830}
2831
Alexander Musmanf82886e2014-09-18 05:12:34 +00002832void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2833 VisitOMPLoopDirective(D);
2834}
2835
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002836void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2837 VisitOMPExecutableDirective(D);
2838}
2839
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002840void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2841 VisitOMPExecutableDirective(D);
2842}
2843
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002844void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2845 VisitOMPExecutableDirective(D);
2846}
2847
Alexander Musman80c22892014-07-17 08:54:58 +00002848void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2849 VisitOMPExecutableDirective(D);
2850}
2851
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002852void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2853 VisitOMPExecutableDirective(D);
2854 AddDeclarationNameInfo(D);
2855}
2856
Michael Kruse7520cf02020-03-25 09:26:14 -05002857void EnqueueVisitor::VisitOMPParallelForDirective(
2858 const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002859 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002860}
2861
Alexander Musmane4e893b2014-09-23 09:33:00 +00002862void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2863 const OMPParallelForSimdDirective *D) {
2864 VisitOMPLoopDirective(D);
2865}
2866
cchen47d60942019-12-05 13:43:48 -05002867void EnqueueVisitor::VisitOMPParallelMasterDirective(
2868 const OMPParallelMasterDirective *D) {
2869 VisitOMPExecutableDirective(D);
2870}
2871
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002872void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2873 const OMPParallelSectionsDirective *D) {
2874 VisitOMPExecutableDirective(D);
2875}
2876
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002877void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2878 VisitOMPExecutableDirective(D);
2879}
2880
Michael Kruse7520cf02020-03-25 09:26:14 -05002881void EnqueueVisitor::VisitOMPTaskyieldDirective(
2882 const OMPTaskyieldDirective *D) {
Alexey Bataev68446b72014-07-18 07:47:19 +00002883 VisitOMPExecutableDirective(D);
2884}
2885
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002886void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2887 VisitOMPExecutableDirective(D);
2888}
2889
Alexey Bataev2df347a2014-07-18 10:17:07 +00002890void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2891 VisitOMPExecutableDirective(D);
2892}
2893
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002894void EnqueueVisitor::VisitOMPTaskgroupDirective(
2895 const OMPTaskgroupDirective *D) {
2896 VisitOMPExecutableDirective(D);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00002897 if (const Expr *E = D->getReductionRef())
2898 VisitStmt(E);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002899}
2900
Alexey Bataev6125da92014-07-21 11:26:11 +00002901void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2902 VisitOMPExecutableDirective(D);
2903}
2904
Alexey Bataevc112e942020-02-28 09:52:15 -05002905void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
2906 VisitOMPExecutableDirective(D);
2907}
2908
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002909void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
2910 VisitOMPExecutableDirective(D);
2911}
2912
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002913void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2914 VisitOMPExecutableDirective(D);
2915}
2916
Alexey Bataev0162e452014-07-22 10:10:35 +00002917void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2918 VisitOMPExecutableDirective(D);
2919}
2920
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002921void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2922 VisitOMPExecutableDirective(D);
2923}
2924
Alexey Bataevc112e942020-02-28 09:52:15 -05002925void EnqueueVisitor::VisitOMPTargetDataDirective(
2926 const OMPTargetDataDirective *D) {
Michael Wong65f367f2015-07-21 13:44:28 +00002927 VisitOMPExecutableDirective(D);
2928}
2929
Samuel Antaodf67fc42016-01-19 19:15:56 +00002930void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2931 const OMPTargetEnterDataDirective *D) {
2932 VisitOMPExecutableDirective(D);
2933}
2934
Samuel Antao72590762016-01-19 20:04:50 +00002935void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2936 const OMPTargetExitDataDirective *D) {
2937 VisitOMPExecutableDirective(D);
2938}
2939
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002940void EnqueueVisitor::VisitOMPTargetParallelDirective(
2941 const OMPTargetParallelDirective *D) {
2942 VisitOMPExecutableDirective(D);
2943}
2944
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002945void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2946 const OMPTargetParallelForDirective *D) {
2947 VisitOMPLoopDirective(D);
2948}
2949
Alexey Bataev13314bf2014-10-09 04:18:56 +00002950void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2951 VisitOMPExecutableDirective(D);
2952}
2953
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002954void EnqueueVisitor::VisitOMPCancellationPointDirective(
2955 const OMPCancellationPointDirective *D) {
2956 VisitOMPExecutableDirective(D);
2957}
2958
Alexey Bataev80909872015-07-02 11:25:17 +00002959void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2960 VisitOMPExecutableDirective(D);
2961}
2962
Alexey Bataev49f6e782015-12-01 04:18:41 +00002963void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2964 VisitOMPLoopDirective(D);
2965}
2966
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002967void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2968 const OMPTaskLoopSimdDirective *D) {
2969 VisitOMPLoopDirective(D);
2970}
2971
Alexey Bataev60e51c42019-10-10 20:13:02 +00002972void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
2973 const OMPMasterTaskLoopDirective *D) {
2974 VisitOMPLoopDirective(D);
2975}
2976
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002977void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
2978 const OMPMasterTaskLoopSimdDirective *D) {
2979 VisitOMPLoopDirective(D);
2980}
2981
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002982void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
2983 const OMPParallelMasterTaskLoopDirective *D) {
2984 VisitOMPLoopDirective(D);
2985}
2986
Alexey Bataev14a388f2019-10-25 10:27:13 -04002987void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
2988 const OMPParallelMasterTaskLoopSimdDirective *D) {
2989 VisitOMPLoopDirective(D);
2990}
2991
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002992void EnqueueVisitor::VisitOMPDistributeDirective(
2993 const OMPDistributeDirective *D) {
2994 VisitOMPLoopDirective(D);
2995}
2996
Carlo Bertolli9925f152016-06-27 14:55:37 +00002997void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
2998 const OMPDistributeParallelForDirective *D) {
2999 VisitOMPLoopDirective(D);
3000}
3001
Kelvin Li4a39add2016-07-05 05:00:15 +00003002void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
3003 const OMPDistributeParallelForSimdDirective *D) {
3004 VisitOMPLoopDirective(D);
3005}
3006
Kelvin Li787f3fc2016-07-06 04:45:38 +00003007void EnqueueVisitor::VisitOMPDistributeSimdDirective(
3008 const OMPDistributeSimdDirective *D) {
3009 VisitOMPLoopDirective(D);
3010}
3011
Kelvin Lia579b912016-07-14 02:54:56 +00003012void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
3013 const OMPTargetParallelForSimdDirective *D) {
3014 VisitOMPLoopDirective(D);
3015}
3016
Kelvin Li986330c2016-07-20 22:57:10 +00003017void EnqueueVisitor::VisitOMPTargetSimdDirective(
3018 const OMPTargetSimdDirective *D) {
3019 VisitOMPLoopDirective(D);
3020}
3021
Kelvin Li02532872016-08-05 14:37:37 +00003022void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3023 const OMPTeamsDistributeDirective *D) {
3024 VisitOMPLoopDirective(D);
3025}
3026
Kelvin Li4e325f72016-10-25 12:50:55 +00003027void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3028 const OMPTeamsDistributeSimdDirective *D) {
3029 VisitOMPLoopDirective(D);
3030}
3031
Kelvin Li579e41c2016-11-30 23:51:03 +00003032void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3033 const OMPTeamsDistributeParallelForSimdDirective *D) {
3034 VisitOMPLoopDirective(D);
3035}
3036
Kelvin Li7ade93f2016-12-09 03:24:30 +00003037void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3038 const OMPTeamsDistributeParallelForDirective *D) {
3039 VisitOMPLoopDirective(D);
3040}
3041
Kelvin Libf594a52016-12-17 05:48:59 +00003042void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3043 const OMPTargetTeamsDirective *D) {
3044 VisitOMPExecutableDirective(D);
3045}
3046
Kelvin Li83c451e2016-12-25 04:52:54 +00003047void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3048 const OMPTargetTeamsDistributeDirective *D) {
3049 VisitOMPLoopDirective(D);
3050}
3051
Kelvin Li80e8f562016-12-29 22:16:30 +00003052void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3053 const OMPTargetTeamsDistributeParallelForDirective *D) {
3054 VisitOMPLoopDirective(D);
3055}
3056
Kelvin Li1851df52017-01-03 05:23:48 +00003057void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3058 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3059 VisitOMPLoopDirective(D);
3060}
3061
Kelvin Lida681182017-01-10 18:08:18 +00003062void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3063 const OMPTargetTeamsDistributeSimdDirective *D) {
3064 VisitOMPLoopDirective(D);
3065}
3066
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003067void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003068 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3069 .Visit(S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003070}
3071
3072bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3073 if (RegionOfInterest.isValid()) {
3074 SourceRange Range = getRawCursorExtent(C);
3075 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3076 return false;
3077 }
3078 return true;
3079}
3080
3081bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3082 while (!WL.empty()) {
3083 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00003084 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00003085
3086 // Set the Parent field, then back to its old value once we're done.
3087 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
Michael Kruse7520cf02020-03-25 09:26:14 -05003088
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 switch (LI.getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003090 case VisitorJob::DeclVisitKind: {
3091 const Decl *D = cast<DeclVisit>(&LI)->get();
3092 if (!D)
3093 continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00003094
Michael Kruse7520cf02020-03-25 09:26:14 -05003095 // For now, perform default visitation for Decls.
3096 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3097 cast<DeclVisit>(&LI)->isFirst())))
3098 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003099
Michael Kruse7520cf02020-03-25 09:26:14 -05003100 continue;
3101 }
3102 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3103 for (const TemplateArgumentLoc &Arg :
3104 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3105 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00003106 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003108 continue;
3109 }
3110 case VisitorJob::TypeLocVisitKind: {
3111 // Perform default visitation for TypeLocs.
3112 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3113 return true;
3114 continue;
3115 }
3116 case VisitorJob::LabelRefVisitKind: {
3117 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3118 if (LabelStmt *stmt = LS->getStmt()) {
3119 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3120 TU))) {
3121 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003123 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003124 continue;
3125 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003126
Michael Kruse7520cf02020-03-25 09:26:14 -05003127 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3128 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3129 if (VisitNestedNameSpecifierLoc(V->get()))
3130 return true;
3131 continue;
3132 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003133
Michael Kruse7520cf02020-03-25 09:26:14 -05003134 case VisitorJob::DeclarationNameInfoVisitKind: {
3135 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3136 return true;
3137 continue;
3138 }
3139 case VisitorJob::MemberRefVisitKind: {
3140 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3141 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3142 return true;
3143 continue;
3144 }
3145 case VisitorJob::StmtVisitKind: {
3146 const Stmt *S = cast<StmtVisit>(&LI)->get();
3147 if (!S)
Guy Benyei11169dd2012-12-18 14:30:41 +00003148 continue;
Richard Smithba71c082013-05-16 06:20:58 +00003149
Michael Kruse7520cf02020-03-25 09:26:14 -05003150 // Update the current cursor.
3151 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3152 if (!IsInRegionOfInterest(Cursor))
3153 continue;
3154 switch (Visitor(Cursor, Parent, ClientData)) {
3155 case CXChildVisit_Break:
3156 return true;
3157 case CXChildVisit_Continue:
3158 break;
3159 case CXChildVisit_Recurse:
3160 if (PostChildrenVisitor)
3161 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3162 EnqueueWorkList(WL, S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 break;
3164 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003165 continue;
3166 }
3167 case VisitorJob::MemberExprPartsKind: {
3168 // Handle the other pieces in the MemberExpr besides the base.
3169 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00003170
Michael Kruse7520cf02020-03-25 09:26:14 -05003171 // Visit the nested-name-specifier
3172 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3173 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +00003174 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05003175
3176 // Visit the declaration name.
3177 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3178 return true;
3179
3180 // Visit the explicitly-specified template arguments, if any.
3181 if (M->hasExplicitTemplateArgs()) {
3182 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3183 *ArgEnd = Arg + M->getNumTemplateArgs();
3184 Arg != ArgEnd; ++Arg) {
3185 if (VisitTemplateArgumentLoc(*Arg))
3186 return true;
3187 }
3188 }
3189 continue;
3190 }
3191 case VisitorJob::DeclRefExprPartsKind: {
3192 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3193 // Visit nested-name-specifier, if present.
3194 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3195 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3196 return true;
3197 // Visit declaration name.
3198 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3199 return true;
3200 continue;
3201 }
3202 case VisitorJob::OverloadExprPartsKind: {
3203 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3204 // Visit the nested-name-specifier.
3205 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3206 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3207 return true;
3208 // Visit the declaration name.
3209 if (VisitDeclarationNameInfo(O->getNameInfo()))
3210 return true;
3211 // Visit the overloaded declaration reference.
3212 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3213 return true;
3214 continue;
3215 }
3216 case VisitorJob::SizeOfPackExprPartsKind: {
3217 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3218 NamedDecl *Pack = E->getPack();
3219 if (isa<TemplateTypeParmDecl>(Pack)) {
3220 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3221 E->getPackLoc(), TU)))
3222 return true;
3223
3224 continue;
3225 }
3226
3227 if (isa<TemplateTemplateParmDecl>(Pack)) {
3228 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3229 E->getPackLoc(), TU)))
3230 return true;
3231
3232 continue;
3233 }
3234
3235 // Non-type template parameter packs and function parameter packs are
3236 // treated like DeclRefExpr cursors.
3237 continue;
3238 }
3239
3240 case VisitorJob::LambdaExprPartsKind: {
3241 // Visit non-init captures.
3242 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3243 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3244 CEnd = E->explicit_capture_end();
3245 C != CEnd; ++C) {
3246 if (!C->capturesVariable())
3247 continue;
3248
3249 if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
3250 TU)))
3251 return true;
3252 }
3253 // Visit init captures
3254 for (auto InitExpr : E->capture_inits()) {
3255 if (Visit(InitExpr))
3256 return true;
3257 }
3258
3259 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3260 // Visit parameters and return type, if present.
3261 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3262 if (E->hasExplicitParameters()) {
3263 // Visit parameters.
3264 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3265 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3266 return true;
3267 }
3268 if (E->hasExplicitResultType()) {
3269 // Visit result type.
3270 if (Visit(Proto.getReturnLoc()))
3271 return true;
3272 }
3273 }
3274 break;
3275 }
3276
3277 case VisitorJob::PostChildrenVisitKind:
3278 if (PostChildrenVisitor(Parent, ClientData))
3279 return true;
3280 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 }
3282 }
3283 return false;
3284}
3285
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003286bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00003287 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 if (!WorkListFreeList.empty()) {
3289 WL = WorkListFreeList.back();
3290 WL->clear();
3291 WorkListFreeList.pop_back();
Michael Kruse7520cf02020-03-25 09:26:14 -05003292 } else {
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 WL = new VisitorWorkList();
3294 WorkListCache.push_back(WL);
3295 }
3296 EnqueueWorkList(*WL, S);
3297 bool result = RunVisitorWorkList(*WL);
3298 WorkListFreeList.push_back(WL);
3299 return result;
3300}
3301
3302namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003303typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00003304RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3305 const DeclarationNameInfo &NI, SourceRange QLoc,
3306 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3308 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3309 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
Michael Kruse7520cf02020-03-25 09:26:14 -05003310
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
Michael Kruse7520cf02020-03-25 09:26:14 -05003312
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 RefNamePieces Pieces;
3314
3315 if (WantQualifier && QLoc.isValid())
3316 Pieces.push_back(QLoc);
Michael Kruse7520cf02020-03-25 09:26:14 -05003317
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3319 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00003320
3321 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3322 Pieces.push_back(*TemplateArgsLoc);
3323
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 if (Kind == DeclarationName::CXXOperatorName) {
3325 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003326 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003328 NI.getInfo().CXXOperatorName.EndOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003330
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 if (WantSinglePiece) {
3332 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3333 Pieces.clear();
3334 Pieces.push_back(R);
Michael Kruse7520cf02020-03-25 09:26:14 -05003335 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003336
Michael Kruse7520cf02020-03-25 09:26:14 -05003337 return Pieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338}
Michael Kruse7520cf02020-03-25 09:26:14 -05003339} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00003340
3341//===----------------------------------------------------------------------===//
3342// Misc. API hooks.
Michael Kruse7520cf02020-03-25 09:26:14 -05003343//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00003344
Chandler Carruth66660742014-06-27 16:37:27 +00003345namespace {
3346struct RegisterFatalErrorHandler {
3347 RegisterFatalErrorHandler() {
Jan Korousf7d23762019-09-12 22:55:55 +00003348 clang_install_aborting_llvm_fatal_error_handler();
Chandler Carruth66660742014-06-27 16:37:27 +00003349 }
3350};
Michael Kruse7520cf02020-03-25 09:26:14 -05003351} // namespace
Chandler Carruth66660742014-06-27 16:37:27 +00003352
Michael Kruse7520cf02020-03-25 09:26:14 -05003353static llvm::ManagedStatic<RegisterFatalErrorHandler>
3354 RegisterFatalErrorHandlerOnce;
Chandler Carruth66660742014-06-27 16:37:27 +00003355
Guy Benyei11169dd2012-12-18 14:30:41 +00003356CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3357 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 // We use crash recovery to make some of our APIs more reliable, implicitly
3359 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003360 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3361 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003362
Chandler Carruth66660742014-06-27 16:37:27 +00003363 // Look through the managed static to trigger construction of the managed
3364 // static which registers our fatal error handler. This ensures it is only
3365 // registered once.
3366 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003367
Adrian Prantlbc068582015-07-08 01:00:30 +00003368 // Initialize targets for clang module support.
3369 llvm::InitializeAllTargets();
3370 llvm::InitializeAllTargetMCs();
3371 llvm::InitializeAllAsmPrinters();
3372 llvm::InitializeAllAsmParsers();
3373
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003374 CIndexer *CIdxr = new CIndexer();
3375
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 if (excludeDeclarationsFromPCH)
3377 CIdxr->setOnlyLocalDecls();
3378 if (displayDiagnostics)
3379 CIdxr->setDisplayDiagnostics();
3380
3381 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3382 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3383 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3384 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3385 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3386 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3387
3388 return CIdxr;
3389}
3390
3391void clang_disposeIndex(CXIndex CIdx) {
3392 if (CIdx)
3393 delete static_cast<CIndexer *>(CIdx);
3394}
3395
3396void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3397 if (CIdx)
3398 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3399}
3400
3401unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3402 if (CIdx)
3403 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3404 return 0;
3405}
3406
Alex Lorenz08615792017-12-04 21:56:36 +00003407void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
3408 const char *Path) {
3409 if (CIdx)
3410 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
3411}
3412
Guy Benyei11169dd2012-12-18 14:30:41 +00003413void clang_toggleCrashRecovery(unsigned isEnabled) {
3414 if (isEnabled)
3415 llvm::CrashRecoveryContext::Enable();
3416 else
3417 llvm::CrashRecoveryContext::Disable();
3418}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003419
Guy Benyei11169dd2012-12-18 14:30:41 +00003420CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3421 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003422 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003423 enum CXErrorCode Result =
3424 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003425 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003426 assert((TU && Result == CXError_Success) ||
3427 (!TU && Result != CXError_Success));
3428 return TU;
3429}
3430
3431enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3432 const char *ast_filename,
3433 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003434 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003435 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003436
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003437 if (!CIdx || !ast_filename || !out_TU)
3438 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003439
Michael Kruse7520cf02020-03-25 09:26:14 -05003440 LOG_FUNC_SECTION { *Log << ast_filename; }
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003441
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3443 FileSystemOptions FileSystemOpts;
3444
Justin Bognerd512c1e2014-10-15 00:33:06 +00003445 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3446 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003447 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Richard Smithdbafb6c2017-06-29 23:23:46 +00003448 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
Michael Kruse7520cf02020-03-25 09:26:14 -05003449 ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3450 CXXIdx->getOnlyLocalDecls(), None, CaptureDiagsKind::All,
David Blaikie6f7382d2014-08-10 19:08:04 +00003451 /*AllowPCHWithCompilerErrors=*/true,
3452 /*UserFilesAreVolatile=*/true);
David Blaikieea4395e2017-01-06 19:49:01 +00003453 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003454 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003455}
3456
3457unsigned clang_defaultEditingTranslationUnitOptions() {
Michael Kruse7520cf02020-03-25 09:26:14 -05003458 return CXTranslationUnit_PrecompiledPreamble |
Guy Benyei11169dd2012-12-18 14:30:41 +00003459 CXTranslationUnit_CacheCompletionResults;
3460}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003461
Michael Kruse7520cf02020-03-25 09:26:14 -05003462CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3463 CXIndex CIdx, const char *source_filename, int num_command_line_args,
3464 const char *const *command_line_args, unsigned num_unsaved_files,
3465 struct CXUnsavedFile *unsaved_files) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
Michael Kruse7520cf02020-03-25 09:26:14 -05003467 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3468 num_command_line_args, unsaved_files,
3469 num_unsaved_files, Options);
Guy Benyei11169dd2012-12-18 14:30:41 +00003470}
3471
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003472static CXErrorCode
3473clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3474 const char *const *command_line_args,
3475 int num_command_line_args,
3476 ArrayRef<CXUnsavedFile> unsaved_files,
3477 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003478 // Set up the initial return values.
3479 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003480 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003481
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003482 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003483 if (!CIdx || !out_TU)
3484 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003485
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3487
3488 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3489 setThreadBackgroundPriority();
3490
3491 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003492 bool CreatePreambleOnFirstParse =
3493 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 // FIXME: Add a flag for modules.
Michael Kruse7520cf02020-03-25 09:26:14 -05003495 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3496 CXTranslationUnit_SingleFileParse))
3497 ? TU_Prefix
3498 : TU_Complete;
3499 bool CacheCodeCompletionResults =
3500 options & CXTranslationUnit_CacheCompletionResults;
3501 bool IncludeBriefCommentsInCodeCompletion =
3502 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003503 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
3504 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
Michael Kruse7520cf02020-03-25 09:26:14 -05003505 bool RetainExcludedCB =
3506 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
Ivan Donchevskii6e895282018-05-17 09:24:37 +00003507 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
3508 if (options & CXTranslationUnit_SkipFunctionBodies) {
3509 SkipFunctionBodies =
3510 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
3511 ? SkipFunctionBodiesScope::Preamble
3512 : SkipFunctionBodiesScope::PreambleAndMainFile;
3513 }
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003514
3515 // Configure the diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05003516 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3517 CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003518
Manuel Klimek016c0242016-03-01 10:56:19 +00003519 if (options & CXTranslationUnit_KeepGoing)
Ivan Donchevskii878271b2019-03-07 10:13:50 +00003520 Diags->setFatalsAsError(true);
Manuel Klimek016c0242016-03-01 10:56:19 +00003521
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003522 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
3523 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
3524 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
3525
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003527 llvm::CrashRecoveryContextCleanupRegistrar<
3528 DiagnosticsEngine,
3529 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
3530 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003531
Ahmed Charlesb8984322014-03-07 20:03:18 +00003532 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3533 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003534
3535 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003536 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3537 RemappedCleanup(RemappedFiles.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003538
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003539 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003540 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003541 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003542 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 }
3544
Ahmed Charlesb8984322014-03-07 20:03:18 +00003545 std::unique_ptr<std::vector<const char *>> Args(
3546 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003547
3548 // Recover resources if we crash before exiting this method.
Michael Kruse7520cf02020-03-25 09:26:14 -05003549 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
3550 ArgsCleanup(Args.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003551
3552 // Since the Clang C library is primarily used by batch tools dealing with
3553 // (often very broken) source code, where spell-checking can have a
Michael Kruse7520cf02020-03-25 09:26:14 -05003554 // significant negative impact on performance (particularly when
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 // precompiled headers are involved), we disable it by default.
3556 // Only do this if we haven't found a spell-checking-related argument.
3557 bool FoundSpellCheckingArgument = false;
3558 for (int I = 0; I != num_command_line_args; ++I) {
3559 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3560 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3561 FoundSpellCheckingArgument = true;
3562 break;
3563 }
3564 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 Args->insert(Args->end(), command_line_args,
3566 command_line_args + num_command_line_args);
3567
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003568 if (!FoundSpellCheckingArgument)
3569 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3570
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 // The 'source_filename' argument is optional. If the caller does not
3572 // specify it then it is assumed that the source file is specified
3573 // in the actual argument list.
3574 // Put the source file after command_line_args otherwise if '-x' flag is
3575 // present it will be unused.
3576 if (source_filename)
3577 Args->push_back(source_filename);
3578
3579 // Do we need the detailed preprocessing record?
3580 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3581 Args->push_back("-Xclang");
3582 Args->push_back("-detailed-preprocessing-record");
3583 }
Alex Lorenzcb006402017-04-27 13:47:03 +00003584
3585 // Suppress any editor placeholder diagnostics.
3586 Args->push_back("-fallow-editor-placeholders");
3587
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003589 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003590 // Unless the user specified that they want the preamble on the first parse
3591 // set it up to be created on the first reparse. This makes the first parse
3592 // faster, trading for a slower (first) reparse.
3593 unsigned PrecompilePreambleAfterNParses =
3594 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Alex Lorenz08615792017-12-04 21:56:36 +00003595
Alex Lorenz08615792017-12-04 21:56:36 +00003596 LibclangInvocationReporter InvocationReporter(
3597 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
Alex Lorenz690f0e22017-12-07 20:37:50 +00003598 options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
3599 unsaved_files);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003600 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003601 Args->data(), Args->data() + Args->size(),
3602 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003603 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003604 CaptureDiagnostics, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003605 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3606 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Argyrios Kyrtzidis735e92c2017-06-09 01:20:48 +00003607 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
Evgeny Mankov2ed2e622019-08-27 22:15:32 +00003608 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003609 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3610 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003611
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003612 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003613 if (!Unit && !ErrUnit)
3614 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003615
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 if (NumErrors != Diags->getClient()->getNumErrors()) {
3617 // Make sure to check that 'Unit' is non-NULL.
3618 if (CXXIdx->getDisplayDiagnostics())
3619 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3620 }
3621
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003622 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3623 return CXError_ASTReadError;
3624
David Blaikieea4395e2017-01-06 19:49:01 +00003625 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
Alex Lorenz690f0e22017-12-07 20:37:50 +00003626 if (CXTranslationUnitImpl *TU = *out_TU) {
3627 TU->ParsingOptions = options;
3628 TU->Arguments.reserve(Args->size());
3629 for (const char *Arg : *Args)
3630 TU->Arguments.push_back(Arg);
3631 return CXError_Success;
3632 }
3633 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003634}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003635
3636CXTranslationUnit
Michael Kruse7520cf02020-03-25 09:26:14 -05003637clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003638 const char *const *command_line_args,
3639 int num_command_line_args,
3640 struct CXUnsavedFile *unsaved_files,
Michael Kruse7520cf02020-03-25 09:26:14 -05003641 unsigned num_unsaved_files, unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003642 CXTranslationUnit TU;
3643 enum CXErrorCode Result = clang_parseTranslationUnit2(
3644 CIdx, source_filename, command_line_args, num_command_line_args,
3645 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003646 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003647 assert((TU && Result == CXError_Success) ||
3648 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003649 return TU;
3650}
3651
3652enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003653 CXIndex CIdx, const char *source_filename,
3654 const char *const *command_line_args, int num_command_line_args,
3655 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3656 unsigned options, CXTranslationUnit *out_TU) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003657 noteBottomOfStack();
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003658 SmallVector<const char *, 4> Args;
3659 Args.push_back("clang");
3660 Args.append(command_line_args, command_line_args + num_command_line_args);
3661 return clang_parseTranslationUnit2FullArgv(
3662 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3663 num_unsaved_files, options, out_TU);
3664}
3665
3666enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3667 CXIndex CIdx, const char *source_filename,
3668 const char *const *command_line_args, int num_command_line_args,
3669 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3670 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003671 LOG_FUNC_SECTION {
3672 *Log << source_filename << ": ";
3673 for (int i = 0; i != num_command_line_args; ++i)
3674 *Log << command_line_args[i] << " ";
3675 }
3676
Alp Toker9d85b182014-07-07 01:23:14 +00003677 if (num_unsaved_files && !unsaved_files)
3678 return CXError_InvalidArguments;
3679
Alp Toker5c532982014-07-07 22:42:03 +00003680 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003681 auto ParseTranslationUnitImpl = [=, &result] {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003682 noteBottomOfStack();
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003683 result = clang_parseTranslationUnit_Impl(
3684 CIdx, source_filename, command_line_args, num_command_line_args,
3685 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3686 };
Erik Verbruggen284848d2017-08-29 09:08:02 +00003687
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 llvm::CrashRecoveryContext CRC;
3689
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003690 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3692 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3693 fprintf(stderr, " 'command_line_args' : [");
3694 for (int i = 0; i != num_command_line_args; ++i) {
3695 if (i)
3696 fprintf(stderr, ", ");
3697 fprintf(stderr, "'%s'", command_line_args[i]);
3698 }
3699 fprintf(stderr, "],\n");
3700 fprintf(stderr, " 'unsaved_files' : [");
3701 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3702 if (i)
3703 fprintf(stderr, ", ");
3704 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3705 unsaved_files[i].Length);
3706 }
3707 fprintf(stderr, "],\n");
3708 fprintf(stderr, " 'options' : %d,\n", options);
3709 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003710
3711 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003713 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003714 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 }
Alp Toker5c532982014-07-07 22:42:03 +00003716
3717 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003718}
3719
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003720CXString clang_Type_getObjCEncoding(CXType CT) {
3721 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3722 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3723 std::string encoding;
Michael Kruse7520cf02020-03-25 09:26:14 -05003724 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003725
3726 return cxstring::createDup(encoding);
3727}
3728
3729static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3730 if (C.kind == CXCursor_MacroDefinition) {
3731 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3732 return MDR->getName();
3733 } else if (C.kind == CXCursor_MacroExpansion) {
3734 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3735 return ME.getName();
3736 }
3737 return nullptr;
3738}
3739
3740unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3741 const IdentifierInfo *II = getMacroIdentifier(C);
3742 if (!II) {
3743 return false;
3744 }
3745 ASTUnit *ASTU = getCursorASTUnit(C);
3746 Preprocessor &PP = ASTU->getPreprocessor();
3747 if (const MacroInfo *MI = PP.getMacroInfo(II))
3748 return MI->isFunctionLike();
3749 return false;
3750}
3751
3752unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3753 const IdentifierInfo *II = getMacroIdentifier(C);
3754 if (!II) {
3755 return false;
3756 }
3757 ASTUnit *ASTU = getCursorASTUnit(C);
3758 Preprocessor &PP = ASTU->getPreprocessor();
3759 if (const MacroInfo *MI = PP.getMacroInfo(II))
3760 return MI->isBuiltinMacro();
3761 return false;
3762}
3763
3764unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3765 const Decl *D = getCursorDecl(C);
3766 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3767 if (!FD) {
3768 return false;
3769 }
3770 return FD->isInlined();
3771}
3772
Michael Kruse7520cf02020-03-25 09:26:14 -05003773static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003774 if (callExpr->getNumArgs() != 1) {
3775 return nullptr;
3776 }
3777
3778 StringLiteral *S = nullptr;
3779 auto *arg = callExpr->getArg(0);
3780 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3781 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3782 auto *subExpr = I->getSubExprAsWritten();
3783
Michael Kruse7520cf02020-03-25 09:26:14 -05003784 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003785 return nullptr;
3786 }
3787
3788 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3789 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3790 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3791 } else {
3792 return nullptr;
3793 }
3794 return S;
3795}
3796
David Blaikie59272572016-04-13 18:23:33 +00003797struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003798 CXEvalResultKind EvalType;
3799 union {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003800 unsigned long long unsignedVal;
3801 long long intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003802 double floatVal;
3803 char *stringVal;
3804 } EvalData;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003805 bool IsUnsignedInt;
David Blaikie59272572016-04-13 18:23:33 +00003806 ~ExprEvalResult() {
3807 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3808 EvalType != CXEval_Int) {
Alex Lorenza19cb2e2019-01-08 23:28:37 +00003809 delete[] EvalData.stringVal;
David Blaikie59272572016-04-13 18:23:33 +00003810 }
3811 }
3812};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003813
3814void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003815 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003816}
3817
3818CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3819 if (!E) {
3820 return CXEval_UnExposed;
3821 }
3822 return ((ExprEvalResult *)E)->EvalType;
3823}
3824
3825int clang_EvalResult_getAsInt(CXEvalResult E) {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003826 return clang_EvalResult_getAsLongLong(E);
3827}
3828
3829long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003830 if (!E) {
3831 return 0;
3832 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003833 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003834 if (Result->IsUnsignedInt)
3835 return Result->EvalData.unsignedVal;
3836 return Result->EvalData.intVal;
3837}
3838
3839unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
3840 return ((ExprEvalResult *)E)->IsUnsignedInt;
3841}
3842
3843unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
3844 if (!E) {
3845 return 0;
3846 }
3847
Michael Kruse7520cf02020-03-25 09:26:14 -05003848 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003849 if (Result->IsUnsignedInt)
3850 return Result->EvalData.unsignedVal;
3851 return Result->EvalData.intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003852}
3853
3854double clang_EvalResult_getAsDouble(CXEvalResult E) {
3855 if (!E) {
3856 return 0;
3857 }
3858 return ((ExprEvalResult *)E)->EvalData.floatVal;
3859}
3860
Michael Kruse7520cf02020-03-25 09:26:14 -05003861const char *clang_EvalResult_getAsStr(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003862 if (!E) {
3863 return nullptr;
3864 }
3865 return ((ExprEvalResult *)E)->EvalData.stringVal;
3866}
3867
Michael Kruse7520cf02020-03-25 09:26:14 -05003868static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003869 Expr::EvalResult ER;
3870 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003871 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003872 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003873
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003874 expr = expr->IgnoreParens();
Emilio Cobos Alvarez74375452019-07-09 14:27:01 +00003875 if (expr->isValueDependent())
3876 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003877 if (!expr->EvaluateAsRValue(ER, ctx))
3878 return nullptr;
3879
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003880 QualType rettype;
3881 CallExpr *callExpr;
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00003882 auto result = std::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003883 result->EvalType = CXEval_UnExposed;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003884 result->IsUnsignedInt = false;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003885
David Blaikiebbc00882016-04-13 18:36:19 +00003886 if (ER.Val.isInt()) {
3887 result->EvalType = CXEval_Int;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003888
Michael Kruse7520cf02020-03-25 09:26:14 -05003889 auto &val = ER.Val.getInt();
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003890 if (val.isUnsigned()) {
3891 result->IsUnsignedInt = true;
3892 result->EvalData.unsignedVal = val.getZExtValue();
3893 } else {
3894 result->EvalData.intVal = val.getExtValue();
3895 }
3896
David Blaikiebbc00882016-04-13 18:36:19 +00003897 return result.release();
3898 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003899
David Blaikiebbc00882016-04-13 18:36:19 +00003900 if (ER.Val.isFloat()) {
3901 llvm::SmallVector<char, 100> Buffer;
3902 ER.Val.getFloat().toString(Buffer);
3903 std::string floatStr(Buffer.data(), Buffer.size());
3904 result->EvalType = CXEval_Float;
3905 bool ignored;
3906 llvm::APFloat apFloat = ER.Val.getFloat();
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003907 apFloat.convert(llvm::APFloat::IEEEdouble(),
David Blaikiebbc00882016-04-13 18:36:19 +00003908 llvm::APFloat::rmNearestTiesToEven, &ignored);
3909 result->EvalData.floatVal = apFloat.convertToDouble();
3910 return result.release();
3911 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003912
David Blaikiebbc00882016-04-13 18:36:19 +00003913 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3914 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3915 auto *subExpr = I->getSubExprAsWritten();
3916 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3917 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003918 const StringLiteral *StrE = nullptr;
3919 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003920 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003921
3922 if (ObjCExpr) {
3923 StrE = ObjCExpr->getString();
3924 result->EvalType = CXEval_ObjCStrLiteral;
3925 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003926 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003927 result->EvalType = CXEval_StrLiteral;
3928 }
3929
3930 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003931 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003932 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3933 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003934 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003935 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003936 }
3937 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3938 expr->getStmtClass() == Stmt::StringLiteralClass) {
3939 const StringLiteral *StrE = nullptr;
3940 const ObjCStringLiteral *ObjCExpr;
3941 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003942
David Blaikiebbc00882016-04-13 18:36:19 +00003943 if (ObjCExpr) {
3944 StrE = ObjCExpr->getString();
3945 result->EvalType = CXEval_ObjCStrLiteral;
3946 } else {
3947 StrE = cast<StringLiteral>(expr);
3948 result->EvalType = CXEval_StrLiteral;
3949 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003950
David Blaikiebbc00882016-04-13 18:36:19 +00003951 std::string strRef(StrE->getString().str());
3952 result->EvalData.stringVal = new char[strRef.size() + 1];
3953 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3954 result->EvalData.stringVal[strRef.size()] = '\0';
3955 return result.release();
3956 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003957
David Blaikiebbc00882016-04-13 18:36:19 +00003958 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3959 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003960
David Blaikiebbc00882016-04-13 18:36:19 +00003961 rettype = CC->getType();
3962 if (rettype.getAsString() == "CFStringRef" &&
3963 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003964
David Blaikiebbc00882016-04-13 18:36:19 +00003965 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3966 StringLiteral *S = getCFSTR_value(callExpr);
3967 if (S) {
3968 std::string strLiteral(S->getString().str());
3969 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003970
David Blaikiebbc00882016-04-13 18:36:19 +00003971 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3972 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3973 strLiteral.size());
3974 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003975 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003976 }
3977 }
3978
David Blaikiebbc00882016-04-13 18:36:19 +00003979 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3980 callExpr = static_cast<CallExpr *>(expr);
3981 rettype = callExpr->getCallReturnType(ctx);
3982
3983 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
3984 return nullptr;
3985
3986 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3987 if (callExpr->getNumArgs() == 1 &&
3988 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
3989 return nullptr;
3990 } else if (rettype.getAsString() == "CFStringRef") {
3991
3992 StringLiteral *S = getCFSTR_value(callExpr);
3993 if (S) {
3994 std::string strLiteral(S->getString().str());
3995 result->EvalType = CXEval_CFStr;
3996 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3997 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3998 strLiteral.size());
3999 result->EvalData.stringVal[strLiteral.size()] = '\0';
4000 return result.release();
4001 }
4002 }
4003 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
4004 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
4005 ValueDecl *V = D->getDecl();
4006 if (V->getKind() == Decl::Function) {
4007 std::string strName = V->getNameAsString();
4008 result->EvalType = CXEval_Other;
4009 result->EvalData.stringVal = new char[strName.size() + 1];
4010 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
4011 result->EvalData.stringVal[strName.size()] = '\0';
4012 return result.release();
4013 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004014 }
4015
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004016 return nullptr;
4017}
4018
Alex Lorenz65317e12019-01-08 22:32:51 +00004019static const Expr *evaluateDeclExpr(const Decl *D) {
4020 if (!D)
Evgeniy Stepanov9b871492018-07-10 19:48:53 +00004021 return nullptr;
Alex Lorenz65317e12019-01-08 22:32:51 +00004022 if (auto *Var = dyn_cast<VarDecl>(D))
4023 return Var->getInit();
4024 else if (auto *Field = dyn_cast<FieldDecl>(D))
4025 return Field->getInClassInitializer();
4026 return nullptr;
4027}
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004028
Alex Lorenz65317e12019-01-08 22:32:51 +00004029static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4030 assert(CS && "invalid compound statement");
4031 for (auto *bodyIterator : CS->body()) {
4032 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4033 return E;
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004034 }
Alex Lorenzc4cf96e2018-07-09 19:56:45 +00004035 return nullptr;
4036}
4037
Alex Lorenz65317e12019-01-08 22:32:51 +00004038CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
4039 if (const Expr *E =
4040 clang_getCursorKind(C) == CXCursor_CompoundStmt
4041 ? evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)))
4042 : evaluateDeclExpr(getCursorDecl(C)))
4043 return const_cast<CXEvalResult>(
4044 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4045 return nullptr;
4046}
4047
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004048unsigned clang_Cursor_hasAttrs(CXCursor C) {
4049 const Decl *D = getCursorDecl(C);
4050 if (!D) {
4051 return 0;
4052 }
4053
4054 if (D->hasAttrs()) {
4055 return 1;
4056 }
4057
4058 return 0;
4059}
Guy Benyei11169dd2012-12-18 14:30:41 +00004060unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4061 return CXSaveTranslationUnit_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05004062}
Guy Benyei11169dd2012-12-18 14:30:41 +00004063
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004064static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4065 const char *FileName,
4066 unsigned options) {
4067 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4069 setThreadBackgroundPriority();
4070
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004071 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4072 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00004073}
4074
4075int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4076 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004077 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004078
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004079 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004080 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004082 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004083
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004084 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4086 if (!CXXUnit->hasSema())
4087 return CXSaveError_InvalidTU;
4088
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004089 CXSaveError result;
4090 auto SaveTranslationUnitImpl = [=, &result]() {
4091 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4092 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004093
Erik Verbruggen3cc39112017-11-14 09:34:39 +00004094 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004095 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00004096
4097 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4098 PrintLibclangResourceUsage(TU);
4099
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004100 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 }
4102
4103 // We have an AST that has invalid nodes due to compiler errors.
4104 // Use a crash recovery thread for protection.
4105
4106 llvm::CrashRecoveryContext CRC;
4107
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004108 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4110 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4111 fprintf(stderr, " 'options' : %d,\n", options);
4112 fprintf(stderr, "}\n");
4113
4114 return CXSaveError_Unknown;
4115
4116 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4117 PrintLibclangResourceUsage(TU);
4118 }
4119
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004120 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004121}
4122
4123void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4124 if (CTUnit) {
4125 // If the translation unit has been marked as unsafe to free, just discard
4126 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004127 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4128 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00004129 return;
4130
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004131 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00004132 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4134 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00004135 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 delete CTUnit;
4137 }
4138}
4139
Erik Verbruggen346066b2017-05-30 14:25:54 +00004140unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4141 if (CTUnit) {
4142 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4143
4144 if (Unit && Unit->isUnsafeToFree())
4145 return false;
4146
4147 Unit->ResetForParse();
4148 return true;
4149 }
4150
4151 return false;
4152}
4153
Guy Benyei11169dd2012-12-18 14:30:41 +00004154unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4155 return CXReparse_None;
4156}
4157
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004158static CXErrorCode
4159clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4160 ArrayRef<CXUnsavedFile> unsaved_files,
4161 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004162 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004163 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004164 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004165 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004166 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004167
4168 // Reset the associated diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05004169 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00004170 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004171
Dmitri Gribenko183436e2013-01-26 21:49:50 +00004172 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4174 setThreadBackgroundPriority();
4175
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004176 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00004178
4179 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4180 new std::vector<ASTUnit::RemappedFile>());
4181
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05004183 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4184 RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00004185
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004186 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004187 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00004188 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004189 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004191
Adrian Prantlbb165fb2015-06-20 18:53:08 +00004192 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4193 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004194 return CXError_Success;
4195 if (isASTReadError(CXXUnit))
4196 return CXError_ASTReadError;
4197 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00004198}
4199
4200int clang_reparseTranslationUnit(CXTranslationUnit TU,
4201 unsigned num_unsaved_files,
4202 struct CXUnsavedFile *unsaved_files,
4203 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004204 LOG_FUNC_SECTION { *Log << TU; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004205
Alp Toker9d85b182014-07-07 01:23:14 +00004206 if (num_unsaved_files && !unsaved_files)
4207 return CXError_InvalidArguments;
4208
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004209 CXErrorCode result;
4210 auto ReparseTranslationUnitImpl = [=, &result]() {
4211 result = clang_reparseTranslationUnit_Impl(
4212 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
4213 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004214
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 llvm::CrashRecoveryContext CRC;
4216
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004217 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004219 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004220 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4222 PrintLibclangResourceUsage(TU);
4223
Alp Toker5c532982014-07-07 22:42:03 +00004224 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004225}
4226
Guy Benyei11169dd2012-12-18 14:30:41 +00004227CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004228 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004229 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004230 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004231 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004232
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004233 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004234 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004235}
4236
4237CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004238 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004239 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004240 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004241 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004242
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004243 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4245}
4246
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004247CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4248 if (isNotUsableTU(CTUnit)) {
4249 LOG_BAD_TU(CTUnit);
4250 return nullptr;
4251 }
4252
Michael Kruse7520cf02020-03-25 09:26:14 -05004253 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004254 impl->TranslationUnit = CTUnit;
4255 return impl;
4256}
4257
4258CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4259 if (!TargetInfo)
4260 return cxstring::createEmpty();
4261
4262 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4263 assert(!isNotUsableTU(CTUnit) &&
4264 "Unexpected unusable translation unit in TargetInfo");
4265
4266 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4267 std::string Triple =
Michael Kruse7520cf02020-03-25 09:26:14 -05004268 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004269 return cxstring::createDup(Triple);
4270}
4271
4272int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4273 if (!TargetInfo)
4274 return -1;
4275
4276 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4277 assert(!isNotUsableTU(CTUnit) &&
4278 "Unexpected unusable translation unit in TargetInfo");
4279
4280 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4281 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4282}
4283
4284void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4285 if (!TargetInfo)
4286 return;
4287
4288 delete TargetInfo;
4289}
4290
Guy Benyei11169dd2012-12-18 14:30:41 +00004291//===----------------------------------------------------------------------===//
4292// CXFile Operations.
4293//===----------------------------------------------------------------------===//
4294
Guy Benyei11169dd2012-12-18 14:30:41 +00004295CXString clang_getFileName(CXFile SFile) {
4296 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00004297 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00004298
4299 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004300 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004301}
4302
4303time_t clang_getFileTime(CXFile SFile) {
4304 if (!SFile)
4305 return 0;
4306
4307 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4308 return FEnt->getModificationTime();
4309}
4310
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004311CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004312 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004313 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00004314 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004315 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004316
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004317 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004318
4319 FileManager &FMgr = CXXUnit->getFileManager();
Harlan Haskins8d323d12019-08-01 21:31:56 +00004320 auto File = FMgr.getFile(file_name);
4321 if (!File)
4322 return nullptr;
4323 return const_cast<FileEntry *>(*File);
Guy Benyei11169dd2012-12-18 14:30:41 +00004324}
4325
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004326const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4327 size_t *size) {
4328 if (isNotUsableTU(TU)) {
4329 LOG_BAD_TU(TU);
4330 return nullptr;
4331 }
4332
4333 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4334 FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
4335 bool Invalid = true;
Nico Weber04347d82019-04-04 21:06:41 +00004336 const llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid);
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004337 if (Invalid) {
4338 if (size)
4339 *size = 0;
4340 return nullptr;
4341 }
4342 if (size)
4343 *size = buf->getBufferSize();
4344 return buf->getBufferStart();
4345}
4346
Michael Kruse7520cf02020-03-25 09:26:14 -05004347unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004348 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004349 LOG_BAD_TU(TU);
4350 return 0;
4351 }
4352
4353 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00004354 return 0;
4355
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004356 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004357 FileEntry *FEnt = static_cast<FileEntry *>(file);
Michael Kruse7520cf02020-03-25 09:26:14 -05004358 return CXXUnit->getPreprocessor()
4359 .getHeaderSearchInfo()
4360 .isFileMultipleIncludeGuarded(FEnt);
Guy Benyei11169dd2012-12-18 14:30:41 +00004361}
4362
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004363int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
4364 if (!file || !outID)
4365 return 1;
4366
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004367 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00004368 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
4369 outID->data[0] = ID.getDevice();
4370 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004371 outID->data[2] = FEnt->getModificationTime();
4372 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004373}
4374
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00004375int clang_File_isEqual(CXFile file1, CXFile file2) {
4376 if (file1 == file2)
4377 return true;
4378
4379 if (!file1 || !file2)
4380 return false;
4381
4382 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
4383 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
4384 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
4385}
4386
Fangrui Songe46ac5f2018-04-07 20:50:35 +00004387CXString clang_File_tryGetRealPathName(CXFile SFile) {
4388 if (!SFile)
4389 return cxstring::createNull();
4390
4391 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4392 return cxstring::createRef(FEnt->tryGetRealPathName());
4393}
4394
Guy Benyei11169dd2012-12-18 14:30:41 +00004395//===----------------------------------------------------------------------===//
4396// CXCursor Operations.
4397//===----------------------------------------------------------------------===//
4398
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004399static const Decl *getDeclFromExpr(const Stmt *E) {
4400 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 return getDeclFromExpr(CE->getSubExpr());
4402
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004403 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004405 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004407 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004409 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 if (PRE->isExplicitProperty())
4411 return PRE->getExplicitProperty();
4412 // It could be messaging both getter and setter as in:
4413 // ++myobj.myprop;
4414 // in which case prefer to associate the setter since it is less obvious
4415 // from inspecting the source that the setter is going to get called.
4416 if (PRE->isMessagingSetter())
4417 return PRE->getImplicitPropertySetter();
4418 return PRE->getImplicitPropertyGetter();
4419 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004420 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004422 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004423 if (Expr *Src = OVE->getSourceExpr())
4424 return getDeclFromExpr(Src);
Michael Kruse7520cf02020-03-25 09:26:14 -05004425
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004426 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004427 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004428 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 if (!CE->isElidable())
Michael Kruse7520cf02020-03-25 09:26:14 -05004430 return CE->getConstructor();
Richard Smith5179eb72016-06-28 19:03:57 +00004431 if (const CXXInheritedCtorInitExpr *CE =
4432 dyn_cast<CXXInheritedCtorInitExpr>(E))
4433 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004434 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 return OME->getMethodDecl();
4436
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004437 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 return PE->getProtocol();
Michael Kruse7520cf02020-03-25 09:26:14 -05004439 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4440 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004442 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004443 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 isa<ParmVarDecl>(SizeOfPack->getPack()))
4445 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00004446
4447 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004448}
4449
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004450static SourceLocation getLocationFromExpr(const Expr *E) {
4451 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 return getLocationFromExpr(CE->getSubExpr());
4453
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004454 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004455 return /*FIXME:*/ Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004456 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004458 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004460 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004462 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004464 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 return PropRef->getLocation();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004466
4467 return E->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00004468}
4469
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00004470extern "C" {
4471
Michael Kruse7520cf02020-03-25 09:26:14 -05004472unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 CXClientData client_data) {
4474 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4475 /*VisitPreprocessorLast=*/false);
4476 return CursorVis.VisitChildren(parent);
4477}
4478
4479#ifndef __has_feature
4480#define __has_feature(x) 0
4481#endif
4482#if __has_feature(blocks)
Michael Kruse7520cf02020-03-25 09:26:14 -05004483typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4484 CXCursor parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00004485
4486static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004487 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4489 return block(cursor, parent);
4490}
4491#else
4492// If we are compiled with a compiler that doesn't have native blocks support,
Michael Kruse7520cf02020-03-25 09:26:14 -05004493// define and call the block manually, so the
4494typedef struct _CXChildVisitResult {
4495 void *isa;
4496 int flags;
4497 int reserved;
4498 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
4499 CXCursor);
4500} * CXCursorVisitorBlock;
Guy Benyei11169dd2012-12-18 14:30:41 +00004501
4502static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004503 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4505 return block->invoke(block, cursor, parent);
4506}
4507#endif
4508
Guy Benyei11169dd2012-12-18 14:30:41 +00004509unsigned clang_visitChildrenWithBlock(CXCursor parent,
4510 CXCursorVisitorBlock block) {
4511 return clang_visitChildren(parent, visitWithBlock, block);
4512}
4513
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004514static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004516 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004517
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004518 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004520 if (const ObjCPropertyImplDecl *PropImpl =
4521 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004523 return cxstring::createDup(Property->getIdentifier()->getName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004524
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004525 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004526 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004527 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004528
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004529 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004531
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004532 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004533 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004534
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004535 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4537 // and returns different names. NamedDecl returns the class name and
4538 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004539 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004540
4541 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004542 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05004543
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 SmallString<1024> S;
4545 llvm::raw_svector_ostream os(S);
4546 ND->printName(os);
Michael Kruse7520cf02020-03-25 09:26:14 -05004547
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004548 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004549}
4550
4551CXString clang_getCursorSpelling(CXCursor C) {
4552 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004553 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004554
4555 if (clang_isReference(C.kind)) {
4556 switch (C.kind) {
4557 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004558 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004559 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 }
4561 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004562 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004563 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 }
4565 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004566 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004568 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 }
4570 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004571 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004572 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 }
4574 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004575 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 assert(Type && "Missing type decl");
4577
Michael Kruse7520cf02020-03-25 09:26:14 -05004578 return cxstring::createDup(
4579 getCursorContext(C).getTypeDeclType(Type).getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 }
4581 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004582 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 assert(Template && "Missing template decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004584
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004585 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004587
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004589 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 assert(NS && "Missing namespace decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004591
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004592 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 }
4594
4595 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004596 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 assert(Field && "Missing member decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004598
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004599 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 }
4601
4602 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004603 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 assert(Label && "Missing label");
Michael Kruse7520cf02020-03-25 09:26:14 -05004605
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004606 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 }
4608
4609 case CXCursor_OverloadedDeclRef: {
4610 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004611 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4612 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004613 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004614 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004616 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004617 return cxstring::createDup(E->getName().getAsString());
Michael Kruse7520cf02020-03-25 09:26:14 -05004618 OverloadedTemplateStorage *Ovl =
4619 Storage.get<OverloadedTemplateStorage *>();
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004621 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004622 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004624
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004626 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 assert(Var && "Missing variable decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004628
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004629 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004631
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004633 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 }
4635 }
4636
4637 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004638 const Expr *E = getCursorExpr(C);
4639
4640 if (C.kind == CXCursor_ObjCStringLiteral ||
4641 C.kind == CXCursor_StringLiteral) {
4642 const StringLiteral *SLit;
4643 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4644 SLit = OSL->getString();
4645 } else {
4646 SLit = cast<StringLiteral>(E);
4647 }
4648 SmallString<256> Buf;
4649 llvm::raw_svector_ostream OS(Buf);
4650 SLit->outputString(OS);
4651 return cxstring::createDup(OS.str());
4652 }
4653
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004654 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 if (D)
4656 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004657 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 }
4659
4660 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004661 const Stmt *S = getCursorStmt(C);
4662 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004663 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004664
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004665 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004667
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 if (C.kind == CXCursor_MacroExpansion)
Michael Kruse7520cf02020-03-25 09:26:14 -05004669 return cxstring::createRef(
4670 getCursorMacroExpansion(C).getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004671
4672 if (C.kind == CXCursor_MacroDefinition)
Michael Kruse7520cf02020-03-25 09:26:14 -05004673 return cxstring::createRef(
4674 getCursorMacroDefinition(C)->getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004675
4676 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004677 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004678
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 if (clang_isDeclaration(C.kind))
4680 return getDeclSpelling(getCursorDecl(C));
4681
4682 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004683 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004684 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 }
4686
4687 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004688 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004689 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 }
4691
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004692 if (C.kind == CXCursor_PackedAttr) {
4693 return cxstring::createRef("packed");
4694 }
4695
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004696 if (C.kind == CXCursor_VisibilityAttr) {
4697 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4698 switch (AA->getVisibility()) {
4699 case VisibilityAttr::VisibilityType::Default:
4700 return cxstring::createRef("default");
4701 case VisibilityAttr::VisibilityType::Hidden:
4702 return cxstring::createRef("hidden");
4703 case VisibilityAttr::VisibilityType::Protected:
4704 return cxstring::createRef("protected");
4705 }
4706 llvm_unreachable("unknown visibility type");
4707 }
4708
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004709 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004710}
4711
Michael Kruse7520cf02020-03-25 09:26:14 -05004712CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 unsigned options) {
4714 if (clang_Cursor_isNull(C))
4715 return clang_getNullRange();
4716
4717 ASTContext &Ctx = getCursorContext(C);
4718
4719 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004720 const Stmt *S = getCursorStmt(C);
4721 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004722 if (pieceIndex > 0)
4723 return clang_getNullRange();
4724 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4725 }
4726
4727 return clang_getNullRange();
4728 }
4729
4730 if (C.kind == CXCursor_ObjCMessageExpr) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004731 if (const ObjCMessageExpr *ME =
4732 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 if (pieceIndex >= ME->getNumSelectorLocs())
4734 return clang_getNullRange();
4735 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4736 }
4737 }
4738
4739 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4740 C.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004741 if (const ObjCMethodDecl *MD =
4742 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 if (pieceIndex >= MD->getNumSelectorLocs())
4744 return clang_getNullRange();
4745 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4746 }
4747 }
4748
4749 if (C.kind == CXCursor_ObjCCategoryDecl ||
4750 C.kind == CXCursor_ObjCCategoryImplDecl) {
4751 if (pieceIndex > 0)
4752 return clang_getNullRange();
Michael Kruse7520cf02020-03-25 09:26:14 -05004753 if (const ObjCCategoryDecl *CD =
4754 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Michael Kruse7520cf02020-03-25 09:26:14 -05004756 if (const ObjCCategoryImplDecl *CID =
4757 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4759 }
4760
4761 if (C.kind == CXCursor_ModuleImportDecl) {
4762 if (pieceIndex > 0)
4763 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004764 if (const ImportDecl *ImportD =
4765 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4767 if (!Locs.empty())
Michael Kruse7520cf02020-03-25 09:26:14 -05004768 return cxloc::translateSourceRange(
4769 Ctx, SourceRange(Locs.front(), Locs.back()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 }
4771 return clang_getNullRange();
4772 }
4773
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004774 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
Kevin Funk4be5d672016-12-20 09:56:56 +00004775 C.kind == CXCursor_ConversionFunction ||
4776 C.kind == CXCursor_FunctionDecl) {
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004777 if (pieceIndex > 0)
4778 return clang_getNullRange();
4779 if (const FunctionDecl *FD =
4780 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4781 DeclarationNameInfo FunctionName = FD->getNameInfo();
4782 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4783 }
4784 return clang_getNullRange();
4785 }
4786
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 // FIXME: A CXCursor_InclusionDirective should give the location of the
4788 // filename, but we don't keep track of this.
4789
4790 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4791 // but we don't keep track of this.
4792
4793 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4794 // but we don't keep track of this.
4795
4796 // Default handling, give the location of the cursor.
4797
4798 if (pieceIndex > 0)
4799 return clang_getNullRange();
4800
4801 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4802 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4803 return cxloc::translateSourceRange(Ctx, Loc);
4804}
4805
Eli Bendersky44a206f2014-07-31 18:04:56 +00004806CXString clang_Cursor_getMangling(CXCursor C) {
4807 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4808 return cxstring::createEmpty();
4809
Eli Bendersky44a206f2014-07-31 18:04:56 +00004810 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004811 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004812 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4813 return cxstring::createEmpty();
4814
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004815 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004816 ASTNameGenerator ASTNameGen(Ctx);
4817 return cxstring::createDup(ASTNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004818}
4819
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004820CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4821 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4822 return nullptr;
4823
4824 const Decl *D = getCursorDecl(C);
4825 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4826 return nullptr;
4827
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004828 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004829 ASTNameGenerator ASTNameGen(Ctx);
4830 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004831 return cxstring::createSet(Manglings);
4832}
4833
Dave Lee1a532c92017-09-22 16:58:57 +00004834CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
4835 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4836 return nullptr;
4837
4838 const Decl *D = getCursorDecl(C);
4839 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
4840 return nullptr;
4841
4842 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004843 ASTNameGenerator ASTNameGen(Ctx);
4844 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Dave Lee1a532c92017-09-22 16:58:57 +00004845 return cxstring::createSet(Manglings);
4846}
4847
Jonathan Coe45ef5032018-01-16 10:19:56 +00004848CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
4849 if (clang_Cursor_isNull(C))
4850 return 0;
4851 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
4852}
4853
4854void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
4855 if (Policy)
4856 delete static_cast<PrintingPolicy *>(Policy);
4857}
4858
4859unsigned
4860clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
4861 enum CXPrintingPolicyProperty Property) {
4862 if (!Policy)
4863 return 0;
4864
4865 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4866 switch (Property) {
4867 case CXPrintingPolicy_Indentation:
4868 return P->Indentation;
4869 case CXPrintingPolicy_SuppressSpecifiers:
4870 return P->SuppressSpecifiers;
4871 case CXPrintingPolicy_SuppressTagKeyword:
4872 return P->SuppressTagKeyword;
4873 case CXPrintingPolicy_IncludeTagDefinition:
4874 return P->IncludeTagDefinition;
4875 case CXPrintingPolicy_SuppressScope:
4876 return P->SuppressScope;
4877 case CXPrintingPolicy_SuppressUnwrittenScope:
4878 return P->SuppressUnwrittenScope;
4879 case CXPrintingPolicy_SuppressInitializers:
4880 return P->SuppressInitializers;
4881 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4882 return P->ConstantArraySizeAsWritten;
4883 case CXPrintingPolicy_AnonymousTagLocations:
4884 return P->AnonymousTagLocations;
4885 case CXPrintingPolicy_SuppressStrongLifetime:
4886 return P->SuppressStrongLifetime;
4887 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4888 return P->SuppressLifetimeQualifiers;
4889 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4890 return P->SuppressTemplateArgsInCXXConstructors;
4891 case CXPrintingPolicy_Bool:
4892 return P->Bool;
4893 case CXPrintingPolicy_Restrict:
4894 return P->Restrict;
4895 case CXPrintingPolicy_Alignof:
4896 return P->Alignof;
4897 case CXPrintingPolicy_UnderscoreAlignof:
4898 return P->UnderscoreAlignof;
4899 case CXPrintingPolicy_UseVoidForZeroParams:
4900 return P->UseVoidForZeroParams;
4901 case CXPrintingPolicy_TerseOutput:
4902 return P->TerseOutput;
4903 case CXPrintingPolicy_PolishForDeclaration:
4904 return P->PolishForDeclaration;
4905 case CXPrintingPolicy_Half:
4906 return P->Half;
4907 case CXPrintingPolicy_MSWChar:
4908 return P->MSWChar;
4909 case CXPrintingPolicy_IncludeNewlines:
4910 return P->IncludeNewlines;
4911 case CXPrintingPolicy_MSVCFormatting:
4912 return P->MSVCFormatting;
4913 case CXPrintingPolicy_ConstantsAsWritten:
4914 return P->ConstantsAsWritten;
4915 case CXPrintingPolicy_SuppressImplicitBase:
4916 return P->SuppressImplicitBase;
4917 case CXPrintingPolicy_FullyQualifiedName:
4918 return P->FullyQualifiedName;
4919 }
4920
4921 assert(false && "Invalid CXPrintingPolicyProperty");
4922 return 0;
4923}
4924
4925void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
4926 enum CXPrintingPolicyProperty Property,
4927 unsigned Value) {
4928 if (!Policy)
4929 return;
4930
4931 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4932 switch (Property) {
4933 case CXPrintingPolicy_Indentation:
4934 P->Indentation = Value;
4935 return;
4936 case CXPrintingPolicy_SuppressSpecifiers:
4937 P->SuppressSpecifiers = Value;
4938 return;
4939 case CXPrintingPolicy_SuppressTagKeyword:
4940 P->SuppressTagKeyword = Value;
4941 return;
4942 case CXPrintingPolicy_IncludeTagDefinition:
4943 P->IncludeTagDefinition = Value;
4944 return;
4945 case CXPrintingPolicy_SuppressScope:
4946 P->SuppressScope = Value;
4947 return;
4948 case CXPrintingPolicy_SuppressUnwrittenScope:
4949 P->SuppressUnwrittenScope = Value;
4950 return;
4951 case CXPrintingPolicy_SuppressInitializers:
4952 P->SuppressInitializers = Value;
4953 return;
4954 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4955 P->ConstantArraySizeAsWritten = Value;
4956 return;
4957 case CXPrintingPolicy_AnonymousTagLocations:
4958 P->AnonymousTagLocations = Value;
4959 return;
4960 case CXPrintingPolicy_SuppressStrongLifetime:
4961 P->SuppressStrongLifetime = Value;
4962 return;
4963 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4964 P->SuppressLifetimeQualifiers = Value;
4965 return;
4966 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4967 P->SuppressTemplateArgsInCXXConstructors = Value;
4968 return;
4969 case CXPrintingPolicy_Bool:
4970 P->Bool = Value;
4971 return;
4972 case CXPrintingPolicy_Restrict:
4973 P->Restrict = Value;
4974 return;
4975 case CXPrintingPolicy_Alignof:
4976 P->Alignof = Value;
4977 return;
4978 case CXPrintingPolicy_UnderscoreAlignof:
4979 P->UnderscoreAlignof = Value;
4980 return;
4981 case CXPrintingPolicy_UseVoidForZeroParams:
4982 P->UseVoidForZeroParams = Value;
4983 return;
4984 case CXPrintingPolicy_TerseOutput:
4985 P->TerseOutput = Value;
4986 return;
4987 case CXPrintingPolicy_PolishForDeclaration:
4988 P->PolishForDeclaration = Value;
4989 return;
4990 case CXPrintingPolicy_Half:
4991 P->Half = Value;
4992 return;
4993 case CXPrintingPolicy_MSWChar:
4994 P->MSWChar = Value;
4995 return;
4996 case CXPrintingPolicy_IncludeNewlines:
4997 P->IncludeNewlines = Value;
4998 return;
4999 case CXPrintingPolicy_MSVCFormatting:
5000 P->MSVCFormatting = Value;
5001 return;
5002 case CXPrintingPolicy_ConstantsAsWritten:
5003 P->ConstantsAsWritten = Value;
5004 return;
5005 case CXPrintingPolicy_SuppressImplicitBase:
5006 P->SuppressImplicitBase = Value;
5007 return;
5008 case CXPrintingPolicy_FullyQualifiedName:
5009 P->FullyQualifiedName = Value;
5010 return;
5011 }
5012
5013 assert(false && "Invalid CXPrintingPolicyProperty");
5014}
5015
5016CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
5017 if (clang_Cursor_isNull(C))
5018 return cxstring::createEmpty();
5019
5020 if (clang_isDeclaration(C.kind)) {
5021 const Decl *D = getCursorDecl(C);
5022 if (!D)
5023 return cxstring::createEmpty();
5024
5025 SmallString<128> Str;
5026 llvm::raw_svector_ostream OS(Str);
5027 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5028 D->print(OS, UserPolicy ? *UserPolicy
5029 : getCursorContext(C).getPrintingPolicy());
5030
5031 return cxstring::createDup(OS.str());
5032 }
5033
5034 return cxstring::createEmpty();
5035}
5036
Guy Benyei11169dd2012-12-18 14:30:41 +00005037CXString clang_getCursorDisplayName(CXCursor C) {
5038 if (!clang_isDeclaration(C.kind))
5039 return clang_getCursorSpelling(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05005040
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005041 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005043 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005044
5045 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005046 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 D = FunTmpl->getTemplatedDecl();
Michael Kruse7520cf02020-03-25 09:26:14 -05005048
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005049 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 SmallString<64> Str;
5051 llvm::raw_svector_ostream OS(Str);
5052 OS << *Function;
5053 if (Function->getPrimaryTemplate())
5054 OS << "<>";
5055 OS << "(";
5056 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5057 if (I)
5058 OS << ", ";
5059 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5060 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005061
Guy Benyei11169dd2012-12-18 14:30:41 +00005062 if (Function->isVariadic()) {
5063 if (Function->getNumParams())
5064 OS << ", ";
5065 OS << "...";
5066 }
5067 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005068 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005070
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005071 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005072 SmallString<64> Str;
5073 llvm::raw_svector_ostream OS(Str);
5074 OS << *ClassTemplate;
5075 OS << "<";
5076 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5077 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5078 if (I)
5079 OS << ", ";
Michael Kruse7520cf02020-03-25 09:26:14 -05005080
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 NamedDecl *Param = Params->getParam(I);
5082 if (Param->getIdentifier()) {
5083 OS << Param->getIdentifier()->getName();
5084 continue;
5085 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005086
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 // There is no parameter name, which makes this tricky. Try to come up
5088 // with something useful that isn't too long.
5089 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
Saar Razff1e0fc2020-01-15 02:48:42 +02005090 if (const auto *TC = TTP->getTypeConstraint()) {
5091 TC->getConceptNameInfo().printName(OS, Policy);
5092 if (TC->hasExplicitTemplateArgs())
5093 OS << "<...>";
5094 } else
Michael Kruse7520cf02020-03-25 09:26:14 -05005095 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5096 else if (NonTypeTemplateParmDecl *NTTP =
5097 dyn_cast<NonTypeTemplateParmDecl>(Param))
Guy Benyei11169dd2012-12-18 14:30:41 +00005098 OS << NTTP->getType().getAsString(Policy);
5099 else
5100 OS << "template<...> class";
5101 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005102
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005104 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005105 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005106
5107 if (const ClassTemplateSpecializationDecl *ClassSpec =
5108 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 // If the type was explicitly written, use that.
5110 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005111 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Serge Pavlov03e672c2017-11-28 16:14:14 +00005112
Benjamin Kramer9170e912013-02-22 15:46:01 +00005113 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 llvm::raw_svector_ostream OS(Str);
5115 OS << *ClassSpec;
Serge Pavlov03e672c2017-11-28 16:14:14 +00005116 printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
5117 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005118 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005120
Guy Benyei11169dd2012-12-18 14:30:41 +00005121 return clang_getCursorSpelling(C);
5122}
Michael Kruse7520cf02020-03-25 09:26:14 -05005123
Guy Benyei11169dd2012-12-18 14:30:41 +00005124CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5125 switch (Kind) {
5126 case CXCursor_FunctionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005127 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 case CXCursor_TypedefDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005129 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 case CXCursor_EnumDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005131 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 case CXCursor_EnumConstantDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005133 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 case CXCursor_StructDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005135 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 case CXCursor_UnionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005137 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 case CXCursor_ClassDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005139 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 case CXCursor_FieldDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005141 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 case CXCursor_VarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005143 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 case CXCursor_ParmDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005145 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 case CXCursor_ObjCInterfaceDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005147 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 case CXCursor_ObjCCategoryDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005149 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 case CXCursor_ObjCProtocolDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005151 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 case CXCursor_ObjCPropertyDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005153 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 case CXCursor_ObjCIvarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005155 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 case CXCursor_ObjCInstanceMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005157 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 case CXCursor_ObjCClassMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005159 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 case CXCursor_ObjCImplementationDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005161 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 case CXCursor_ObjCCategoryImplDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005163 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 case CXCursor_CXXMethod:
Michael Kruse7520cf02020-03-25 09:26:14 -05005165 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 case CXCursor_UnexposedDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005167 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005169 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 case CXCursor_ObjCProtocolRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005171 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 case CXCursor_ObjCClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005173 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 case CXCursor_TypeRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005175 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 case CXCursor_TemplateRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005177 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005179 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005181 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005183 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005185 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005187 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 case CXCursor_IntegerLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005189 return cxstring::createRef("IntegerLiteral");
Leonard Chandb01c3a2018-06-20 17:19:40 +00005190 case CXCursor_FixedPointLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005191 return cxstring::createRef("FixedPointLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 case CXCursor_FloatingLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005193 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 case CXCursor_ImaginaryLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005195 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 case CXCursor_StringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005197 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 case CXCursor_CharacterLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005199 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 case CXCursor_ParenExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005201 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 case CXCursor_UnaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005203 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 case CXCursor_ArraySubscriptExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005205 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00005206 case CXCursor_OMPArraySectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005207 return cxstring::createRef("OMPArraySectionExpr");
Alexey Bataev7ac9efb2020-02-05 09:33:05 -05005208 case CXCursor_OMPArrayShapingExpr:
5209 return cxstring::createRef("OMPArrayShapingExpr");
Alexey Bataev13a15042020-04-01 15:06:38 -04005210 case CXCursor_OMPIteratorExpr:
5211 return cxstring::createRef("OMPIteratorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 case CXCursor_BinaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005213 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 case CXCursor_CompoundAssignOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005215 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 case CXCursor_ConditionalOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005217 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 case CXCursor_CStyleCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005219 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 case CXCursor_CompoundLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005221 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 case CXCursor_InitListExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005223 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 case CXCursor_AddrLabelExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005225 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 case CXCursor_StmtExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005227 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 case CXCursor_GenericSelectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005229 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 case CXCursor_GNUNullExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005231 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 case CXCursor_CXXStaticCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005233 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 case CXCursor_CXXDynamicCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005235 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 case CXCursor_CXXReinterpretCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005237 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 case CXCursor_CXXConstCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005239 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 case CXCursor_CXXFunctionalCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005241 return cxstring::createRef("CXXFunctionalCastExpr");
Anastasia Stulovaa6a237f2020-05-18 11:02:01 +01005242 case CXCursor_CXXAddrspaceCastExpr:
5243 return cxstring::createRef("CXXAddrspaceCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 case CXCursor_CXXTypeidExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005245 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 case CXCursor_CXXBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005247 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 case CXCursor_CXXNullPtrLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005249 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 case CXCursor_CXXThisExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005251 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 case CXCursor_CXXThrowExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005253 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 case CXCursor_CXXNewExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005255 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 case CXCursor_CXXDeleteExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005257 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 case CXCursor_UnaryExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005259 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 case CXCursor_ObjCStringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005261 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 case CXCursor_ObjCBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005263 return cxstring::createRef("ObjCBoolLiteralExpr");
Erik Pilkington29099de2016-07-16 00:35:23 +00005264 case CXCursor_ObjCAvailabilityCheckExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005265 return cxstring::createRef("ObjCAvailabilityCheckExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00005266 case CXCursor_ObjCSelfExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005267 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 case CXCursor_ObjCEncodeExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005269 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 case CXCursor_ObjCSelectorExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005271 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 case CXCursor_ObjCProtocolExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005273 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 case CXCursor_ObjCBridgedCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005275 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 case CXCursor_BlockExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005277 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 case CXCursor_PackExpansionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005279 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 case CXCursor_SizeOfPackExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005281 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005283 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 case CXCursor_UnexposedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005285 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 case CXCursor_DeclRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005287 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 case CXCursor_MemberRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005289 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005291 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 case CXCursor_ObjCMessageExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005293 return cxstring::createRef("ObjCMessageExpr");
Erik Pilkingtoneee944e2019-07-02 18:28:13 +00005294 case CXCursor_BuiltinBitCastExpr:
5295 return cxstring::createRef("BuiltinBitCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 case CXCursor_UnexposedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005297 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 case CXCursor_DeclStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005299 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 case CXCursor_LabelStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005301 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 case CXCursor_CompoundStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005303 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 case CXCursor_CaseStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005305 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 case CXCursor_DefaultStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005307 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 case CXCursor_IfStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005309 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 case CXCursor_SwitchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005311 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 case CXCursor_WhileStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005313 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 case CXCursor_DoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005315 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 case CXCursor_ForStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005317 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 case CXCursor_GotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005319 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 case CXCursor_IndirectGotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005321 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 case CXCursor_ContinueStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005323 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 case CXCursor_BreakStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005325 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 case CXCursor_ReturnStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005327 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 case CXCursor_GCCAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005329 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 case CXCursor_MSAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005331 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 case CXCursor_ObjCAtTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005333 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 case CXCursor_ObjCAtCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005335 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 case CXCursor_ObjCAtFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005337 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 case CXCursor_ObjCAtThrowStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005339 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 case CXCursor_ObjCAtSynchronizedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005341 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 case CXCursor_ObjCAutoreleasePoolStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005343 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 case CXCursor_ObjCForCollectionStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005345 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 case CXCursor_CXXCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005347 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 case CXCursor_CXXTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005349 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 case CXCursor_CXXForRangeStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005351 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 case CXCursor_SEHTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005353 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 case CXCursor_SEHExceptStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005355 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 case CXCursor_SEHFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005357 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00005358 case CXCursor_SEHLeaveStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005359 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 case CXCursor_NullStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005361 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 case CXCursor_InvalidFile:
Michael Kruse7520cf02020-03-25 09:26:14 -05005363 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005365 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 case CXCursor_NoDeclFound:
Michael Kruse7520cf02020-03-25 09:26:14 -05005367 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00005368 case CXCursor_NotImplemented:
Michael Kruse7520cf02020-03-25 09:26:14 -05005369 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 case CXCursor_TranslationUnit:
Michael Kruse7520cf02020-03-25 09:26:14 -05005371 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 case CXCursor_UnexposedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005373 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 case CXCursor_IBActionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005375 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 case CXCursor_IBOutletAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005377 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 case CXCursor_IBOutletCollectionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005379 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 case CXCursor_CXXFinalAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005381 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005382 case CXCursor_CXXOverrideAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005383 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005384 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005385 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005386 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005387 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005388 case CXCursor_PackedAttr:
5389 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00005390 case CXCursor_PureAttr:
5391 return cxstring::createRef("attribute(pure)");
5392 case CXCursor_ConstAttr:
5393 return cxstring::createRef("attribute(const)");
5394 case CXCursor_NoDuplicateAttr:
5395 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00005396 case CXCursor_CUDAConstantAttr:
5397 return cxstring::createRef("attribute(constant)");
5398 case CXCursor_CUDADeviceAttr:
5399 return cxstring::createRef("attribute(device)");
5400 case CXCursor_CUDAGlobalAttr:
5401 return cxstring::createRef("attribute(global)");
5402 case CXCursor_CUDAHostAttr:
5403 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00005404 case CXCursor_CUDASharedAttr:
5405 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00005406 case CXCursor_VisibilityAttr:
5407 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00005408 case CXCursor_DLLExport:
5409 return cxstring::createRef("attribute(dllexport)");
5410 case CXCursor_DLLImport:
5411 return cxstring::createRef("attribute(dllimport)");
Michael Wud092d0b2018-08-03 05:03:22 +00005412 case CXCursor_NSReturnsRetained:
5413 return cxstring::createRef("attribute(ns_returns_retained)");
5414 case CXCursor_NSReturnsNotRetained:
5415 return cxstring::createRef("attribute(ns_returns_not_retained)");
5416 case CXCursor_NSReturnsAutoreleased:
5417 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5418 case CXCursor_NSConsumesSelf:
5419 return cxstring::createRef("attribute(ns_consumes_self)");
5420 case CXCursor_NSConsumed:
5421 return cxstring::createRef("attribute(ns_consumed)");
5422 case CXCursor_ObjCException:
5423 return cxstring::createRef("attribute(objc_exception)");
5424 case CXCursor_ObjCNSObject:
5425 return cxstring::createRef("attribute(NSObject)");
5426 case CXCursor_ObjCIndependentClass:
5427 return cxstring::createRef("attribute(objc_independent_class)");
5428 case CXCursor_ObjCPreciseLifetime:
5429 return cxstring::createRef("attribute(objc_precise_lifetime)");
5430 case CXCursor_ObjCReturnsInnerPointer:
5431 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5432 case CXCursor_ObjCRequiresSuper:
5433 return cxstring::createRef("attribute(objc_requires_super)");
5434 case CXCursor_ObjCRootClass:
5435 return cxstring::createRef("attribute(objc_root_class)");
5436 case CXCursor_ObjCSubclassingRestricted:
5437 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5438 case CXCursor_ObjCExplicitProtocolImpl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005439 return cxstring::createRef(
5440 "attribute(objc_protocol_requires_explicit_implementation)");
Michael Wud092d0b2018-08-03 05:03:22 +00005441 case CXCursor_ObjCDesignatedInitializer:
5442 return cxstring::createRef("attribute(objc_designated_initializer)");
5443 case CXCursor_ObjCRuntimeVisible:
5444 return cxstring::createRef("attribute(objc_runtime_visible)");
5445 case CXCursor_ObjCBoxable:
5446 return cxstring::createRef("attribute(objc_boxable)");
Michael Wu58d837d2018-08-03 05:55:40 +00005447 case CXCursor_FlagEnum:
5448 return cxstring::createRef("attribute(flag_enum)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005450 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005452 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005454 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005456 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005458 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005460 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005462 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005464 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005466 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005468 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005470 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005472 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005474 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005476 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005478 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005480 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005482 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005484 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005486 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005488 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005490 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005492 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005493 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005494 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005496 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005497 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00005498 return cxstring::createRef("OMPParallelDirective");
5499 case CXCursor_OMPSimdDirective:
5500 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00005501 case CXCursor_OMPForDirective:
5502 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00005503 case CXCursor_OMPForSimdDirective:
5504 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00005505 case CXCursor_OMPSectionsDirective:
5506 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00005507 case CXCursor_OMPSectionDirective:
5508 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00005509 case CXCursor_OMPSingleDirective:
5510 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00005511 case CXCursor_OMPMasterDirective:
5512 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00005513 case CXCursor_OMPCriticalDirective:
5514 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00005515 case CXCursor_OMPParallelForDirective:
5516 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00005517 case CXCursor_OMPParallelForSimdDirective:
5518 return cxstring::createRef("OMPParallelForSimdDirective");
cchen47d60942019-12-05 13:43:48 -05005519 case CXCursor_OMPParallelMasterDirective:
5520 return cxstring::createRef("OMPParallelMasterDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00005521 case CXCursor_OMPParallelSectionsDirective:
5522 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00005523 case CXCursor_OMPTaskDirective:
5524 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00005525 case CXCursor_OMPTaskyieldDirective:
5526 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00005527 case CXCursor_OMPBarrierDirective:
5528 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00005529 case CXCursor_OMPTaskwaitDirective:
5530 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00005531 case CXCursor_OMPTaskgroupDirective:
5532 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00005533 case CXCursor_OMPFlushDirective:
5534 return cxstring::createRef("OMPFlushDirective");
Alexey Bataevc112e942020-02-28 09:52:15 -05005535 case CXCursor_OMPDepobjDirective:
5536 return cxstring::createRef("OMPDepobjDirective");
Alexey Bataevfcba7c32020-03-20 07:03:01 -04005537 case CXCursor_OMPScanDirective:
5538 return cxstring::createRef("OMPScanDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00005539 case CXCursor_OMPOrderedDirective:
5540 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00005541 case CXCursor_OMPAtomicDirective:
5542 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00005543 case CXCursor_OMPTargetDirective:
5544 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00005545 case CXCursor_OMPTargetDataDirective:
5546 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00005547 case CXCursor_OMPTargetEnterDataDirective:
5548 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00005549 case CXCursor_OMPTargetExitDataDirective:
5550 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00005551 case CXCursor_OMPTargetParallelDirective:
5552 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00005553 case CXCursor_OMPTargetParallelForDirective:
5554 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00005555 case CXCursor_OMPTargetUpdateDirective:
5556 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00005557 case CXCursor_OMPTeamsDirective:
5558 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00005559 case CXCursor_OMPCancellationPointDirective:
5560 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00005561 case CXCursor_OMPCancelDirective:
5562 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00005563 case CXCursor_OMPTaskLoopDirective:
5564 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005565 case CXCursor_OMPTaskLoopSimdDirective:
5566 return cxstring::createRef("OMPTaskLoopSimdDirective");
Alexey Bataev60e51c42019-10-10 20:13:02 +00005567 case CXCursor_OMPMasterTaskLoopDirective:
5568 return cxstring::createRef("OMPMasterTaskLoopDirective");
Alexey Bataevb8552ab2019-10-18 16:47:35 +00005569 case CXCursor_OMPMasterTaskLoopSimdDirective:
5570 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
Alexey Bataev5bbcead2019-10-14 17:17:41 +00005571 case CXCursor_OMPParallelMasterTaskLoopDirective:
5572 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
Alexey Bataev14a388f2019-10-25 10:27:13 -04005573 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5574 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00005575 case CXCursor_OMPDistributeDirective:
5576 return cxstring::createRef("OMPDistributeDirective");
Carlo Bertolli9925f152016-06-27 14:55:37 +00005577 case CXCursor_OMPDistributeParallelForDirective:
5578 return cxstring::createRef("OMPDistributeParallelForDirective");
Kelvin Li4a39add2016-07-05 05:00:15 +00005579 case CXCursor_OMPDistributeParallelForSimdDirective:
5580 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
Kelvin Li787f3fc2016-07-06 04:45:38 +00005581 case CXCursor_OMPDistributeSimdDirective:
5582 return cxstring::createRef("OMPDistributeSimdDirective");
Kelvin Lia579b912016-07-14 02:54:56 +00005583 case CXCursor_OMPTargetParallelForSimdDirective:
5584 return cxstring::createRef("OMPTargetParallelForSimdDirective");
Kelvin Li986330c2016-07-20 22:57:10 +00005585 case CXCursor_OMPTargetSimdDirective:
5586 return cxstring::createRef("OMPTargetSimdDirective");
Kelvin Li02532872016-08-05 14:37:37 +00005587 case CXCursor_OMPTeamsDistributeDirective:
5588 return cxstring::createRef("OMPTeamsDistributeDirective");
Kelvin Li4e325f72016-10-25 12:50:55 +00005589 case CXCursor_OMPTeamsDistributeSimdDirective:
5590 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
Kelvin Li579e41c2016-11-30 23:51:03 +00005591 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5592 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
Kelvin Li7ade93f2016-12-09 03:24:30 +00005593 case CXCursor_OMPTeamsDistributeParallelForDirective:
5594 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
Kelvin Libf594a52016-12-17 05:48:59 +00005595 case CXCursor_OMPTargetTeamsDirective:
5596 return cxstring::createRef("OMPTargetTeamsDirective");
Kelvin Li83c451e2016-12-25 04:52:54 +00005597 case CXCursor_OMPTargetTeamsDistributeDirective:
5598 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
Kelvin Li80e8f562016-12-29 22:16:30 +00005599 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5600 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
Kelvin Li1851df52017-01-03 05:23:48 +00005601 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5602 return cxstring::createRef(
5603 "OMPTargetTeamsDistributeParallelForSimdDirective");
Kelvin Lida681182017-01-10 18:08:18 +00005604 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5605 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00005606 case CXCursor_OverloadCandidate:
Michael Kruse7520cf02020-03-25 09:26:14 -05005607 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00005608 case CXCursor_TypeAliasTemplateDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005609 return cxstring::createRef("TypeAliasTemplateDecl");
Olivier Goffart81978012016-06-09 16:15:55 +00005610 case CXCursor_StaticAssert:
Michael Kruse7520cf02020-03-25 09:26:14 -05005611 return cxstring::createRef("StaticAssert");
Olivier Goffartd211c642016-11-04 06:29:27 +00005612 case CXCursor_FriendDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005613 return cxstring::createRef("FriendDecl");
Sven van Haastregtdc2c9302019-02-11 11:00:56 +00005614 case CXCursor_ConvergentAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005615 return cxstring::createRef("attribute(convergent)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005616 case CXCursor_WarnUnusedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005617 return cxstring::createRef("attribute(warn_unused)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005618 case CXCursor_WarnUnusedResultAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005619 return cxstring::createRef("attribute(warn_unused_result)");
Emilio Cobos Alvarezcd741272019-03-13 16:16:54 +00005620 case CXCursor_AlignedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005621 return cxstring::createRef("attribute(aligned)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 }
5623
5624 llvm_unreachable("Unhandled CXCursorKind");
5625}
5626
5627struct GetCursorData {
5628 SourceLocation TokenBeginLoc;
5629 bool PointsAtMacroArgExpansion;
5630 bool VisitedObjCPropertyImplDecl;
5631 SourceLocation VisitedDeclaratorDeclStartLoc;
5632 CXCursor &BestCursor;
5633
Michael Kruse7520cf02020-03-25 09:26:14 -05005634 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5635 CXCursor &outputCursor)
5636 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5638 VisitedObjCPropertyImplDecl = false;
5639 }
5640};
5641
Michael Kruse7520cf02020-03-25 09:26:14 -05005642static enum CXChildVisitResult
5643GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5645 CXCursor *BestCursor = &Data->BestCursor;
5646
5647 // If we point inside a macro argument we should provide info of what the
5648 // token is so use the actual cursor, don't replace it with a macro expansion
5649 // cursor.
5650 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5651 return CXChildVisit_Recurse;
Michael Kruse7520cf02020-03-25 09:26:14 -05005652
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 if (clang_isDeclaration(cursor.kind)) {
5654 // Avoid having the implicit methods override the property decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05005655 if (const ObjCMethodDecl *MD =
5656 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 if (MD->isImplicit())
5658 return CXChildVisit_Break;
5659
Michael Kruse7520cf02020-03-25 09:26:14 -05005660 } else if (const ObjCInterfaceDecl *ID =
5661 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005662 // Check that when we have multiple @class references in the same line,
5663 // that later ones do not override the previous ones.
5664 // If we have:
5665 // @class Foo, Bar;
5666 // source ranges for both start at '@', so 'Bar' will end up overriding
5667 // 'Foo' even though the cursor location was at 'Foo'.
5668 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5669 BestCursor->kind == CXCursor_ObjCClassRef)
Michael Kruse7520cf02020-03-25 09:26:14 -05005670 if (const ObjCInterfaceDecl *PrevID =
5671 dyn_cast_or_null<ObjCInterfaceDecl>(
5672 getCursorDecl(*BestCursor))) {
5673 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5674 !ID->isThisDeclarationADefinition())
5675 return CXChildVisit_Break;
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 }
5677
Michael Kruse7520cf02020-03-25 09:26:14 -05005678 } else if (const DeclaratorDecl *DD =
5679 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5681 // Check that when we have multiple declarators in the same line,
5682 // that later ones do not override the previous ones.
5683 // If we have:
5684 // int Foo, Bar;
5685 // source ranges for both start at 'int', so 'Bar' will end up overriding
5686 // 'Foo' even though the cursor location was at 'Foo'.
5687 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5688 return CXChildVisit_Break;
5689 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5690
Michael Kruse7520cf02020-03-25 09:26:14 -05005691 } else if (const ObjCPropertyImplDecl *PropImp =
5692 dyn_cast_or_null<ObjCPropertyImplDecl>(
5693 getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005694 (void)PropImp;
5695 // Check that when we have multiple @synthesize in the same line,
5696 // that later ones do not override the previous ones.
5697 // If we have:
5698 // @synthesize Foo, Bar;
5699 // source ranges for both start at '@', so 'Bar' will end up overriding
5700 // 'Foo' even though the cursor location was at 'Foo'.
5701 if (Data->VisitedObjCPropertyImplDecl)
5702 return CXChildVisit_Break;
5703 Data->VisitedObjCPropertyImplDecl = true;
5704 }
5705 }
5706
5707 if (clang_isExpression(cursor.kind) &&
5708 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005709 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005710 // Avoid having the cursor of an expression replace the declaration cursor
5711 // when the expression source range overlaps the declaration range.
5712 // This can happen for C++ constructor expressions whose range generally
5713 // include the variable declaration, e.g.:
Michael Kruse7520cf02020-03-25 09:26:14 -05005714 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5715 // cursor.
Guy Benyei11169dd2012-12-18 14:30:41 +00005716 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5717 D->getLocation() == Data->TokenBeginLoc)
5718 return CXChildVisit_Break;
5719 }
5720 }
5721
Michael Kruse7520cf02020-03-25 09:26:14 -05005722 // If our current best cursor is the construction of a temporary object,
5723 // don't replace that cursor with a type reference, because we want
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 // clang_getCursor() to point at the constructor.
5725 if (clang_isExpression(BestCursor->kind) &&
5726 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5727 cursor.kind == CXCursor_TypeRef) {
5728 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5729 // as having the actual point on the type reference.
5730 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5731 return CXChildVisit_Recurse;
5732 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005733
5734 // If we already have an Objective-C superclass reference, don't
5735 // update it further.
5736 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5737 return CXChildVisit_Break;
5738
Guy Benyei11169dd2012-12-18 14:30:41 +00005739 *BestCursor = cursor;
5740 return CXChildVisit_Recurse;
5741}
5742
5743CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005744 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005745 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005747 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005748
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005749 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5751
5752 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5753 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5754
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005755 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005756 CXFile SearchFile;
5757 unsigned SearchLine, SearchColumn;
5758 CXFile ResultFile;
5759 unsigned ResultLine, ResultColumn;
5760 CXString SearchFileName, ResultFileName, KindSpelling, USR;
Michael Kruse7520cf02020-03-25 09:26:14 -05005761 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005763
5764 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5765 nullptr);
Michael Kruse7520cf02020-03-25 09:26:14 -05005766 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5767 nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005768 SearchFileName = clang_getFileName(SearchFile);
5769 ResultFileName = clang_getFileName(ResultFile);
5770 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5771 USR = clang_getCursorUSR(Result);
Michael Kruse7520cf02020-03-25 09:26:14 -05005772 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5773 SearchLine, SearchColumn,
5774 clang_getCString(KindSpelling))
5775 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5776 ResultLine, ResultColumn, clang_getCString(USR),
5777 IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005778 clang_disposeString(SearchFileName);
5779 clang_disposeString(ResultFileName);
5780 clang_disposeString(KindSpelling);
5781 clang_disposeString(USR);
Michael Kruse7520cf02020-03-25 09:26:14 -05005782
Guy Benyei11169dd2012-12-18 14:30:41 +00005783 CXCursor Definition = clang_getCursorDefinition(Result);
5784 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5785 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
Michael Kruse7520cf02020-03-25 09:26:14 -05005786 CXString DefinitionKindSpelling =
5787 clang_getCursorKindSpelling(Definition.kind);
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 CXFile DefinitionFile;
5789 unsigned DefinitionLine, DefinitionColumn;
Michael Kruse7520cf02020-03-25 09:26:14 -05005790 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5791 &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005792 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005793 *Log << llvm::format(" -> %s(%s:%d:%d)",
Michael Kruse7520cf02020-03-25 09:26:14 -05005794 clang_getCString(DefinitionKindSpelling),
5795 clang_getCString(DefinitionFileName), DefinitionLine,
5796 DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005797 clang_disposeString(DefinitionFileName);
5798 clang_disposeString(DefinitionKindSpelling);
5799 }
5800 }
5801
5802 return Result;
5803}
5804
5805CXCursor clang_getNullCursor(void) {
5806 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5807}
5808
5809unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005810 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5811 // can't set consistently. For example, when visiting a DeclStmt we will set
5812 // it but we don't set it on the result of clang_getCursorDefinition for
5813 // a reference of the same declaration.
5814 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5815 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5816 // to provide that kind of info.
5817 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005818 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005819 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005820 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005821
Guy Benyei11169dd2012-12-18 14:30:41 +00005822 return X == Y;
5823}
5824
5825unsigned clang_hashCursor(CXCursor C) {
5826 unsigned Index = 0;
5827 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5828 Index = 1;
Michael Kruse7520cf02020-03-25 09:26:14 -05005829
5830 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5831 std::make_pair(C.kind, C.data[Index]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005832}
5833
5834unsigned clang_isInvalid(enum CXCursorKind K) {
5835 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5836}
5837
5838unsigned clang_isDeclaration(enum CXCursorKind K) {
5839 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005840 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5841}
5842
Ivan Donchevskii08ff9102018-01-04 10:59:50 +00005843unsigned clang_isInvalidDeclaration(CXCursor C) {
5844 if (clang_isDeclaration(C.kind)) {
5845 if (const Decl *D = getCursorDecl(C))
5846 return D->isInvalidDecl();
5847 }
5848
5849 return 0;
5850}
5851
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005852unsigned clang_isReference(enum CXCursorKind K) {
5853 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5854}
Guy Benyei11169dd2012-12-18 14:30:41 +00005855
5856unsigned clang_isExpression(enum CXCursorKind K) {
5857 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5858}
5859
5860unsigned clang_isStatement(enum CXCursorKind K) {
5861 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5862}
5863
5864unsigned clang_isAttribute(enum CXCursorKind K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005865 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005866}
5867
5868unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5869 return K == CXCursor_TranslationUnit;
5870}
5871
5872unsigned clang_isPreprocessing(enum CXCursorKind K) {
5873 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5874}
Michael Kruse7520cf02020-03-25 09:26:14 -05005875
Guy Benyei11169dd2012-12-18 14:30:41 +00005876unsigned clang_isUnexposed(enum CXCursorKind K) {
5877 switch (K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005878 case CXCursor_UnexposedDecl:
5879 case CXCursor_UnexposedExpr:
5880 case CXCursor_UnexposedStmt:
5881 case CXCursor_UnexposedAttr:
5882 return true;
5883 default:
5884 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 }
5886}
5887
Michael Kruse7520cf02020-03-25 09:26:14 -05005888CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005889
5890CXSourceLocation clang_getCursorLocation(CXCursor C) {
5891 if (clang_isReference(C.kind)) {
5892 switch (C.kind) {
5893 case CXCursor_ObjCSuperClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005894 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5895 getCursorObjCSuperClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5897 }
5898
5899 case CXCursor_ObjCProtocolRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005900 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5901 getCursorObjCProtocolRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005902 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5903 }
5904
5905 case CXCursor_ObjCClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005906 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5907 getCursorObjCClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005908 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5909 }
5910
5911 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005912 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005913 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5914 }
5915
5916 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005917 std::pair<const TemplateDecl *, SourceLocation> P =
5918 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005919 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5920 }
5921
5922 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005923 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5925 }
5926
5927 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005928 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005929 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5930 }
5931
5932 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005933 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005934 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5935 }
5936
5937 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005938 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005939 if (!BaseSpec)
5940 return clang_getNullLocation();
Michael Kruse7520cf02020-03-25 09:26:14 -05005941
Guy Benyei11169dd2012-12-18 14:30:41 +00005942 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
Michael Kruse7520cf02020-03-25 09:26:14 -05005943 return cxloc::translateSourceLocation(
5944 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005945
Guy Benyei11169dd2012-12-18 14:30:41 +00005946 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005947 BaseSpec->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005948 }
5949
5950 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005951 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005952 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5953 }
5954
5955 case CXCursor_OverloadedDeclRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005956 return cxloc::translateSourceLocation(
5957 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
Guy Benyei11169dd2012-12-18 14:30:41 +00005958
5959 default:
5960 // FIXME: Need a way to enumerate all non-reference cases.
5961 llvm_unreachable("Missed a reference kind");
5962 }
5963 }
5964
5965 if (clang_isExpression(C.kind))
Michael Kruse7520cf02020-03-25 09:26:14 -05005966 return cxloc::translateSourceLocation(
5967 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
Guy Benyei11169dd2012-12-18 14:30:41 +00005968
5969 if (clang_isStatement(C.kind))
5970 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005971 getCursorStmt(C)->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005972
5973 if (C.kind == CXCursor_PreprocessingDirective) {
5974 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5975 return cxloc::translateSourceLocation(getCursorContext(C), L);
5976 }
5977
5978 if (C.kind == CXCursor_MacroExpansion) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005979 SourceLocation L =
5980 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005981 return cxloc::translateSourceLocation(getCursorContext(C), L);
5982 }
5983
5984 if (C.kind == CXCursor_MacroDefinition) {
5985 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5986 return cxloc::translateSourceLocation(getCursorContext(C), L);
5987 }
5988
5989 if (C.kind == CXCursor_InclusionDirective) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005990 SourceLocation L =
5991 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005992 return cxloc::translateSourceLocation(getCursorContext(C), L);
5993 }
5994
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005995 if (clang_isAttribute(C.kind)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005996 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005997 return cxloc::translateSourceLocation(getCursorContext(C), L);
5998 }
5999
Guy Benyei11169dd2012-12-18 14:30:41 +00006000 if (!clang_isDeclaration(C.kind))
6001 return clang_getNullLocation();
6002
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006003 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006004 if (!D)
6005 return clang_getNullLocation();
6006
6007 SourceLocation Loc = D->getLocation();
6008 // FIXME: Multiple variables declared in a single declaration
6009 // currently lack the information needed to correctly determine their
6010 // ranges when accounting for the type-specifier. We use context
6011 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6012 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006013 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006014 if (!cxcursor::isFirstInDeclGroup(C))
6015 Loc = VD->getLocation();
6016 }
6017
6018 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006019 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006020 Loc = MD->getSelectorStartLoc();
6021
6022 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
6023}
6024
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00006025} // end extern "C"
6026
Guy Benyei11169dd2012-12-18 14:30:41 +00006027CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6028 assert(TU);
6029
6030 // Guard against an invalid SourceLocation, or we may assert in one
6031 // of the following calls.
6032 if (SLoc.isInvalid())
6033 return clang_getNullCursor();
6034
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006035 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006036
6037 // Translate the given source location to make it point at the beginning of
6038 // the token under the cursor.
6039 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6040 CXXUnit->getASTContext().getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05006041
Guy Benyei11169dd2012-12-18 14:30:41 +00006042 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6043 if (SLoc.isValid()) {
6044 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6045 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Michael Kruse7520cf02020-03-25 09:26:14 -05006046 /*VisitPreprocessorLast=*/true,
Guy Benyei11169dd2012-12-18 14:30:41 +00006047 /*VisitIncludedEntities=*/false,
6048 SourceLocation(SLoc));
6049 CursorVis.visitFileRegion();
6050 }
6051
6052 return Result;
6053}
6054
6055static SourceRange getRawCursorExtent(CXCursor C) {
6056 if (clang_isReference(C.kind)) {
6057 switch (C.kind) {
6058 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05006059 return getCursorObjCSuperClassRef(C).second;
Guy Benyei11169dd2012-12-18 14:30:41 +00006060
6061 case CXCursor_ObjCProtocolRef:
6062 return getCursorObjCProtocolRef(C).second;
6063
6064 case CXCursor_ObjCClassRef:
6065 return getCursorObjCClassRef(C).second;
6066
6067 case CXCursor_TypeRef:
6068 return getCursorTypeRef(C).second;
6069
6070 case CXCursor_TemplateRef:
6071 return getCursorTemplateRef(C).second;
6072
6073 case CXCursor_NamespaceRef:
6074 return getCursorNamespaceRef(C).second;
6075
6076 case CXCursor_MemberRef:
6077 return getCursorMemberRef(C).second;
6078
6079 case CXCursor_CXXBaseSpecifier:
6080 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6081
6082 case CXCursor_LabelRef:
6083 return getCursorLabelRef(C).second;
6084
6085 case CXCursor_OverloadedDeclRef:
6086 return getCursorOverloadedDeclRef(C).second;
6087
6088 case CXCursor_VariableRef:
6089 return getCursorVariableRef(C).second;
Michael Kruse7520cf02020-03-25 09:26:14 -05006090
Guy Benyei11169dd2012-12-18 14:30:41 +00006091 default:
6092 // FIXME: Need a way to enumerate all non-reference cases.
6093 llvm_unreachable("Missed a reference kind");
6094 }
6095 }
6096
6097 if (clang_isExpression(C.kind))
6098 return getCursorExpr(C)->getSourceRange();
6099
6100 if (clang_isStatement(C.kind))
6101 return getCursorStmt(C)->getSourceRange();
6102
6103 if (clang_isAttribute(C.kind))
6104 return getCursorAttr(C)->getRange();
6105
6106 if (C.kind == CXCursor_PreprocessingDirective)
6107 return cxcursor::getCursorPreprocessingDirective(C);
6108
6109 if (C.kind == CXCursor_MacroExpansion) {
6110 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006111 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006112 return TU->mapRangeFromPreamble(Range);
6113 }
6114
6115 if (C.kind == CXCursor_MacroDefinition) {
6116 ASTUnit *TU = getCursorASTUnit(C);
6117 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6118 return TU->mapRangeFromPreamble(Range);
6119 }
6120
6121 if (C.kind == CXCursor_InclusionDirective) {
6122 ASTUnit *TU = getCursorASTUnit(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05006123 SourceRange Range =
6124 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006125 return TU->mapRangeFromPreamble(Range);
6126 }
6127
6128 if (C.kind == CXCursor_TranslationUnit) {
6129 ASTUnit *TU = getCursorASTUnit(C);
6130 FileID MainID = TU->getSourceManager().getMainFileID();
6131 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6132 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6133 return SourceRange(Start, End);
6134 }
6135
6136 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006137 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006138 if (!D)
6139 return SourceRange();
6140
6141 SourceRange R = D->getSourceRange();
6142 // FIXME: Multiple variables declared in a single declaration
6143 // currently lack the information needed to correctly determine their
6144 // ranges when accounting for the type-specifier. We use context
6145 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6146 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006147 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006148 if (!cxcursor::isFirstInDeclGroup(C))
6149 R.setBegin(VD->getLocation());
6150 }
6151 return R;
6152 }
6153 return SourceRange();
6154}
6155
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006156/// Retrieves the "raw" cursor extent, which is then extended to include
Guy Benyei11169dd2012-12-18 14:30:41 +00006157/// the decl-specifier-seq for declarations.
6158static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6159 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006160 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006161 if (!D)
6162 return SourceRange();
6163
6164 SourceRange R = D->getSourceRange();
6165
6166 // Adjust the start of the location for declarations preceded by
6167 // declaration specifiers.
6168 SourceLocation StartLoc;
6169 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6170 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006171 StartLoc = TI->getTypeLoc().getBeginLoc();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006172 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006173 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006174 StartLoc = TI->getTypeLoc().getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 }
6176
6177 if (StartLoc.isValid() && R.getBegin().isValid() &&
6178 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6179 R.setBegin(StartLoc);
6180
6181 // FIXME: Multiple variables declared in a single declaration
6182 // currently lack the information needed to correctly determine their
6183 // ranges when accounting for the type-specifier. We use context
6184 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6185 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006186 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006187 if (!cxcursor::isFirstInDeclGroup(C))
6188 R.setBegin(VD->getLocation());
6189 }
6190
Michael Kruse7520cf02020-03-25 09:26:14 -05006191 return R;
Guy Benyei11169dd2012-12-18 14:30:41 +00006192 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006193
Guy Benyei11169dd2012-12-18 14:30:41 +00006194 return getRawCursorExtent(C);
6195}
6196
Guy Benyei11169dd2012-12-18 14:30:41 +00006197CXSourceRange clang_getCursorExtent(CXCursor C) {
6198 SourceRange R = getRawCursorExtent(C);
6199 if (R.isInvalid())
6200 return clang_getNullRange();
6201
6202 return cxloc::translateSourceRange(getCursorContext(C), R);
6203}
6204
6205CXCursor clang_getCursorReferenced(CXCursor C) {
6206 if (clang_isInvalid(C.kind))
6207 return clang_getNullCursor();
6208
6209 CXTranslationUnit tu = getCursorTU(C);
6210 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006211 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006212 if (!D)
6213 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006214 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006215 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006216 if (const ObjCPropertyImplDecl *PropImpl =
6217 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006218 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6219 return MakeCXCursor(Property, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006220
Guy Benyei11169dd2012-12-18 14:30:41 +00006221 return C;
6222 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006223
Guy Benyei11169dd2012-12-18 14:30:41 +00006224 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006225 const Expr *E = getCursorExpr(C);
6226 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00006227 if (D) {
6228 CXCursor declCursor = MakeCXCursor(D, tu);
6229 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6230 declCursor);
6231 return declCursor;
6232 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006233
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006234 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00006235 return MakeCursorOverloadedDeclRef(Ovl, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006236
Guy Benyei11169dd2012-12-18 14:30:41 +00006237 return clang_getNullCursor();
6238 }
6239
6240 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006241 const Stmt *S = getCursorStmt(C);
6242 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00006243 if (LabelDecl *label = Goto->getLabel())
6244 if (LabelStmt *labelS = label->getStmt())
Michael Kruse7520cf02020-03-25 09:26:14 -05006245 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006246
6247 return clang_getNullCursor();
6248 }
Richard Smith66a81862015-05-04 02:25:31 +00006249
Guy Benyei11169dd2012-12-18 14:30:41 +00006250 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00006251 if (const MacroDefinitionRecord *Def =
6252 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006253 return MakeMacroDefinitionCursor(Def, tu);
6254 }
6255
6256 if (!clang_isReference(C.kind))
6257 return clang_getNullCursor();
6258
6259 switch (C.kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006260 case CXCursor_ObjCSuperClassRef:
6261 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006262
Michael Kruse7520cf02020-03-25 09:26:14 -05006263 case CXCursor_ObjCProtocolRef: {
6264 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6265 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6266 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006267
Michael Kruse7520cf02020-03-25 09:26:14 -05006268 return MakeCXCursor(Prot, tu);
6269 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006270
Michael Kruse7520cf02020-03-25 09:26:14 -05006271 case CXCursor_ObjCClassRef: {
6272 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6273 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6274 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006275
Michael Kruse7520cf02020-03-25 09:26:14 -05006276 return MakeCXCursor(Class, tu);
6277 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006278
Michael Kruse7520cf02020-03-25 09:26:14 -05006279 case CXCursor_TypeRef:
6280 return MakeCXCursor(getCursorTypeRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006281
Michael Kruse7520cf02020-03-25 09:26:14 -05006282 case CXCursor_TemplateRef:
6283 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006284
Michael Kruse7520cf02020-03-25 09:26:14 -05006285 case CXCursor_NamespaceRef:
6286 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006287
Michael Kruse7520cf02020-03-25 09:26:14 -05006288 case CXCursor_MemberRef:
6289 return MakeCXCursor(getCursorMemberRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006290
Michael Kruse7520cf02020-03-25 09:26:14 -05006291 case CXCursor_CXXBaseSpecifier: {
6292 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6293 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6294 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006295
Michael Kruse7520cf02020-03-25 09:26:14 -05006296 case CXCursor_LabelRef:
6297 // FIXME: We end up faking the "parent" declaration here because we
6298 // don't want to make CXCursor larger.
6299 return MakeCXCursor(
6300 getCursorLabelRef(C).first,
6301 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006302
Michael Kruse7520cf02020-03-25 09:26:14 -05006303 case CXCursor_OverloadedDeclRef:
6304 return C;
Guy Benyei11169dd2012-12-18 14:30:41 +00006305
Michael Kruse7520cf02020-03-25 09:26:14 -05006306 case CXCursor_VariableRef:
6307 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6308
6309 default:
6310 // We would prefer to enumerate all non-reference cursor kinds here.
6311 llvm_unreachable("Unhandled reference cursor kind");
Guy Benyei11169dd2012-12-18 14:30:41 +00006312 }
6313}
6314
6315CXCursor clang_getCursorDefinition(CXCursor C) {
6316 if (clang_isInvalid(C.kind))
6317 return clang_getNullCursor();
6318
6319 CXTranslationUnit TU = getCursorTU(C);
6320
6321 bool WasReference = false;
6322 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6323 C = clang_getCursorReferenced(C);
6324 WasReference = true;
6325 }
6326
6327 if (C.kind == CXCursor_MacroExpansion)
6328 return clang_getCursorReferenced(C);
6329
6330 if (!clang_isDeclaration(C.kind))
6331 return clang_getNullCursor();
6332
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006333 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006334 if (!D)
6335 return clang_getNullCursor();
6336
6337 switch (D->getKind()) {
6338 // Declaration kinds that don't really separate the notions of
6339 // declaration and definition.
6340 case Decl::Namespace:
6341 case Decl::Typedef:
6342 case Decl::TypeAlias:
6343 case Decl::TypeAliasTemplate:
6344 case Decl::TemplateTypeParm:
6345 case Decl::EnumConstant:
6346 case Decl::Field:
Richard Smithbdb84f32016-07-22 23:36:59 +00006347 case Decl::Binding:
John McCall5e77d762013-04-16 07:28:30 +00006348 case Decl::MSProperty:
Richard Smithbab6df82020-04-11 22:15:29 -07006349 case Decl::MSGuid:
Guy Benyei11169dd2012-12-18 14:30:41 +00006350 case Decl::IndirectField:
6351 case Decl::ObjCIvar:
6352 case Decl::ObjCAtDefsField:
6353 case Decl::ImplicitParam:
6354 case Decl::ParmVar:
6355 case Decl::NonTypeTemplateParm:
6356 case Decl::TemplateTemplateParm:
6357 case Decl::ObjCCategoryImpl:
6358 case Decl::ObjCImplementation:
6359 case Decl::AccessSpec:
6360 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006361 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 case Decl::ObjCPropertyImpl:
6363 case Decl::FileScopeAsm:
6364 case Decl::StaticAssert:
6365 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006366 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006367 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006368 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006369 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006370 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006371 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006372 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006373 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006374 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006375 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006376 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006377 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006378 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006379 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006380 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006381 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006382 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006383 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006384 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006385 return C;
6386
6387 // Declaration kinds that don't make any sense here, but are
6388 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006389 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006390 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006391 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006392 break;
6393
6394 // Declaration kinds for which the definition is not resolvable.
6395 case Decl::UnresolvedUsingTypename:
6396 case Decl::UnresolvedUsingValue:
6397 break;
6398
6399 case Decl::UsingDirective:
6400 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6401 TU);
6402
6403 case Decl::NamespaceAlias:
6404 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6405
6406 case Decl::Enum:
6407 case Decl::Record:
6408 case Decl::CXXRecord:
6409 case Decl::ClassTemplateSpecialization:
6410 case Decl::ClassTemplatePartialSpecialization:
6411 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6412 return MakeCXCursor(Def, TU);
6413 return clang_getNullCursor();
6414
6415 case Decl::Function:
6416 case Decl::CXXMethod:
6417 case Decl::CXXConstructor:
6418 case Decl::CXXDestructor:
6419 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006420 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006422 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006423 return clang_getNullCursor();
6424 }
6425
Larisse Voufo39a1e502013-08-06 01:03:05 +00006426 case Decl::Var:
6427 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006428 case Decl::VarTemplatePartialSpecialization:
6429 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006430 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006431 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006432 return MakeCXCursor(Def, TU);
6433 return clang_getNullCursor();
6434 }
6435
6436 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006437 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006438 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6439 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6440 return clang_getNullCursor();
6441 }
6442
6443 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006444 if (RecordDecl *Def =
6445 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006446 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6447 TU);
6448 return clang_getNullCursor();
6449 }
6450
Larisse Voufo39a1e502013-08-06 01:03:05 +00006451 case Decl::VarTemplate: {
6452 if (VarDecl *Def =
6453 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6454 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6455 return clang_getNullCursor();
6456 }
6457
Guy Benyei11169dd2012-12-18 14:30:41 +00006458 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006459 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6460 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006461
6462 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006463 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006464 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006465 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006466
6467 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006468 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006469 if (Method->isThisDeclarationADefinition())
6470 return C;
6471
6472 // Dig out the method definition in the associated
6473 // @implementation, if we have it.
6474 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006475 if (const ObjCInterfaceDecl *Class =
6476 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006477 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006478 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6479 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006480 if (Def->isThisDeclarationADefinition())
6481 return MakeCXCursor(Def, TU);
6482
6483 return clang_getNullCursor();
6484 }
6485
6486 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006487 if (ObjCCategoryImplDecl *Impl =
6488 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006489 return MakeCXCursor(Impl, TU);
6490 return clang_getNullCursor();
6491
6492 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006493 if (const ObjCProtocolDecl *Def =
6494 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006495 return MakeCXCursor(Def, TU);
6496 return clang_getNullCursor();
6497
6498 case Decl::ObjCInterface: {
6499 // There are two notions of a "definition" for an Objective-C
6500 // class: the interface and its implementation. When we resolved a
6501 // reference to an Objective-C class, produce the @interface as
6502 // the definition; when we were provided with the interface,
6503 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006504 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006505 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006506 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006507 return MakeCXCursor(Def, TU);
6508 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6509 return MakeCXCursor(Impl, TU);
6510 return clang_getNullCursor();
6511 }
6512
6513 case Decl::ObjCProperty:
6514 // FIXME: We don't really know where to find the
6515 // ObjCPropertyImplDecls that implement this property.
6516 return clang_getNullCursor();
6517
6518 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006519 if (const ObjCInterfaceDecl *Class =
6520 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006521 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006522 return MakeCXCursor(Def, TU);
6523
6524 return clang_getNullCursor();
6525
6526 case Decl::Friend:
6527 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6528 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6529 return clang_getNullCursor();
6530
6531 case Decl::FriendTemplate:
6532 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6533 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6534 return clang_getNullCursor();
6535 }
6536
6537 return clang_getNullCursor();
6538}
6539
6540unsigned clang_isCursorDefinition(CXCursor C) {
6541 if (!clang_isDeclaration(C.kind))
6542 return 0;
6543
6544 return clang_getCursorDefinition(C) == C;
6545}
6546
6547CXCursor clang_getCanonicalCursor(CXCursor C) {
6548 if (!clang_isDeclaration(C.kind))
6549 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006550
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006551 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006552 if (const ObjCCategoryImplDecl *CatImplD =
6553 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006554 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6555 return MakeCXCursor(CatD, getCursorTU(C));
6556
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006557 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6558 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006559 return MakeCXCursor(IFD, getCursorTU(C));
6560
6561 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6562 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006563
Guy Benyei11169dd2012-12-18 14:30:41 +00006564 return C;
6565}
6566
6567int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6568 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6569}
Michael Kruse7520cf02020-03-25 09:26:14 -05006570
Guy Benyei11169dd2012-12-18 14:30:41 +00006571unsigned clang_getNumOverloadedDecls(CXCursor C) {
6572 if (C.kind != CXCursor_OverloadedDeclRef)
6573 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006574
Guy Benyei11169dd2012-12-18 14:30:41 +00006575 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006576 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006577 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006578
6579 if (OverloadedTemplateStorage *S =
6580 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006581 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006582
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006583 const Decl *D = Storage.get<const Decl *>();
6584 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006585 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006586
Guy Benyei11169dd2012-12-18 14:30:41 +00006587 return 0;
6588}
6589
6590CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6591 if (cursor.kind != CXCursor_OverloadedDeclRef)
6592 return clang_getNullCursor();
6593
6594 if (index >= clang_getNumOverloadedDecls(cursor))
6595 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006596
Guy Benyei11169dd2012-12-18 14:30:41 +00006597 CXTranslationUnit TU = getCursorTU(cursor);
6598 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006599 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006600 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006601
6602 if (OverloadedTemplateStorage *S =
6603 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006604 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006605
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006606 const Decl *D = Storage.get<const Decl *>();
6607 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006608 // FIXME: This is, unfortunately, linear time.
6609 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6610 std::advance(Pos, index);
6611 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6612 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006613
Guy Benyei11169dd2012-12-18 14:30:41 +00006614 return clang_getNullCursor();
6615}
Michael Kruse7520cf02020-03-25 09:26:14 -05006616
6617void clang_getDefinitionSpellingAndExtent(
6618 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6619 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006620 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006621 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006622 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6623
6624 SourceManager &SM = FD->getASTContext().getSourceManager();
6625 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6626 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6627 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6628 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6629 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6630 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6631}
6632
Guy Benyei11169dd2012-12-18 14:30:41 +00006633CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6634 unsigned PieceIndex) {
6635 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006636
Guy Benyei11169dd2012-12-18 14:30:41 +00006637 switch (C.kind) {
6638 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006639 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006640 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6641 E->getQualifierLoc().getSourceRange());
6642 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006643
Guy Benyei11169dd2012-12-18 14:30:41 +00006644 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006645 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6646 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6647 Pieces =
6648 buildPieces(NameFlags, false, E->getNameInfo(),
6649 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6650 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006651 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006652
Guy Benyei11169dd2012-12-18 14:30:41 +00006653 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006654 if (const CXXOperatorCallExpr *OCE =
6655 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006656 const Expr *Callee = OCE->getCallee();
6657 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006658 Callee = ICE->getSubExpr();
6659
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006660 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006661 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6662 DRE->getQualifierLoc().getSourceRange());
6663 }
6664 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006665
Guy Benyei11169dd2012-12-18 14:30:41 +00006666 default:
6667 break;
6668 }
6669
6670 if (Pieces.empty()) {
6671 if (PieceIndex == 0)
6672 return clang_getCursorExtent(C);
6673 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006674 SourceRange R = Pieces[PieceIndex];
6675 if (R.isValid())
6676 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006677 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006678
Guy Benyei11169dd2012-12-18 14:30:41 +00006679 return clang_getNullRange();
6680}
6681
6682void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006683 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6684 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006685}
6686
Michael Kruse7520cf02020-03-25 09:26:14 -05006687void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006688 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006689 llvm::llvm_execute_on_thread(fn, user_data,
6690 stack_size == 0
6691 ? clang::DesiredStackSize
6692 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006693}
6694
Guy Benyei11169dd2012-12-18 14:30:41 +00006695//===----------------------------------------------------------------------===//
6696// Token-based Operations.
6697//===----------------------------------------------------------------------===//
6698
6699/* CXToken layout:
6700 * int_data[0]: a CXTokenKind
6701 * int_data[1]: starting token location
6702 * int_data[2]: token length
6703 * int_data[3]: reserved
6704 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6705 * otherwise unused.
6706 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006707CXTokenKind clang_getTokenKind(CXToken CXTok) {
6708 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6709}
6710
6711CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6712 switch (clang_getTokenKind(CXTok)) {
6713 case CXToken_Identifier:
6714 case CXToken_Keyword:
6715 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006716 return cxstring::createRef(
6717 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006718
6719 case CXToken_Literal: {
6720 // We have stashed the starting pointer in the ptr_data field. Use it.
6721 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006722 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006723 }
6724
6725 case CXToken_Punctuation:
6726 case CXToken_Comment:
6727 break;
6728 }
6729
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006730 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006731 LOG_BAD_TU(TU);
6732 return cxstring::createEmpty();
6733 }
6734
Guy Benyei11169dd2012-12-18 14:30:41 +00006735 // We have to find the starting buffer pointer the hard way, by
6736 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006737 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006738 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006739 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006740
6741 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006742 std::pair<FileID, unsigned> LocInfo =
6743 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006744 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006745 StringRef Buffer =
6746 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006747 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006748 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006749
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006750 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006751}
6752
6753CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006754 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006755 LOG_BAD_TU(TU);
6756 return clang_getNullLocation();
6757 }
6758
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006759 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006760 if (!CXXUnit)
6761 return clang_getNullLocation();
6762
Michael Kruse7520cf02020-03-25 09:26:14 -05006763 return cxloc::translateSourceLocation(
6764 CXXUnit->getASTContext(),
6765 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006766}
6767
6768CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006769 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006770 LOG_BAD_TU(TU);
6771 return clang_getNullRange();
6772 }
6773
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006774 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006775 if (!CXXUnit)
6776 return clang_getNullRange();
6777
Michael Kruse7520cf02020-03-25 09:26:14 -05006778 return cxloc::translateSourceRange(
6779 CXXUnit->getASTContext(),
6780 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006781}
6782
6783static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6784 SmallVectorImpl<CXToken> &CXTokens) {
6785 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006786 std::pair<FileID, unsigned> BeginLocInfo =
6787 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6788 std::pair<FileID, unsigned> EndLocInfo =
6789 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006790
6791 // Cannot tokenize across files.
6792 if (BeginLocInfo.first != EndLocInfo.first)
6793 return;
6794
6795 // Create a lexer
6796 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006797 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006798 if (Invalid)
6799 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006800
Guy Benyei11169dd2012-12-18 14:30:41 +00006801 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006802 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6803 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006804 Lex.SetCommentRetentionState(true);
6805
6806 // Lex tokens until we hit the end of the range.
6807 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6808 Token Tok;
6809 bool previousWasAt = false;
6810 do {
6811 // Lex the next token
6812 Lex.LexFromRawLexer(Tok);
6813 if (Tok.is(tok::eof))
6814 break;
6815
6816 // Initialize the CXToken.
6817 CXToken CXTok;
6818
6819 // - Common fields
6820 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6821 CXTok.int_data[2] = Tok.getLength();
6822 CXTok.int_data[3] = 0;
6823
6824 // - Kind-specific fields
6825 if (Tok.isLiteral()) {
6826 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006827 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006828 } else if (Tok.is(tok::raw_identifier)) {
6829 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006830 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006831
6832 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6833 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006834 } else {
6835 CXTok.int_data[0] =
6836 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006837 }
6838 CXTok.ptr_data = II;
6839 } else if (Tok.is(tok::comment)) {
6840 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006841 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006842 } else {
6843 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006844 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006845 }
6846 CXTokens.push_back(CXTok);
6847 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006848 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006849}
6850
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006851CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006852 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006853
6854 if (isNotUsableTU(TU)) {
6855 LOG_BAD_TU(TU);
6856 return NULL;
6857 }
6858
6859 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6860 if (!CXXUnit)
6861 return NULL;
6862
6863 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6864 if (Begin.isInvalid())
6865 return NULL;
6866 SourceManager &SM = CXXUnit->getSourceManager();
6867 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006868 DecomposedEnd.second +=
6869 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006870
Michael Kruse7520cf02020-03-25 09:26:14 -05006871 SourceLocation End =
6872 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006873
6874 SmallVector<CXToken, 32> CXTokens;
6875 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6876
6877 if (CXTokens.empty())
6878 return NULL;
6879
6880 CXTokens.resize(1);
6881 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6882
6883 memmove(Token, CXTokens.data(), sizeof(CXToken));
6884 return Token;
6885}
6886
Michael Kruse7520cf02020-03-25 09:26:14 -05006887void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6888 unsigned *NumTokens) {
6889 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006890
Guy Benyei11169dd2012-12-18 14:30:41 +00006891 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006892 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006893 if (NumTokens)
6894 *NumTokens = 0;
6895
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006896 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006897 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006898 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006899 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006900
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006901 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006902 if (!CXXUnit || !Tokens || !NumTokens)
6903 return;
6904
6905 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006906
Guy Benyei11169dd2012-12-18 14:30:41 +00006907 SourceRange R = cxloc::translateCXSourceRange(Range);
6908 if (R.isInvalid())
6909 return;
6910
6911 SmallVector<CXToken, 32> CXTokens;
6912 getTokens(CXXUnit, R, CXTokens);
6913
6914 if (CXTokens.empty())
6915 return;
6916
Serge Pavlov52525732018-02-21 02:02:39 +00006917 *Tokens = static_cast<CXToken *>(
6918 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006919 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6920 *NumTokens = CXTokens.size();
6921}
6922
Michael Kruse7520cf02020-03-25 09:26:14 -05006923void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6924 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006925 free(Tokens);
6926}
6927
Guy Benyei11169dd2012-12-18 14:30:41 +00006928//===----------------------------------------------------------------------===//
6929// Token annotation APIs.
6930//===----------------------------------------------------------------------===//
6931
Guy Benyei11169dd2012-12-18 14:30:41 +00006932static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6933 CXCursor parent,
6934 CXClientData client_data);
6935static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6936 CXClientData client_data);
6937
6938namespace {
6939class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006940 CXToken *Tokens;
6941 CXCursor *Cursors;
6942 unsigned NumTokens;
6943 unsigned TokIdx;
6944 unsigned PreprocessingTokIdx;
6945 CursorVisitor AnnotateVis;
6946 SourceManager &SrcMgr;
6947 bool HasContextSensitiveKeywords;
6948
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006949 struct PostChildrenAction {
6950 CXCursor cursor;
6951 enum Action { Invalid, Ignore, Postpone } action;
6952 };
6953 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6954
Guy Benyei11169dd2012-12-18 14:30:41 +00006955 struct PostChildrenInfo {
6956 CXCursor Cursor;
6957 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006958 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006959 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006960 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006961 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006962 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006963
6964 CXToken &getTok(unsigned Idx) {
6965 assert(Idx < NumTokens);
6966 return Tokens[Idx];
6967 }
6968 const CXToken &getTok(unsigned Idx) const {
6969 assert(Idx < NumTokens);
6970 return Tokens[Idx];
6971 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006972 bool MoreTokens() const { return TokIdx < NumTokens; }
6973 unsigned NextToken() const { return TokIdx; }
6974 void AdvanceToken() { ++TokIdx; }
6975 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006976 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006977 }
6978 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006979 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006980 }
6981 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006982 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006983 }
6984
6985 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006986 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006987 SourceRange);
6988
6989public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006990 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006991 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05006992 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
6993 PreprocessingTokIdx(0),
6994 AnnotateVis(TU, AnnotateTokensVisitor, this,
6995 /*VisitPreprocessorLast=*/true,
6996 /*VisitIncludedEntities=*/false, RegionOfInterest,
6997 /*VisitDeclsOnly=*/false,
6998 AnnotateTokensPostChildrenVisitor),
6999 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
7000 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007001
7002 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
7003 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007004 bool IsIgnoredChildCursor(CXCursor cursor) const;
7005 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
7006
Guy Benyei11169dd2012-12-18 14:30:41 +00007007 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007008 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
7009 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
7010
Guy Benyei11169dd2012-12-18 14:30:41 +00007011 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05007012
7013 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00007014 /// context-sensitive keywords.
7015 bool hasContextSensitiveKeywords() const {
7016 return HasContextSensitiveKeywords;
7017 }
7018
Michael Kruse7520cf02020-03-25 09:26:14 -05007019 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00007020};
Michael Kruse7520cf02020-03-25 09:26:14 -05007021} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00007022
7023void AnnotateTokensWorker::AnnotateTokens() {
7024 // Walk the AST within the region of interest, annotating tokens
7025 // along the way.
7026 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007027}
Guy Benyei11169dd2012-12-18 14:30:41 +00007028
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007029bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7030 if (PostChildrenInfos.empty())
7031 return false;
7032
7033 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7034 if (ChildAction.cursor == cursor &&
7035 ChildAction.action == PostChildrenAction::Ignore) {
7036 return true;
7037 }
7038 }
7039
7040 return false;
7041}
7042
7043const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7044 if (!clang_isExpression(Cursor.kind))
7045 return nullptr;
7046
7047 const Expr *E = getCursorExpr(Cursor);
7048 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7049 const OverloadedOperatorKind Kind = OCE->getOperator();
7050 if (Kind == OO_Call || Kind == OO_Subscript)
7051 return OCE;
7052 }
7053
7054 return nullptr;
7055}
7056
7057AnnotateTokensWorker::PostChildrenActions
7058AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7059 PostChildrenActions actions;
7060
7061 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7062 // visited before the arguments to the operator call. For the Call and
7063 // Subscript operator the range of this DeclRefExpr includes the whole call
7064 // expression, so that all tokens in that range would be mapped to the
7065 // operator function, including the tokens of the arguments. To avoid that,
7066 // ensure to visit this DeclRefExpr as last node.
7067 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7068 const Expr *Callee = OCE->getCallee();
7069 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7070 const Expr *SubExpr = ICE->getSubExpr();
7071 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007072 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007073 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7074
7075 // Visit the DeclRefExpr as last.
7076 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7077 actions.push_back({cxChild, PostChildrenAction::Postpone});
7078
7079 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7080 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7081 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7082 actions.push_back({cxChild, PostChildrenAction::Ignore});
7083 }
7084 }
7085 }
7086
7087 return actions;
7088}
7089
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007090static inline void updateCursorAnnotation(CXCursor &Cursor,
7091 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007092 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007093 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007094 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007095}
7096
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007097/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007098//// between the cursor location and the source range is the same as
7099/// \arg compResult.
7100///
7101/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7102/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007103void AnnotateTokensWorker::annotateAndAdvanceTokens(
7104 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007105 while (MoreTokens()) {
7106 const unsigned I = NextToken();
7107 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007108 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7109 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007110
7111 SourceLocation TokLoc = GetTokenLoc(I);
7112 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007113 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007114 AdvanceToken();
7115 continue;
7116 }
7117 break;
7118 }
7119}
7120
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007121/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007122/// \returns true if it advanced beyond all macro tokens, false otherwise.
7123bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007124 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007125 assert(MoreTokens());
7126 assert(isFunctionMacroToken(NextToken()) &&
7127 "Should be called only for macro arg tokens");
7128
7129 // This works differently than annotateAndAdvanceTokens; because expanded
7130 // macro arguments can have arbitrary translation-unit source order, we do not
7131 // advance the token index one by one until a token fails the range test.
7132 // We only advance once past all of the macro arg tokens if all of them
7133 // pass the range test. If one of them fails we keep the token index pointing
7134 // at the start of the macro arg tokens so that the failing token will be
7135 // annotated by a subsequent annotation try.
7136
7137 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007138
Guy Benyei11169dd2012-12-18 14:30:41 +00007139 unsigned I = NextToken();
7140 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7141 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7142 if (TokLoc.isFileID())
7143 continue; // not macro arg token, it's parens or comma.
7144 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7145 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7146 Cursors[I] = updateC;
7147 } else
7148 atLeastOneCompFail = true;
7149 }
7150
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007151 if (atLeastOneCompFail)
7152 return false;
7153
7154 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7155 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007156}
7157
Michael Kruse7520cf02020-03-25 09:26:14 -05007158enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7159 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007160 SourceRange cursorRange = getRawCursorExtent(cursor);
7161 if (cursorRange.isInvalid())
7162 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007163
7164 if (IsIgnoredChildCursor(cursor))
7165 return CXChildVisit_Continue;
7166
Guy Benyei11169dd2012-12-18 14:30:41 +00007167 if (!HasContextSensitiveKeywords) {
7168 // Objective-C properties can have context-sensitive keywords.
7169 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007170 if (const ObjCPropertyDecl *Property =
7171 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7172 HasContextSensitiveKeywords =
7173 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007174 }
7175 // Objective-C methods can have context-sensitive keywords.
7176 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7177 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007178 if (const ObjCMethodDecl *Method =
7179 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007180 if (Method->getObjCDeclQualifier())
7181 HasContextSensitiveKeywords = true;
7182 else {
David Majnemer59f77922016-06-24 04:05:48 +00007183 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007184 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007185 HasContextSensitiveKeywords = true;
7186 break;
7187 }
7188 }
7189 }
7190 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007191 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007192 // C++ methods can have context-sensitive keywords.
7193 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007194 if (const CXXMethodDecl *Method =
7195 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007196 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7197 HasContextSensitiveKeywords = true;
7198 }
7199 }
7200 // C++ classes can have context-sensitive keywords.
7201 else if (cursor.kind == CXCursor_StructDecl ||
7202 cursor.kind == CXCursor_ClassDecl ||
7203 cursor.kind == CXCursor_ClassTemplate ||
7204 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007205 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007206 if (D->hasAttr<FinalAttr>())
7207 HasContextSensitiveKeywords = true;
7208 }
7209 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007210
7211 // Don't override a property annotation with its getter/setter method.
7212 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7213 parent.kind == CXCursor_ObjCPropertyDecl)
7214 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007215
7216 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007217 // Items in the preprocessing record are kept separate from items in
7218 // declarations, so we keep a separate token index.
7219 unsigned SavedTokIdx = TokIdx;
7220 TokIdx = PreprocessingTokIdx;
7221
7222 // Skip tokens up until we catch up to the beginning of the preprocessing
7223 // entry.
7224 while (MoreTokens()) {
7225 const unsigned I = NextToken();
7226 SourceLocation TokLoc = GetTokenLoc(I);
7227 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7228 case RangeBefore:
7229 AdvanceToken();
7230 continue;
7231 case RangeAfter:
7232 case RangeOverlap:
7233 break;
7234 }
7235 break;
7236 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007237
Guy Benyei11169dd2012-12-18 14:30:41 +00007238 // Look at all of the tokens within this range.
7239 while (MoreTokens()) {
7240 const unsigned I = NextToken();
7241 SourceLocation TokLoc = GetTokenLoc(I);
7242 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7243 case RangeBefore:
7244 llvm_unreachable("Infeasible");
7245 case RangeAfter:
7246 break;
7247 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007248 // For macro expansions, just note where the beginning of the macro
7249 // expansion occurs.
7250 if (cursor.kind == CXCursor_MacroExpansion) {
7251 if (TokLoc == cursorRange.getBegin())
7252 Cursors[I] = cursor;
7253 AdvanceToken();
7254 break;
7255 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007256 // We may have already annotated macro names inside macro definitions.
7257 if (Cursors[I].kind != CXCursor_MacroExpansion)
7258 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007259 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007260 continue;
7261 }
7262 break;
7263 }
7264
7265 // Save the preprocessing token index; restore the non-preprocessing
7266 // token index.
7267 PreprocessingTokIdx = TokIdx;
7268 TokIdx = SavedTokIdx;
7269 return CXChildVisit_Recurse;
7270 }
7271
7272 if (cursorRange.isInvalid())
7273 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007274
7275 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007276 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007277 const enum CXCursorKind K = clang_getCursorKind(parent);
7278 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007279 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7280 // Attributes are annotated out-of-order, skip tokens until we reach it.
7281 clang_isAttribute(cursor.kind))
7282 ? clang_getNullCursor()
7283 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007284
7285 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7286
7287 // Avoid having the cursor of an expression "overwrite" the annotation of the
7288 // variable declaration that it belongs to.
7289 // This can happen for C++ constructor expressions whose range generally
7290 // include the variable declaration, e.g.:
7291 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007292 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007293 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007294 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007295 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007296 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7297 E->getBeginLoc() == D->getLocation() &&
7298 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007299 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007300 AdvanceToken();
7301 }
7302 }
7303 }
7304
7305 // Before recursing into the children keep some state that we are going
7306 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7307 // extra work after the child nodes are visited.
7308 // Note that we don't call VisitChildren here to avoid traversing statements
7309 // code-recursively which can blow the stack.
7310
7311 PostChildrenInfo Info;
7312 Info.Cursor = cursor;
7313 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007314 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007315 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007316 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007317 PostChildrenInfos.push_back(Info);
7318
7319 return CXChildVisit_Recurse;
7320}
7321
7322bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7323 if (PostChildrenInfos.empty())
7324 return false;
7325 const PostChildrenInfo &Info = PostChildrenInfos.back();
7326 if (!clang_equalCursors(Info.Cursor, cursor))
7327 return false;
7328
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007329 HandlePostPonedChildCursors(Info);
7330
Guy Benyei11169dd2012-12-18 14:30:41 +00007331 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7332 const unsigned AfterChildren = NextToken();
7333 SourceRange cursorRange = Info.CursorRange;
7334
7335 // Scan the tokens that are at the end of the cursor, but are not captured
7336 // but the child cursors.
7337 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7338
7339 // Scan the tokens that are at the beginning of the cursor, but are not
7340 // capture by the child cursors.
7341 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7342 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7343 break;
7344
7345 Cursors[I] = cursor;
7346 }
7347
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007348 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7349 // encountered the attribute cursor.
7350 if (clang_isAttribute(cursor.kind))
7351 TokIdx = Info.BeforeReachingCursorIdx;
7352
Guy Benyei11169dd2012-12-18 14:30:41 +00007353 PostChildrenInfos.pop_back();
7354 return false;
7355}
7356
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007357void AnnotateTokensWorker::HandlePostPonedChildCursors(
7358 const PostChildrenInfo &Info) {
7359 for (const auto &ChildAction : Info.ChildActions) {
7360 if (ChildAction.action == PostChildrenAction::Postpone) {
7361 HandlePostPonedChildCursor(ChildAction.cursor,
7362 Info.BeforeChildrenTokenIdx);
7363 }
7364 }
7365}
7366
7367void AnnotateTokensWorker::HandlePostPonedChildCursor(
7368 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007369 unsigned I = StartTokenIndex;
7370
7371 // The bracket tokens of a Call or Subscript operator are mapped to
7372 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7373 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7374 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007375 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7376 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007377 if (clang_Range_isNull(CXRefNameRange))
7378 break; // All ranges handled.
7379
7380 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7381 while (I < NumTokens) {
7382 const SourceLocation TokenLocation = GetTokenLoc(I);
7383 if (!TokenLocation.isValid())
7384 break;
7385
7386 // Adapt the end range, because LocationCompare() reports
7387 // RangeOverlap even for the not-inclusive end location.
7388 const SourceLocation fixedEnd =
7389 RefNameRange.getEnd().getLocWithOffset(-1);
7390 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7391
7392 const RangeComparisonResult ComparisonResult =
7393 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7394
7395 if (ComparisonResult == RangeOverlap) {
7396 Cursors[I++] = Cursor;
7397 } else if (ComparisonResult == RangeBefore) {
7398 ++I; // Not relevant token, check next one.
7399 } else if (ComparisonResult == RangeAfter) {
7400 break; // All tokens updated for current range, check next.
7401 }
7402 }
7403 }
7404}
7405
Guy Benyei11169dd2012-12-18 14:30:41 +00007406static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7407 CXCursor parent,
7408 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007409 return static_cast<AnnotateTokensWorker *>(client_data)
7410 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007411}
7412
7413static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7414 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007415 return static_cast<AnnotateTokensWorker *>(client_data)
7416 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007417}
7418
7419namespace {
7420
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007421/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007422/// and mark tokens that are macro arguments. This info is used by the
7423/// AnnotateTokensWorker.
7424class MarkMacroArgTokensVisitor {
7425 SourceManager &SM;
7426 CXToken *Tokens;
7427 unsigned NumTokens;
7428 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007429
Guy Benyei11169dd2012-12-18 14:30:41 +00007430public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007431 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7432 unsigned numTokens)
7433 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007434
7435 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7436 if (cursor.kind != CXCursor_MacroExpansion)
7437 return CXChildVisit_Continue;
7438
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007439 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007440 if (macroRange.getBegin() == macroRange.getEnd())
7441 return CXChildVisit_Continue; // it's not a function macro.
7442
7443 for (; CurIdx < NumTokens; ++CurIdx) {
7444 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7445 macroRange.getBegin()))
7446 break;
7447 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007448
Guy Benyei11169dd2012-12-18 14:30:41 +00007449 if (CurIdx == NumTokens)
7450 return CXChildVisit_Break;
7451
7452 for (; CurIdx < NumTokens; ++CurIdx) {
7453 SourceLocation tokLoc = getTokenLoc(CurIdx);
7454 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7455 break;
7456
7457 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7458 }
7459
7460 if (CurIdx == NumTokens)
7461 return CXChildVisit_Break;
7462
7463 return CXChildVisit_Continue;
7464 }
7465
7466private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007467 CXToken &getTok(unsigned Idx) {
7468 assert(Idx < NumTokens);
7469 return Tokens[Idx];
7470 }
7471 const CXToken &getTok(unsigned Idx) const {
7472 assert(Idx < NumTokens);
7473 return Tokens[Idx];
7474 }
7475
Guy Benyei11169dd2012-12-18 14:30:41 +00007476 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007477 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007478 }
7479
7480 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7481 // The third field is reserved and currently not used. Use it here
7482 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007483 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007484 }
7485};
7486
7487} // end anonymous namespace
7488
7489static CXChildVisitResult
7490MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7491 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007492 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7493 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007494}
7495
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007496/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007497/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007498static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7499 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007500 if (NextIdx >= NumTokens)
7501 return true;
7502
7503 ++NextIdx;
7504 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007505 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007506}
7507
Guy Benyei11169dd2012-12-18 14:30:41 +00007508static void annotatePreprocessorTokens(CXTranslationUnit TU,
7509 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007510 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007511 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007512 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007513
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007514 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007515 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007516 std::pair<FileID, unsigned> BeginLocInfo =
7517 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7518 std::pair<FileID, unsigned> EndLocInfo =
7519 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007520
7521 if (BeginLocInfo.first != EndLocInfo.first)
7522 return;
7523
7524 StringRef Buffer;
7525 bool Invalid = false;
7526 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7527 if (Buffer.empty() || Invalid)
7528 return;
7529
7530 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007531 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7532 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007533 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007534
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007535 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007536 // Lex tokens in raw mode until we hit the end of the range, to avoid
7537 // entering #includes or expanding macros.
7538 while (true) {
7539 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007540 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7541 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007542 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007543 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007544 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7545
Guy Benyei11169dd2012-12-18 14:30:41 +00007546 reprocess:
7547 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007548 // We have found a preprocessing directive. Annotate the tokens
7549 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007550 //
7551 // FIXME: Some simple tests here could identify macro definitions and
7552 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007553
7554 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007555 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7556 break;
7557
Craig Topper69186e72014-06-08 08:38:04 +00007558 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007559 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007560 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7561 break;
7562
7563 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007564 IdentifierInfo &II =
7565 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007566 SourceLocation MappedTokLoc =
7567 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7568 MI = getMacroInfo(II, MappedTokLoc, TU);
7569 }
7570 }
7571
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007572 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007573 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007574 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7575 finished = true;
7576 break;
7577 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007578 // If we are in a macro definition, check if the token was ever a
7579 // macro name and annotate it if that's the case.
7580 if (MI) {
7581 SourceLocation SaveLoc = Tok.getLocation();
7582 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007583 MacroDefinitionRecord *MacroDef =
7584 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007585 Tok.setLocation(SaveLoc);
7586 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007587 Cursors[NextIdx - 1] =
7588 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007589 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007590 } while (!Tok.isAtStartOfLine());
7591
Michael Kruse7520cf02020-03-25 09:26:14 -05007592 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007593 assert(TokIdx <= LastIdx);
7594 SourceLocation EndLoc =
7595 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7596 CXCursor Cursor =
7597 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7598
7599 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007600 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007601
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007602 if (finished)
7603 break;
7604 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007605 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007606 }
7607}
7608
7609// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007610static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7611 CXToken *Tokens, unsigned NumTokens,
7612 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007613 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007614 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7615 setThreadBackgroundPriority();
7616
7617 // Determine the region of interest, which contains all of the tokens.
7618 SourceRange RegionOfInterest;
7619 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007620 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7621 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7622 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007623
Guy Benyei11169dd2012-12-18 14:30:41 +00007624 // Relex the tokens within the source range to look for preprocessing
7625 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007626 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007627
7628 // If begin location points inside a macro argument, set it to the expansion
7629 // location so we can have the full context when annotating semantically.
7630 {
7631 SourceManager &SM = CXXUnit->getSourceManager();
7632 SourceLocation Loc =
7633 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7634 if (Loc.isMacroID())
7635 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7636 }
7637
Guy Benyei11169dd2012-12-18 14:30:41 +00007638 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7639 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007640 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7641 NumTokens);
7642 CursorVisitor MacroArgMarker(
7643 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7644 /*VisitPreprocessorLast=*/true,
7645 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007646 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7647 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007648
Guy Benyei11169dd2012-12-18 14:30:41 +00007649 // Annotate all of the source locations in the region of interest that map to
7650 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007651 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007652
Guy Benyei11169dd2012-12-18 14:30:41 +00007653 // FIXME: We use a ridiculous stack size here because the data-recursion
7654 // algorithm uses a large stack frame than the non-data recursive version,
7655 // and AnnotationTokensWorker currently transforms the data-recursion
7656 // algorithm back into a traditional recursion by explicitly calling
7657 // VisitChildren(). We will need to remove this explicit recursive call.
7658 W.AnnotateTokens();
7659
7660 // If we ran into any entities that involve context-sensitive keywords,
7661 // take another pass through the tokens to mark them as such.
7662 if (W.hasContextSensitiveKeywords()) {
7663 for (unsigned I = 0; I != NumTokens; ++I) {
7664 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7665 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007666
Guy Benyei11169dd2012-12-18 14:30:41 +00007667 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7668 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007669 if (const ObjCPropertyDecl *Property =
7670 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007671 if (Property->getPropertyAttributesAsWritten() != 0 &&
7672 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007673 .Case("readonly", true)
7674 .Case("assign", true)
7675 .Case("unsafe_unretained", true)
7676 .Case("readwrite", true)
7677 .Case("retain", true)
7678 .Case("copy", true)
7679 .Case("nonatomic", true)
7680 .Case("atomic", true)
7681 .Case("getter", true)
7682 .Case("setter", true)
7683 .Case("strong", true)
7684 .Case("weak", true)
7685 .Case("class", true)
7686 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007687 Tokens[I].int_data[0] = CXToken_Keyword;
7688 }
7689 continue;
7690 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007691
Guy Benyei11169dd2012-12-18 14:30:41 +00007692 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7693 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7694 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7695 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007696 .Case("in", true)
7697 .Case("out", true)
7698 .Case("inout", true)
7699 .Case("oneway", true)
7700 .Case("bycopy", true)
7701 .Case("byref", true)
7702 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007703 Tokens[I].int_data[0] = CXToken_Keyword;
7704 continue;
7705 }
7706
7707 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7708 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7709 Tokens[I].int_data[0] = CXToken_Keyword;
7710 continue;
7711 }
7712 }
7713 }
7714}
7715
Michael Kruse7520cf02020-03-25 09:26:14 -05007716void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7717 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007718 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007719 LOG_BAD_TU(TU);
7720 return;
7721 }
7722 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007723 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007724 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007725 }
7726
7727 LOG_FUNC_SECTION {
7728 *Log << TU << ' ';
7729 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007730 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007731 *Log << clang_getRange(bloc, eloc);
7732 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007733
7734 // Any token we don't specifically annotate will have a NULL cursor.
7735 CXCursor C = clang_getNullCursor();
7736 for (unsigned I = 0; I != NumTokens; ++I)
7737 Cursors[I] = C;
7738
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007739 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007740 if (!CXXUnit)
7741 return;
7742
7743 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007744
7745 auto AnnotateTokensImpl = [=]() {
7746 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7747 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007748 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007749 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007750 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7751 }
7752}
7753
Guy Benyei11169dd2012-12-18 14:30:41 +00007754//===----------------------------------------------------------------------===//
7755// Operations for querying linkage of a cursor.
7756//===----------------------------------------------------------------------===//
7757
Guy Benyei11169dd2012-12-18 14:30:41 +00007758CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7759 if (!clang_isDeclaration(cursor.kind))
7760 return CXLinkage_Invalid;
7761
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007762 const Decl *D = cxcursor::getCursorDecl(cursor);
7763 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007764 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007765 case NoLinkage:
7766 case VisibleNoLinkage:
7767 return CXLinkage_NoLinkage;
7768 case ModuleInternalLinkage:
7769 case InternalLinkage:
7770 return CXLinkage_Internal;
7771 case UniqueExternalLinkage:
7772 return CXLinkage_UniqueExternal;
7773 case ModuleLinkage:
7774 case ExternalLinkage:
7775 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007776 };
7777
7778 return CXLinkage_Invalid;
7779}
Guy Benyei11169dd2012-12-18 14:30:41 +00007780
7781//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007782// Operations for querying visibility of a cursor.
7783//===----------------------------------------------------------------------===//
7784
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007785CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7786 if (!clang_isDeclaration(cursor.kind))
7787 return CXVisibility_Invalid;
7788
7789 const Decl *D = cxcursor::getCursorDecl(cursor);
7790 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7791 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007792 case HiddenVisibility:
7793 return CXVisibility_Hidden;
7794 case ProtectedVisibility:
7795 return CXVisibility_Protected;
7796 case DefaultVisibility:
7797 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007798 };
7799
7800 return CXVisibility_Invalid;
7801}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007802
7803//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007804// Operations for querying language of a cursor.
7805//===----------------------------------------------------------------------===//
7806
7807static CXLanguageKind getDeclLanguage(const Decl *D) {
7808 if (!D)
7809 return CXLanguage_C;
7810
7811 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007812 default:
7813 break;
7814 case Decl::ImplicitParam:
7815 case Decl::ObjCAtDefsField:
7816 case Decl::ObjCCategory:
7817 case Decl::ObjCCategoryImpl:
7818 case Decl::ObjCCompatibleAlias:
7819 case Decl::ObjCImplementation:
7820 case Decl::ObjCInterface:
7821 case Decl::ObjCIvar:
7822 case Decl::ObjCMethod:
7823 case Decl::ObjCProperty:
7824 case Decl::ObjCPropertyImpl:
7825 case Decl::ObjCProtocol:
7826 case Decl::ObjCTypeParam:
7827 return CXLanguage_ObjC;
7828 case Decl::CXXConstructor:
7829 case Decl::CXXConversion:
7830 case Decl::CXXDestructor:
7831 case Decl::CXXMethod:
7832 case Decl::CXXRecord:
7833 case Decl::ClassTemplate:
7834 case Decl::ClassTemplatePartialSpecialization:
7835 case Decl::ClassTemplateSpecialization:
7836 case Decl::Friend:
7837 case Decl::FriendTemplate:
7838 case Decl::FunctionTemplate:
7839 case Decl::LinkageSpec:
7840 case Decl::Namespace:
7841 case Decl::NamespaceAlias:
7842 case Decl::NonTypeTemplateParm:
7843 case Decl::StaticAssert:
7844 case Decl::TemplateTemplateParm:
7845 case Decl::TemplateTypeParm:
7846 case Decl::UnresolvedUsingTypename:
7847 case Decl::UnresolvedUsingValue:
7848 case Decl::Using:
7849 case Decl::UsingDirective:
7850 case Decl::UsingShadow:
7851 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007852 }
7853
7854 return CXLanguage_C;
7855}
7856
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007857static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7858 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007859 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007860
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007861 switch (D->getAvailability()) {
7862 case AR_Available:
7863 case AR_NotYetIntroduced:
7864 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007865 return getCursorAvailabilityForDecl(
7866 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007867 return CXAvailability_Available;
7868
7869 case AR_Deprecated:
7870 return CXAvailability_Deprecated;
7871
7872 case AR_Unavailable:
7873 return CXAvailability_NotAvailable;
7874 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007875
7876 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007877}
7878
Guy Benyei11169dd2012-12-18 14:30:41 +00007879enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7880 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007881 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7882 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007883
7884 return CXAvailability_Available;
7885}
7886
7887static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007888 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007889 if (In.empty())
7890 return Out;
7891
7892 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007893
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007894 Optional<unsigned> Minor = In.getMinor();
7895 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007896 Out.Minor = *Minor;
7897 else
7898 return Out;
7899
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007900 Optional<unsigned> Subminor = In.getSubminor();
7901 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007902 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007903
Guy Benyei11169dd2012-12-18 14:30:41 +00007904 return Out;
7905}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007906
Alex Lorenz1345ea22017-06-12 19:06:30 +00007907static void getCursorPlatformAvailabilityForDecl(
7908 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7909 int *always_unavailable, CXString *unavailable_message,
7910 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007911 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007912 for (auto A : D->attrs()) {
7913 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007914 HadAvailAttr = true;
7915 if (always_deprecated)
7916 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007917 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007918 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007919 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007920 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007921 continue;
7922 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007923
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007924 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007925 HadAvailAttr = true;
7926 if (always_unavailable)
7927 *always_unavailable = 1;
7928 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007929 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007930 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7931 }
7932 continue;
7933 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007934
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007935 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007936 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007937 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007938 }
7939 }
7940
7941 if (!HadAvailAttr)
7942 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7943 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007944 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7945 deprecated_message, always_unavailable, unavailable_message,
7946 AvailabilityAttrs);
7947
7948 if (AvailabilityAttrs.empty())
7949 return;
7950
Michael Kruse7520cf02020-03-25 09:26:14 -05007951 llvm::sort(
7952 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7953 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7954 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007955 ASTContext &Ctx = D->getASTContext();
7956 auto It = std::unique(
7957 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7958 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7959 if (LHS->getPlatform() != RHS->getPlatform())
7960 return false;
7961
7962 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7963 LHS->getDeprecated() == RHS->getDeprecated() &&
7964 LHS->getObsoleted() == RHS->getObsoleted() &&
7965 LHS->getMessage() == RHS->getMessage() &&
7966 LHS->getReplacement() == RHS->getReplacement())
7967 return true;
7968
7969 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
7970 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
7971 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
7972 return false;
7973
7974 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
7975 LHS->setIntroduced(Ctx, RHS->getIntroduced());
7976
7977 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
7978 LHS->setDeprecated(Ctx, RHS->getDeprecated());
7979 if (LHS->getMessage().empty())
7980 LHS->setMessage(Ctx, RHS->getMessage());
7981 if (LHS->getReplacement().empty())
7982 LHS->setReplacement(Ctx, RHS->getReplacement());
7983 }
7984
7985 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
7986 LHS->setObsoleted(Ctx, RHS->getObsoleted());
7987 if (LHS->getMessage().empty())
7988 LHS->setMessage(Ctx, RHS->getMessage());
7989 if (LHS->getReplacement().empty())
7990 LHS->setReplacement(Ctx, RHS->getReplacement());
7991 }
7992
7993 return true;
7994 });
7995 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007996}
7997
Alex Lorenz1345ea22017-06-12 19:06:30 +00007998int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00007999 CXString *deprecated_message,
8000 int *always_unavailable,
8001 CXString *unavailable_message,
8002 CXPlatformAvailability *availability,
8003 int availability_size) {
8004 if (always_deprecated)
8005 *always_deprecated = 0;
8006 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008007 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00008008 if (always_unavailable)
8009 *always_unavailable = 0;
8010 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008011 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008012
Guy Benyei11169dd2012-12-18 14:30:41 +00008013 if (!clang_isDeclaration(cursor.kind))
8014 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008015
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008016 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00008017 if (!D)
8018 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008019
Alex Lorenz1345ea22017-06-12 19:06:30 +00008020 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
8021 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8022 always_unavailable, unavailable_message,
8023 AvailabilityAttrs);
8024 for (const auto &Avail :
8025 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8026 .take_front(availability_size))) {
8027 availability[Avail.index()].Platform =
8028 cxstring::createDup(Avail.value()->getPlatform()->getName());
8029 availability[Avail.index()].Introduced =
8030 convertVersion(Avail.value()->getIntroduced());
8031 availability[Avail.index()].Deprecated =
8032 convertVersion(Avail.value()->getDeprecated());
8033 availability[Avail.index()].Obsoleted =
8034 convertVersion(Avail.value()->getObsoleted());
8035 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8036 availability[Avail.index()].Message =
8037 cxstring::createDup(Avail.value()->getMessage());
8038 }
8039
8040 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008041}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008042
Guy Benyei11169dd2012-12-18 14:30:41 +00008043void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8044 clang_disposeString(availability->Platform);
8045 clang_disposeString(availability->Message);
8046}
8047
8048CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8049 if (clang_isDeclaration(cursor.kind))
8050 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8051
8052 return CXLanguage_Invalid;
8053}
8054
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008055CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8056 const Decl *D = cxcursor::getCursorDecl(cursor);
8057 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8058 switch (VD->getTLSKind()) {
8059 case VarDecl::TLS_None:
8060 return CXTLS_None;
8061 case VarDecl::TLS_Dynamic:
8062 return CXTLS_Dynamic;
8063 case VarDecl::TLS_Static:
8064 return CXTLS_Static;
8065 }
8066 }
8067
8068 return CXTLS_None;
8069}
8070
Michael Kruse7520cf02020-03-25 09:26:14 -05008071/// If the given cursor is the "templated" declaration
8072/// describing a class or function template, return the class or
8073/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008074static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008075 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008076 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008077
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008078 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008079 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8080 return FunTmpl;
8081
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008082 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008083 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8084 return ClassTmpl;
8085
8086 return D;
8087}
8088
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008089enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8090 StorageClass sc = SC_None;
8091 const Decl *D = getCursorDecl(C);
8092 if (D) {
8093 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8094 sc = FD->getStorageClass();
8095 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8096 sc = VD->getStorageClass();
8097 } else {
8098 return CX_SC_Invalid;
8099 }
8100 } else {
8101 return CX_SC_Invalid;
8102 }
8103 switch (sc) {
8104 case SC_None:
8105 return CX_SC_None;
8106 case SC_Extern:
8107 return CX_SC_Extern;
8108 case SC_Static:
8109 return CX_SC_Static;
8110 case SC_PrivateExtern:
8111 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008112 case SC_Auto:
8113 return CX_SC_Auto;
8114 case SC_Register:
8115 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008116 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008117 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008118}
8119
Guy Benyei11169dd2012-12-18 14:30:41 +00008120CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8121 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008122 if (const Decl *D = getCursorDecl(cursor)) {
8123 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008124 if (!DC)
8125 return clang_getNullCursor();
8126
Michael Kruse7520cf02020-03-25 09:26:14 -05008127 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008128 getCursorTU(cursor));
8129 }
8130 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008131
Guy Benyei11169dd2012-12-18 14:30:41 +00008132 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008133 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008134 return MakeCXCursor(D, getCursorTU(cursor));
8135 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008136
Guy Benyei11169dd2012-12-18 14:30:41 +00008137 return clang_getNullCursor();
8138}
8139
8140CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8141 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008142 if (const Decl *D = getCursorDecl(cursor)) {
8143 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008144 if (!DC)
8145 return clang_getNullCursor();
8146
Michael Kruse7520cf02020-03-25 09:26:14 -05008147 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008148 getCursorTU(cursor));
8149 }
8150 }
8151
Michael Kruse7520cf02020-03-25 09:26:14 -05008152 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008153 // statement or expression, so we return nothing.
8154 return clang_getNullCursor();
8155}
8156
8157CXFile clang_getIncludedFile(CXCursor cursor) {
8158 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008159 return nullptr;
8160
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008161 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008162 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008163}
8164
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008165unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8166 if (C.kind != CXCursor_ObjCPropertyDecl)
8167 return CXObjCPropertyAttr_noattr;
8168
8169 unsigned Result = CXObjCPropertyAttr_noattr;
8170 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008171 ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008172
Michael Kruse7520cf02020-03-25 09:26:14 -05008173#define SET_CXOBJCPROP_ATTR(A) \
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008174 if (Attr & ObjCPropertyAttribute::kind_##A) \
Michael Kruse7520cf02020-03-25 09:26:14 -05008175 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008176 SET_CXOBJCPROP_ATTR(readonly);
8177 SET_CXOBJCPROP_ATTR(getter);
8178 SET_CXOBJCPROP_ATTR(assign);
8179 SET_CXOBJCPROP_ATTR(readwrite);
8180 SET_CXOBJCPROP_ATTR(retain);
8181 SET_CXOBJCPROP_ATTR(copy);
8182 SET_CXOBJCPROP_ATTR(nonatomic);
8183 SET_CXOBJCPROP_ATTR(setter);
8184 SET_CXOBJCPROP_ATTR(atomic);
8185 SET_CXOBJCPROP_ATTR(weak);
8186 SET_CXOBJCPROP_ATTR(strong);
8187 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008188 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008189#undef SET_CXOBJCPROP_ATTR
8190
8191 return Result;
8192}
8193
Michael Wu6e88f532018-08-03 05:38:29 +00008194CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8195 if (C.kind != CXCursor_ObjCPropertyDecl)
8196 return cxstring::createNull();
8197
8198 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8199 Selector sel = PD->getGetterName();
8200 if (sel.isNull())
8201 return cxstring::createNull();
8202
8203 return cxstring::createDup(sel.getAsString());
8204}
8205
8206CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8207 if (C.kind != CXCursor_ObjCPropertyDecl)
8208 return cxstring::createNull();
8209
8210 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8211 Selector sel = PD->getSetterName();
8212 if (sel.isNull())
8213 return cxstring::createNull();
8214
8215 return cxstring::createDup(sel.getAsString());
8216}
8217
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008218unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8219 if (!clang_isDeclaration(C.kind))
8220 return CXObjCDeclQualifier_None;
8221
8222 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8223 const Decl *D = getCursorDecl(C);
8224 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8225 QT = MD->getObjCDeclQualifier();
8226 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8227 QT = PD->getObjCDeclQualifier();
8228 if (QT == Decl::OBJC_TQ_None)
8229 return CXObjCDeclQualifier_None;
8230
8231 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008232 if (QT & Decl::OBJC_TQ_In)
8233 Result |= CXObjCDeclQualifier_In;
8234 if (QT & Decl::OBJC_TQ_Inout)
8235 Result |= CXObjCDeclQualifier_Inout;
8236 if (QT & Decl::OBJC_TQ_Out)
8237 Result |= CXObjCDeclQualifier_Out;
8238 if (QT & Decl::OBJC_TQ_Bycopy)
8239 Result |= CXObjCDeclQualifier_Bycopy;
8240 if (QT & Decl::OBJC_TQ_Byref)
8241 Result |= CXObjCDeclQualifier_Byref;
8242 if (QT & Decl::OBJC_TQ_Oneway)
8243 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008244
8245 return Result;
8246}
8247
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008248unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8249 if (!clang_isDeclaration(C.kind))
8250 return 0;
8251
8252 const Decl *D = getCursorDecl(C);
8253 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8254 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8255 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8256 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8257
8258 return 0;
8259}
8260
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008261unsigned clang_Cursor_isVariadic(CXCursor C) {
8262 if (!clang_isDeclaration(C.kind))
8263 return 0;
8264
8265 const Decl *D = getCursorDecl(C);
8266 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8267 return FD->isVariadic();
8268 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8269 return MD->isVariadic();
8270
8271 return 0;
8272}
8273
Michael Kruse7520cf02020-03-25 09:26:14 -05008274unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8275 CXString *definedIn,
8276 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008277 if (!clang_isDeclaration(C.kind))
8278 return 0;
8279
8280 const Decl *D = getCursorDecl(C);
8281
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008282 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008283 if (language)
8284 *language = cxstring::createDup(attr->getLanguage());
8285 if (definedIn)
8286 *definedIn = cxstring::createDup(attr->getDefinedIn());
8287 if (isGenerated)
8288 *isGenerated = attr->getGeneratedDeclaration();
8289 return 1;
8290 }
8291 return 0;
8292}
8293
Guy Benyei11169dd2012-12-18 14:30:41 +00008294CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8295 if (!clang_isDeclaration(C.kind))
8296 return clang_getNullRange();
8297
8298 const Decl *D = getCursorDecl(C);
8299 ASTContext &Context = getCursorContext(C);
8300 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8301 if (!RC)
8302 return clang_getNullRange();
8303
8304 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8305}
8306
8307CXString clang_Cursor_getRawCommentText(CXCursor C) {
8308 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008309 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008310
8311 const Decl *D = getCursorDecl(C);
8312 ASTContext &Context = getCursorContext(C);
8313 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008314 StringRef RawText =
8315 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008316
8317 // Don't duplicate the string because RawText points directly into source
8318 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008319 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008320}
8321
8322CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8323 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008324 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008325
8326 const Decl *D = getCursorDecl(C);
8327 const ASTContext &Context = getCursorContext(C);
8328 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8329
8330 if (RC) {
8331 StringRef BriefText = RC->getBriefText(Context);
8332
8333 // Don't duplicate the string because RawComment ensures that this memory
8334 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008335 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008336 }
8337
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008338 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008339}
8340
Guy Benyei11169dd2012-12-18 14:30:41 +00008341CXModule clang_Cursor_getModule(CXCursor C) {
8342 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008343 if (const ImportDecl *ImportD =
8344 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008345 return ImportD->getImportedModule();
8346 }
8347
Craig Topper69186e72014-06-08 08:38:04 +00008348 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008349}
8350
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008351CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8352 if (isNotUsableTU(TU)) {
8353 LOG_BAD_TU(TU);
8354 return nullptr;
8355 }
8356 if (!File)
8357 return nullptr;
8358 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008359
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008360 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8361 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8362 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008363
Richard Smithfeb54b62014-10-23 02:01:19 +00008364 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008365}
8366
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008367CXFile clang_Module_getASTFile(CXModule CXMod) {
8368 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008369 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008370 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008371 return const_cast<FileEntry *>(Mod->getASTFile());
8372}
8373
Guy Benyei11169dd2012-12-18 14:30:41 +00008374CXModule clang_Module_getParent(CXModule CXMod) {
8375 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008376 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008377 Module *Mod = static_cast<Module *>(CXMod);
Guy Benyei11169dd2012-12-18 14:30:41 +00008378 return Mod->Parent;
8379}
8380
8381CXString clang_Module_getName(CXModule CXMod) {
8382 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008383 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008384 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008385 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008386}
8387
8388CXString clang_Module_getFullName(CXModule CXMod) {
8389 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008390 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008391 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008392 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008393}
8394
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008395int clang_Module_isSystem(CXModule CXMod) {
8396 if (!CXMod)
8397 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008398 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008399 return Mod->IsSystem;
8400}
8401
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008402unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8403 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008404 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008405 LOG_BAD_TU(TU);
8406 return 0;
8407 }
8408 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008409 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008410 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008411 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8412 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8413 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008414}
8415
Michael Kruse7520cf02020-03-25 09:26:14 -05008416CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8417 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008418 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008419 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008420 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008421 }
8422 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008423 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008424 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008425 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008426
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008427 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8428 if (Index < TopHeaders.size())
8429 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008430
Craig Topper69186e72014-06-08 08:38:04 +00008431 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008432}
8433
Guy Benyei11169dd2012-12-18 14:30:41 +00008434//===----------------------------------------------------------------------===//
8435// C++ AST instrospection.
8436//===----------------------------------------------------------------------===//
8437
Jonathan Coe29565352016-04-27 12:48:25 +00008438unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8439 if (!clang_isDeclaration(C.kind))
8440 return 0;
8441
8442 const Decl *D = cxcursor::getCursorDecl(C);
8443 const CXXConstructorDecl *Constructor =
8444 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8445 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8446}
8447
8448unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8449 if (!clang_isDeclaration(C.kind))
8450 return 0;
8451
8452 const Decl *D = cxcursor::getCursorDecl(C);
8453 const CXXConstructorDecl *Constructor =
8454 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8455 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8456}
8457
8458unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8459 if (!clang_isDeclaration(C.kind))
8460 return 0;
8461
8462 const Decl *D = cxcursor::getCursorDecl(C);
8463 const CXXConstructorDecl *Constructor =
8464 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8465 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8466}
8467
8468unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8469 if (!clang_isDeclaration(C.kind))
8470 return 0;
8471
8472 const Decl *D = cxcursor::getCursorDecl(C);
8473 const CXXConstructorDecl *Constructor =
8474 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8475 // Passing 'false' excludes constructors marked 'explicit'.
8476 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8477}
8478
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008479unsigned clang_CXXField_isMutable(CXCursor C) {
8480 if (!clang_isDeclaration(C.kind))
8481 return 0;
8482
8483 if (const auto D = cxcursor::getCursorDecl(C))
8484 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8485 return FD->isMutable() ? 1 : 0;
8486 return 0;
8487}
8488
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008489unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8490 if (!clang_isDeclaration(C.kind))
8491 return 0;
8492
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008493 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008494 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008495 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008496 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8497}
8498
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008499unsigned clang_CXXMethod_isConst(CXCursor C) {
8500 if (!clang_isDeclaration(C.kind))
8501 return 0;
8502
8503 const Decl *D = cxcursor::getCursorDecl(C);
8504 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008505 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008506 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008507}
8508
Jonathan Coe29565352016-04-27 12:48:25 +00008509unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8510 if (!clang_isDeclaration(C.kind))
8511 return 0;
8512
8513 const Decl *D = cxcursor::getCursorDecl(C);
8514 const CXXMethodDecl *Method =
8515 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8516 return (Method && Method->isDefaulted()) ? 1 : 0;
8517}
8518
Guy Benyei11169dd2012-12-18 14:30:41 +00008519unsigned clang_CXXMethod_isStatic(CXCursor C) {
8520 if (!clang_isDeclaration(C.kind))
8521 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008522
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008523 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008524 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008525 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008526 return (Method && Method->isStatic()) ? 1 : 0;
8527}
8528
8529unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8530 if (!clang_isDeclaration(C.kind))
8531 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008532
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008533 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008534 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008535 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008536 return (Method && Method->isVirtual()) ? 1 : 0;
8537}
Guy Benyei11169dd2012-12-18 14:30:41 +00008538
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008539unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8540 if (!clang_isDeclaration(C.kind))
8541 return 0;
8542
8543 const auto *D = cxcursor::getCursorDecl(C);
8544 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8545 if (RD)
8546 RD = RD->getDefinition();
8547 return (RD && RD->isAbstract()) ? 1 : 0;
8548}
8549
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008550unsigned clang_EnumDecl_isScoped(CXCursor C) {
8551 if (!clang_isDeclaration(C.kind))
8552 return 0;
8553
8554 const Decl *D = cxcursor::getCursorDecl(C);
8555 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8556 return (Enum && Enum->isScoped()) ? 1 : 0;
8557}
8558
Guy Benyei11169dd2012-12-18 14:30:41 +00008559//===----------------------------------------------------------------------===//
8560// Attribute introspection.
8561//===----------------------------------------------------------------------===//
8562
Guy Benyei11169dd2012-12-18 14:30:41 +00008563CXType clang_getIBOutletCollectionType(CXCursor C) {
8564 if (C.kind != CXCursor_IBOutletCollectionAttr)
8565 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008566
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008567 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008568 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8569
8570 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008571}
Guy Benyei11169dd2012-12-18 14:30:41 +00008572
8573//===----------------------------------------------------------------------===//
8574// Inspecting memory usage.
8575//===----------------------------------------------------------------------===//
8576
8577typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8578
8579static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008580 enum CXTUResourceUsageKind k,
8581 unsigned long amount) {
8582 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008583 entries.push_back(entry);
8584}
8585
Guy Benyei11169dd2012-12-18 14:30:41 +00008586const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8587 const char *str = "";
8588 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008589 case CXTUResourceUsage_AST:
8590 str = "ASTContext: expressions, declarations, and types";
8591 break;
8592 case CXTUResourceUsage_Identifiers:
8593 str = "ASTContext: identifiers";
8594 break;
8595 case CXTUResourceUsage_Selectors:
8596 str = "ASTContext: selectors";
8597 break;
8598 case CXTUResourceUsage_GlobalCompletionResults:
8599 str = "Code completion: cached global results";
8600 break;
8601 case CXTUResourceUsage_SourceManagerContentCache:
8602 str = "SourceManager: content cache allocator";
8603 break;
8604 case CXTUResourceUsage_AST_SideTables:
8605 str = "ASTContext: side tables";
8606 break;
8607 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8608 str = "SourceManager: malloc'ed memory buffers";
8609 break;
8610 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8611 str = "SourceManager: mmap'ed memory buffers";
8612 break;
8613 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8614 str = "ExternalASTSource: malloc'ed memory buffers";
8615 break;
8616 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8617 str = "ExternalASTSource: mmap'ed memory buffers";
8618 break;
8619 case CXTUResourceUsage_Preprocessor:
8620 str = "Preprocessor: malloc'ed memory";
8621 break;
8622 case CXTUResourceUsage_PreprocessingRecord:
8623 str = "Preprocessor: PreprocessingRecord";
8624 break;
8625 case CXTUResourceUsage_SourceManager_DataStructures:
8626 str = "SourceManager: data structures and tables";
8627 break;
8628 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8629 str = "Preprocessor: header search tables";
8630 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008631 }
8632 return str;
8633}
8634
8635CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008636 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008637 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008638 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008639 return usage;
8640 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008641
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008642 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008643 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008644 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008645
Guy Benyei11169dd2012-12-18 14:30:41 +00008646 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008647 createCXTUResourceUsageEntry(
8648 *entries, CXTUResourceUsage_AST,
8649 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008650
8651 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008652 createCXTUResourceUsageEntry(
8653 *entries, CXTUResourceUsage_Identifiers,
8654 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008655
8656 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008657 createCXTUResourceUsageEntry(
8658 *entries, CXTUResourceUsage_Selectors,
8659 (unsigned long)astContext.Selectors.getTotalMemory());
8660
Guy Benyei11169dd2012-12-18 14:30:41 +00008661 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008662 createCXTUResourceUsageEntry(
8663 *entries, CXTUResourceUsage_AST_SideTables,
8664 (unsigned long)astContext.getSideTableAllocatedMemory());
8665
Guy Benyei11169dd2012-12-18 14:30:41 +00008666 // How much memory is used for caching global code completion results?
8667 unsigned long completionBytes = 0;
8668 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008669 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008670 completionBytes = completionAllocator->getTotalMemory();
8671 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008672 createCXTUResourceUsageEntry(
8673 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8674
Guy Benyei11169dd2012-12-18 14:30:41 +00008675 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008676 createCXTUResourceUsageEntry(
8677 *entries, CXTUResourceUsage_SourceManagerContentCache,
8678 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8679
Guy Benyei11169dd2012-12-18 14:30:41 +00008680 // How much memory is being used by the MemoryBuffer's in SourceManager?
8681 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008682 astUnit->getSourceManager().getMemoryBufferSizes();
8683
Guy Benyei11169dd2012-12-18 14:30:41 +00008684 createCXTUResourceUsageEntry(*entries,
8685 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008686 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008687 createCXTUResourceUsageEntry(*entries,
8688 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008689 (unsigned long)srcBufs.mmap_bytes);
8690 createCXTUResourceUsageEntry(
8691 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8692 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8693
Guy Benyei11169dd2012-12-18 14:30:41 +00008694 // How much memory is being used by the ExternalASTSource?
8695 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8696 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008697 esrc->getMemoryBufferSizes();
8698
8699 createCXTUResourceUsageEntry(
8700 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8701 (unsigned long)sizes.malloc_bytes);
8702 createCXTUResourceUsageEntry(
8703 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8704 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008705 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008706
Guy Benyei11169dd2012-12-18 14:30:41 +00008707 // How much memory is being used by the Preprocessor?
8708 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008709 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008710 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008711
Guy Benyei11169dd2012-12-18 14:30:41 +00008712 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8713 createCXTUResourceUsageEntry(*entries,
8714 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008715 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008716 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008717
Guy Benyei11169dd2012-12-18 14:30:41 +00008718 createCXTUResourceUsageEntry(*entries,
8719 CXTUResourceUsage_Preprocessor_HeaderSearch,
8720 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008721
Michael Kruse7520cf02020-03-25 09:26:14 -05008722 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8723 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008724 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008725 return usage;
8726}
8727
8728void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8729 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008730 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008731}
8732
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008733CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8734 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008735 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008736 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008737
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008738 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008739 LOG_BAD_TU(TU);
8740 return skipped;
8741 }
8742
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008743 if (!file)
8744 return skipped;
8745
8746 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008747 PreprocessingRecord *ppRec =
8748 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008749 if (!ppRec)
8750 return skipped;
8751
8752 ASTContext &Ctx = astUnit->getASTContext();
8753 SourceManager &sm = Ctx.getSourceManager();
8754 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8755 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008756 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008757
8758 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8759 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008760 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8761 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008762 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008763 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8764 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008765 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008766 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8767 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008768 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008769 }
8770
8771 skipped->count = wantedRanges.size();
8772 skipped->ranges = new CXSourceRange[skipped->count];
8773 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8774 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8775
8776 return skipped;
8777}
8778
Cameron Desrochersd8091282016-08-18 15:43:55 +00008779CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8780 CXSourceRangeList *skipped = new CXSourceRangeList;
8781 skipped->count = 0;
8782 skipped->ranges = nullptr;
8783
8784 if (isNotUsableTU(TU)) {
8785 LOG_BAD_TU(TU);
8786 return skipped;
8787 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008788
Cameron Desrochersd8091282016-08-18 15:43:55 +00008789 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008790 PreprocessingRecord *ppRec =
8791 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008792 if (!ppRec)
8793 return skipped;
8794
8795 ASTContext &Ctx = astUnit->getASTContext();
8796
8797 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8798
8799 skipped->count = SkippedRanges.size();
8800 skipped->ranges = new CXSourceRange[skipped->count];
8801 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8802 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8803
8804 return skipped;
8805}
8806
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008807void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8808 if (ranges) {
8809 delete[] ranges->ranges;
8810 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008811 }
8812}
8813
Guy Benyei11169dd2012-12-18 14:30:41 +00008814void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8815 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8816 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008817 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008818 clang_getTUResourceUsageName(Usage.entries[I].kind),
8819 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008820
Guy Benyei11169dd2012-12-18 14:30:41 +00008821 clang_disposeCXTUResourceUsage(Usage);
8822}
8823
8824//===----------------------------------------------------------------------===//
8825// Misc. utility functions.
8826//===----------------------------------------------------------------------===//
8827
Richard Smith0a7b2972018-07-03 21:34:13 +00008828/// Default to using our desired 8 MB stack size on "safety" threads.
8829static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008830
8831namespace clang {
8832
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008833bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008834 unsigned Size) {
8835 if (!Size)
8836 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008837 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008838 return CRC.RunSafelyOnThread(Fn, Size);
8839 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008840}
8841
Michael Kruse7520cf02020-03-25 09:26:14 -05008842unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008843
Michael Kruse7520cf02020-03-25 09:26:14 -05008844void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008845
Michael Kruse7520cf02020-03-25 09:26:14 -05008846} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008847
8848void clang::setThreadBackgroundPriority() {
8849 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8850 return;
8851
Nico Weber18cfd9f2019-04-21 19:18:41 +00008852#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008853 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008854#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008855}
8856
8857void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8858 if (!Unit)
8859 return;
8860
Michael Kruse7520cf02020-03-25 09:26:14 -05008861 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8862 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008863 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008864 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008865 CXString Msg =
8866 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008867 fprintf(stderr, "%s\n", clang_getCString(Msg));
8868 clang_disposeString(Msg);
8869 }
Nico Weber1865df42018-04-27 19:11:14 +00008870#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008871 // On Windows, force a flush, since there may be multiple copies of
8872 // stderr and stdout in the file system, all with different buffers
8873 // but writing to the same device.
8874 fflush(stderr);
8875#endif
8876}
8877
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008878MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8879 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008880 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008881 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008882 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008883 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008884 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008885
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008886 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008887 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008888 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008889 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008890 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8891 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008892 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8893 return Def.getMacroInfo();
8894 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008895 }
8896
Craig Topper69186e72014-06-08 08:38:04 +00008897 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008898}
8899
Richard Smith66a81862015-05-04 02:25:31 +00008900const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008901 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008902 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008903 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008904 const IdentifierInfo *II = MacroDef->getName();
8905 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008906 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008907
8908 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8909}
8910
Richard Smith66a81862015-05-04 02:25:31 +00008911MacroDefinitionRecord *
8912cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8913 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008914 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008915 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008916 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008917 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008918
8919 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008920 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008921 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8922 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008923 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008924
8925 // Check that the token is inside the definition and not its argument list.
8926 SourceManager &SM = Unit->getSourceManager();
8927 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008928 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008929 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00008930 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008931
8932 Preprocessor &PP = Unit->getPreprocessor();
8933 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
8934 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00008935 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008936
Alp Toker2d57cea2014-05-17 04:53:25 +00008937 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008938 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008939 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008940
8941 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00008942 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00008943 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008944
Richard Smith20e883e2015-04-29 23:20:19 +00008945 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00008946 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00008947 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008948
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008949 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008950}
8951
Richard Smith66a81862015-05-04 02:25:31 +00008952MacroDefinitionRecord *
8953cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
8954 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008955 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008956 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008957
8958 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008959 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008960 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008961 Preprocessor &PP = Unit->getPreprocessor();
8962 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00008963 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008964 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
8965 Token Tok;
8966 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00008967 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008968
8969 return checkForMacroInMacroDefinition(MI, Tok, TU);
8970}
8971
Guy Benyei11169dd2012-12-18 14:30:41 +00008972CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008973 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00008974}
8975
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008976Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
8977 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008978 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008979 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00008980 if (Unit->isMainFileAST())
8981 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008982 return *this;
8983 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00008984 } else {
8985 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008986 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008987 return *this;
8988}
8989
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00008990Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
8991 *this << FE->getName();
8992 return *this;
8993}
8994
8995Logger &cxindex::Logger::operator<<(CXCursor cursor) {
8996 CXString cursorName = clang_getCursorDisplayName(cursor);
8997 *this << cursorName << "@" << clang_getCursorLocation(cursor);
8998 clang_disposeString(cursorName);
8999 return *this;
9000}
9001
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009002Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
9003 CXFile File;
9004 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00009005 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009006 CXString FileName = clang_getFileName(File);
9007 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
9008 clang_disposeString(FileName);
9009 return *this;
9010}
9011
9012Logger &cxindex::Logger::operator<<(CXSourceRange range) {
9013 CXSourceLocation BLoc = clang_getRangeStart(range);
9014 CXSourceLocation ELoc = clang_getRangeEnd(range);
9015
9016 CXFile BFile;
9017 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009018 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009019
9020 CXFile EFile;
9021 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009022 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009023
9024 CXString BFileName = clang_getFileName(BFile);
9025 if (BFile == EFile) {
9026 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05009027 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009028 } else {
9029 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009030 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9031 BColumn)
9032 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9033 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009034 clang_disposeString(EFileName);
9035 }
9036 clang_disposeString(BFileName);
9037 return *this;
9038}
9039
9040Logger &cxindex::Logger::operator<<(CXString Str) {
9041 *this << clang_getCString(Str);
9042 return *this;
9043}
9044
9045Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9046 LogOS << Fmt;
9047 return *this;
9048}
9049
Benjamin Kramer762bc332019-08-07 14:44:40 +00009050static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009051
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009052cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009053 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009054
9055 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9056
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009057 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009058 OS << "[libclang:" << Name << ':';
9059
Alp Toker1a86ad22014-07-06 06:24:00 +00009060#ifdef USE_DARWIN_THREADS
9061 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009062 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9063 OS << tid << ':';
9064#endif
9065
9066 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9067 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009068 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009069
9070 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009071 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009072 OS << "--------------------------------------------------\n";
9073 }
9074}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009075
9076#ifdef CLANG_TOOL_EXTRA_BUILD
9077// This anchor is used to force the linker to link the clang-tidy plugin.
9078extern volatile int ClangTidyPluginAnchorSource;
9079static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9080 ClangTidyPluginAnchorSource;
9081
9082// This anchor is used to force the linker to link the clang-include-fixer
9083// plugin.
9084extern volatile int ClangIncludeFixerPluginAnchorSource;
9085static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9086 ClangIncludeFixerPluginAnchorSource;
9087#endif