blob: 583950c4620b9c30412f699613f427046d29db25 [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");
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 case CXCursor_CXXTypeidExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005243 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 case CXCursor_CXXBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005245 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 case CXCursor_CXXNullPtrLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005247 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 case CXCursor_CXXThisExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005249 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 case CXCursor_CXXThrowExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005251 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 case CXCursor_CXXNewExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005253 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 case CXCursor_CXXDeleteExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005255 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 case CXCursor_UnaryExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005257 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 case CXCursor_ObjCStringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005259 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 case CXCursor_ObjCBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005261 return cxstring::createRef("ObjCBoolLiteralExpr");
Erik Pilkington29099de2016-07-16 00:35:23 +00005262 case CXCursor_ObjCAvailabilityCheckExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005263 return cxstring::createRef("ObjCAvailabilityCheckExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00005264 case CXCursor_ObjCSelfExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005265 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 case CXCursor_ObjCEncodeExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005267 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 case CXCursor_ObjCSelectorExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005269 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 case CXCursor_ObjCProtocolExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005271 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 case CXCursor_ObjCBridgedCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005273 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 case CXCursor_BlockExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005275 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 case CXCursor_PackExpansionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005277 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 case CXCursor_SizeOfPackExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005279 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005281 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 case CXCursor_UnexposedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005283 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 case CXCursor_DeclRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005285 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 case CXCursor_MemberRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005287 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005289 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 case CXCursor_ObjCMessageExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005291 return cxstring::createRef("ObjCMessageExpr");
Erik Pilkingtoneee944e2019-07-02 18:28:13 +00005292 case CXCursor_BuiltinBitCastExpr:
5293 return cxstring::createRef("BuiltinBitCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 case CXCursor_UnexposedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005295 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 case CXCursor_DeclStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005297 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 case CXCursor_LabelStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005299 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 case CXCursor_CompoundStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005301 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 case CXCursor_CaseStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005303 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 case CXCursor_DefaultStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005305 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 case CXCursor_IfStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005307 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 case CXCursor_SwitchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005309 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 case CXCursor_WhileStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005311 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 case CXCursor_DoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005313 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 case CXCursor_ForStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005315 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 case CXCursor_GotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005317 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 case CXCursor_IndirectGotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005319 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 case CXCursor_ContinueStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005321 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 case CXCursor_BreakStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005323 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 case CXCursor_ReturnStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005325 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 case CXCursor_GCCAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005327 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 case CXCursor_MSAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005329 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 case CXCursor_ObjCAtTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005331 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 case CXCursor_ObjCAtCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005333 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 case CXCursor_ObjCAtFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005335 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 case CXCursor_ObjCAtThrowStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005337 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 case CXCursor_ObjCAtSynchronizedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005339 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 case CXCursor_ObjCAutoreleasePoolStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005341 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 case CXCursor_ObjCForCollectionStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005343 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 case CXCursor_CXXCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005345 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 case CXCursor_CXXTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005347 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 case CXCursor_CXXForRangeStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005349 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 case CXCursor_SEHTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005351 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 case CXCursor_SEHExceptStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005353 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 case CXCursor_SEHFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005355 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00005356 case CXCursor_SEHLeaveStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005357 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 case CXCursor_NullStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005359 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 case CXCursor_InvalidFile:
Michael Kruse7520cf02020-03-25 09:26:14 -05005361 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005363 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 case CXCursor_NoDeclFound:
Michael Kruse7520cf02020-03-25 09:26:14 -05005365 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 case CXCursor_NotImplemented:
Michael Kruse7520cf02020-03-25 09:26:14 -05005367 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00005368 case CXCursor_TranslationUnit:
Michael Kruse7520cf02020-03-25 09:26:14 -05005369 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 case CXCursor_UnexposedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005371 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 case CXCursor_IBActionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005373 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 case CXCursor_IBOutletAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005375 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 case CXCursor_IBOutletCollectionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005377 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 case CXCursor_CXXFinalAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005379 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 case CXCursor_CXXOverrideAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005381 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005382 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005383 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005384 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005385 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005386 case CXCursor_PackedAttr:
5387 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00005388 case CXCursor_PureAttr:
5389 return cxstring::createRef("attribute(pure)");
5390 case CXCursor_ConstAttr:
5391 return cxstring::createRef("attribute(const)");
5392 case CXCursor_NoDuplicateAttr:
5393 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00005394 case CXCursor_CUDAConstantAttr:
5395 return cxstring::createRef("attribute(constant)");
5396 case CXCursor_CUDADeviceAttr:
5397 return cxstring::createRef("attribute(device)");
5398 case CXCursor_CUDAGlobalAttr:
5399 return cxstring::createRef("attribute(global)");
5400 case CXCursor_CUDAHostAttr:
5401 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00005402 case CXCursor_CUDASharedAttr:
5403 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00005404 case CXCursor_VisibilityAttr:
5405 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00005406 case CXCursor_DLLExport:
5407 return cxstring::createRef("attribute(dllexport)");
5408 case CXCursor_DLLImport:
5409 return cxstring::createRef("attribute(dllimport)");
Michael Wud092d0b2018-08-03 05:03:22 +00005410 case CXCursor_NSReturnsRetained:
5411 return cxstring::createRef("attribute(ns_returns_retained)");
5412 case CXCursor_NSReturnsNotRetained:
5413 return cxstring::createRef("attribute(ns_returns_not_retained)");
5414 case CXCursor_NSReturnsAutoreleased:
5415 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5416 case CXCursor_NSConsumesSelf:
5417 return cxstring::createRef("attribute(ns_consumes_self)");
5418 case CXCursor_NSConsumed:
5419 return cxstring::createRef("attribute(ns_consumed)");
5420 case CXCursor_ObjCException:
5421 return cxstring::createRef("attribute(objc_exception)");
5422 case CXCursor_ObjCNSObject:
5423 return cxstring::createRef("attribute(NSObject)");
5424 case CXCursor_ObjCIndependentClass:
5425 return cxstring::createRef("attribute(objc_independent_class)");
5426 case CXCursor_ObjCPreciseLifetime:
5427 return cxstring::createRef("attribute(objc_precise_lifetime)");
5428 case CXCursor_ObjCReturnsInnerPointer:
5429 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5430 case CXCursor_ObjCRequiresSuper:
5431 return cxstring::createRef("attribute(objc_requires_super)");
5432 case CXCursor_ObjCRootClass:
5433 return cxstring::createRef("attribute(objc_root_class)");
5434 case CXCursor_ObjCSubclassingRestricted:
5435 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5436 case CXCursor_ObjCExplicitProtocolImpl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005437 return cxstring::createRef(
5438 "attribute(objc_protocol_requires_explicit_implementation)");
Michael Wud092d0b2018-08-03 05:03:22 +00005439 case CXCursor_ObjCDesignatedInitializer:
5440 return cxstring::createRef("attribute(objc_designated_initializer)");
5441 case CXCursor_ObjCRuntimeVisible:
5442 return cxstring::createRef("attribute(objc_runtime_visible)");
5443 case CXCursor_ObjCBoxable:
5444 return cxstring::createRef("attribute(objc_boxable)");
Michael Wu58d837d2018-08-03 05:55:40 +00005445 case CXCursor_FlagEnum:
5446 return cxstring::createRef("attribute(flag_enum)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005448 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005450 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005452 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005454 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005456 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005458 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005460 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005462 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005464 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005466 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005468 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005470 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005472 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005474 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005476 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005478 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005480 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005482 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005484 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005486 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005488 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005490 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005492 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005493 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005494 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005495 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00005496 return cxstring::createRef("OMPParallelDirective");
5497 case CXCursor_OMPSimdDirective:
5498 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00005499 case CXCursor_OMPForDirective:
5500 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00005501 case CXCursor_OMPForSimdDirective:
5502 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00005503 case CXCursor_OMPSectionsDirective:
5504 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00005505 case CXCursor_OMPSectionDirective:
5506 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00005507 case CXCursor_OMPSingleDirective:
5508 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00005509 case CXCursor_OMPMasterDirective:
5510 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00005511 case CXCursor_OMPCriticalDirective:
5512 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00005513 case CXCursor_OMPParallelForDirective:
5514 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00005515 case CXCursor_OMPParallelForSimdDirective:
5516 return cxstring::createRef("OMPParallelForSimdDirective");
cchen47d60942019-12-05 13:43:48 -05005517 case CXCursor_OMPParallelMasterDirective:
5518 return cxstring::createRef("OMPParallelMasterDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00005519 case CXCursor_OMPParallelSectionsDirective:
5520 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00005521 case CXCursor_OMPTaskDirective:
5522 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00005523 case CXCursor_OMPTaskyieldDirective:
5524 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00005525 case CXCursor_OMPBarrierDirective:
5526 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00005527 case CXCursor_OMPTaskwaitDirective:
5528 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00005529 case CXCursor_OMPTaskgroupDirective:
5530 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00005531 case CXCursor_OMPFlushDirective:
5532 return cxstring::createRef("OMPFlushDirective");
Alexey Bataevc112e942020-02-28 09:52:15 -05005533 case CXCursor_OMPDepobjDirective:
5534 return cxstring::createRef("OMPDepobjDirective");
Alexey Bataevfcba7c32020-03-20 07:03:01 -04005535 case CXCursor_OMPScanDirective:
5536 return cxstring::createRef("OMPScanDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00005537 case CXCursor_OMPOrderedDirective:
5538 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00005539 case CXCursor_OMPAtomicDirective:
5540 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00005541 case CXCursor_OMPTargetDirective:
5542 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00005543 case CXCursor_OMPTargetDataDirective:
5544 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00005545 case CXCursor_OMPTargetEnterDataDirective:
5546 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00005547 case CXCursor_OMPTargetExitDataDirective:
5548 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00005549 case CXCursor_OMPTargetParallelDirective:
5550 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00005551 case CXCursor_OMPTargetParallelForDirective:
5552 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00005553 case CXCursor_OMPTargetUpdateDirective:
5554 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00005555 case CXCursor_OMPTeamsDirective:
5556 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00005557 case CXCursor_OMPCancellationPointDirective:
5558 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00005559 case CXCursor_OMPCancelDirective:
5560 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00005561 case CXCursor_OMPTaskLoopDirective:
5562 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005563 case CXCursor_OMPTaskLoopSimdDirective:
5564 return cxstring::createRef("OMPTaskLoopSimdDirective");
Alexey Bataev60e51c42019-10-10 20:13:02 +00005565 case CXCursor_OMPMasterTaskLoopDirective:
5566 return cxstring::createRef("OMPMasterTaskLoopDirective");
Alexey Bataevb8552ab2019-10-18 16:47:35 +00005567 case CXCursor_OMPMasterTaskLoopSimdDirective:
5568 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
Alexey Bataev5bbcead2019-10-14 17:17:41 +00005569 case CXCursor_OMPParallelMasterTaskLoopDirective:
5570 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
Alexey Bataev14a388f2019-10-25 10:27:13 -04005571 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5572 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00005573 case CXCursor_OMPDistributeDirective:
5574 return cxstring::createRef("OMPDistributeDirective");
Carlo Bertolli9925f152016-06-27 14:55:37 +00005575 case CXCursor_OMPDistributeParallelForDirective:
5576 return cxstring::createRef("OMPDistributeParallelForDirective");
Kelvin Li4a39add2016-07-05 05:00:15 +00005577 case CXCursor_OMPDistributeParallelForSimdDirective:
5578 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
Kelvin Li787f3fc2016-07-06 04:45:38 +00005579 case CXCursor_OMPDistributeSimdDirective:
5580 return cxstring::createRef("OMPDistributeSimdDirective");
Kelvin Lia579b912016-07-14 02:54:56 +00005581 case CXCursor_OMPTargetParallelForSimdDirective:
5582 return cxstring::createRef("OMPTargetParallelForSimdDirective");
Kelvin Li986330c2016-07-20 22:57:10 +00005583 case CXCursor_OMPTargetSimdDirective:
5584 return cxstring::createRef("OMPTargetSimdDirective");
Kelvin Li02532872016-08-05 14:37:37 +00005585 case CXCursor_OMPTeamsDistributeDirective:
5586 return cxstring::createRef("OMPTeamsDistributeDirective");
Kelvin Li4e325f72016-10-25 12:50:55 +00005587 case CXCursor_OMPTeamsDistributeSimdDirective:
5588 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
Kelvin Li579e41c2016-11-30 23:51:03 +00005589 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5590 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
Kelvin Li7ade93f2016-12-09 03:24:30 +00005591 case CXCursor_OMPTeamsDistributeParallelForDirective:
5592 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
Kelvin Libf594a52016-12-17 05:48:59 +00005593 case CXCursor_OMPTargetTeamsDirective:
5594 return cxstring::createRef("OMPTargetTeamsDirective");
Kelvin Li83c451e2016-12-25 04:52:54 +00005595 case CXCursor_OMPTargetTeamsDistributeDirective:
5596 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
Kelvin Li80e8f562016-12-29 22:16:30 +00005597 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5598 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
Kelvin Li1851df52017-01-03 05:23:48 +00005599 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5600 return cxstring::createRef(
5601 "OMPTargetTeamsDistributeParallelForSimdDirective");
Kelvin Lida681182017-01-10 18:08:18 +00005602 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5603 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00005604 case CXCursor_OverloadCandidate:
Michael Kruse7520cf02020-03-25 09:26:14 -05005605 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00005606 case CXCursor_TypeAliasTemplateDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005607 return cxstring::createRef("TypeAliasTemplateDecl");
Olivier Goffart81978012016-06-09 16:15:55 +00005608 case CXCursor_StaticAssert:
Michael Kruse7520cf02020-03-25 09:26:14 -05005609 return cxstring::createRef("StaticAssert");
Olivier Goffartd211c642016-11-04 06:29:27 +00005610 case CXCursor_FriendDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005611 return cxstring::createRef("FriendDecl");
Sven van Haastregtdc2c9302019-02-11 11:00:56 +00005612 case CXCursor_ConvergentAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005613 return cxstring::createRef("attribute(convergent)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005614 case CXCursor_WarnUnusedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005615 return cxstring::createRef("attribute(warn_unused)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005616 case CXCursor_WarnUnusedResultAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005617 return cxstring::createRef("attribute(warn_unused_result)");
Emilio Cobos Alvarezcd741272019-03-13 16:16:54 +00005618 case CXCursor_AlignedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005619 return cxstring::createRef("attribute(aligned)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005620 }
5621
5622 llvm_unreachable("Unhandled CXCursorKind");
5623}
5624
5625struct GetCursorData {
5626 SourceLocation TokenBeginLoc;
5627 bool PointsAtMacroArgExpansion;
5628 bool VisitedObjCPropertyImplDecl;
5629 SourceLocation VisitedDeclaratorDeclStartLoc;
5630 CXCursor &BestCursor;
5631
Michael Kruse7520cf02020-03-25 09:26:14 -05005632 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5633 CXCursor &outputCursor)
5634 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5636 VisitedObjCPropertyImplDecl = false;
5637 }
5638};
5639
Michael Kruse7520cf02020-03-25 09:26:14 -05005640static enum CXChildVisitResult
5641GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5643 CXCursor *BestCursor = &Data->BestCursor;
5644
5645 // If we point inside a macro argument we should provide info of what the
5646 // token is so use the actual cursor, don't replace it with a macro expansion
5647 // cursor.
5648 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5649 return CXChildVisit_Recurse;
Michael Kruse7520cf02020-03-25 09:26:14 -05005650
Guy Benyei11169dd2012-12-18 14:30:41 +00005651 if (clang_isDeclaration(cursor.kind)) {
5652 // Avoid having the implicit methods override the property decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05005653 if (const ObjCMethodDecl *MD =
5654 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 if (MD->isImplicit())
5656 return CXChildVisit_Break;
5657
Michael Kruse7520cf02020-03-25 09:26:14 -05005658 } else if (const ObjCInterfaceDecl *ID =
5659 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005660 // Check that when we have multiple @class references in the same line,
5661 // that later ones do not override the previous ones.
5662 // If we have:
5663 // @class Foo, Bar;
5664 // source ranges for both start at '@', so 'Bar' will end up overriding
5665 // 'Foo' even though the cursor location was at 'Foo'.
5666 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5667 BestCursor->kind == CXCursor_ObjCClassRef)
Michael Kruse7520cf02020-03-25 09:26:14 -05005668 if (const ObjCInterfaceDecl *PrevID =
5669 dyn_cast_or_null<ObjCInterfaceDecl>(
5670 getCursorDecl(*BestCursor))) {
5671 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5672 !ID->isThisDeclarationADefinition())
5673 return CXChildVisit_Break;
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 }
5675
Michael Kruse7520cf02020-03-25 09:26:14 -05005676 } else if (const DeclaratorDecl *DD =
5677 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005678 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5679 // Check that when we have multiple declarators in the same line,
5680 // that later ones do not override the previous ones.
5681 // If we have:
5682 // int Foo, Bar;
5683 // source ranges for both start at 'int', so 'Bar' will end up overriding
5684 // 'Foo' even though the cursor location was at 'Foo'.
5685 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5686 return CXChildVisit_Break;
5687 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5688
Michael Kruse7520cf02020-03-25 09:26:14 -05005689 } else if (const ObjCPropertyImplDecl *PropImp =
5690 dyn_cast_or_null<ObjCPropertyImplDecl>(
5691 getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005692 (void)PropImp;
5693 // Check that when we have multiple @synthesize in the same line,
5694 // that later ones do not override the previous ones.
5695 // If we have:
5696 // @synthesize Foo, Bar;
5697 // source ranges for both start at '@', so 'Bar' will end up overriding
5698 // 'Foo' even though the cursor location was at 'Foo'.
5699 if (Data->VisitedObjCPropertyImplDecl)
5700 return CXChildVisit_Break;
5701 Data->VisitedObjCPropertyImplDecl = true;
5702 }
5703 }
5704
5705 if (clang_isExpression(cursor.kind) &&
5706 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005707 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005708 // Avoid having the cursor of an expression replace the declaration cursor
5709 // when the expression source range overlaps the declaration range.
5710 // This can happen for C++ constructor expressions whose range generally
5711 // include the variable declaration, e.g.:
Michael Kruse7520cf02020-03-25 09:26:14 -05005712 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5713 // cursor.
Guy Benyei11169dd2012-12-18 14:30:41 +00005714 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5715 D->getLocation() == Data->TokenBeginLoc)
5716 return CXChildVisit_Break;
5717 }
5718 }
5719
Michael Kruse7520cf02020-03-25 09:26:14 -05005720 // If our current best cursor is the construction of a temporary object,
5721 // don't replace that cursor with a type reference, because we want
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 // clang_getCursor() to point at the constructor.
5723 if (clang_isExpression(BestCursor->kind) &&
5724 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5725 cursor.kind == CXCursor_TypeRef) {
5726 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5727 // as having the actual point on the type reference.
5728 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5729 return CXChildVisit_Recurse;
5730 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005731
5732 // If we already have an Objective-C superclass reference, don't
5733 // update it further.
5734 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5735 return CXChildVisit_Break;
5736
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 *BestCursor = cursor;
5738 return CXChildVisit_Recurse;
5739}
5740
5741CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005742 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005743 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005746
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005747 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005748 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5749
5750 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5751 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5752
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005753 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005754 CXFile SearchFile;
5755 unsigned SearchLine, SearchColumn;
5756 CXFile ResultFile;
5757 unsigned ResultLine, ResultColumn;
5758 CXString SearchFileName, ResultFileName, KindSpelling, USR;
Michael Kruse7520cf02020-03-25 09:26:14 -05005759 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
Guy Benyei11169dd2012-12-18 14:30:41 +00005760 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005761
5762 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5763 nullptr);
Michael Kruse7520cf02020-03-25 09:26:14 -05005764 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5765 nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 SearchFileName = clang_getFileName(SearchFile);
5767 ResultFileName = clang_getFileName(ResultFile);
5768 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5769 USR = clang_getCursorUSR(Result);
Michael Kruse7520cf02020-03-25 09:26:14 -05005770 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5771 SearchLine, SearchColumn,
5772 clang_getCString(KindSpelling))
5773 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5774 ResultLine, ResultColumn, clang_getCString(USR),
5775 IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005776 clang_disposeString(SearchFileName);
5777 clang_disposeString(ResultFileName);
5778 clang_disposeString(KindSpelling);
5779 clang_disposeString(USR);
Michael Kruse7520cf02020-03-25 09:26:14 -05005780
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 CXCursor Definition = clang_getCursorDefinition(Result);
5782 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5783 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
Michael Kruse7520cf02020-03-25 09:26:14 -05005784 CXString DefinitionKindSpelling =
5785 clang_getCursorKindSpelling(Definition.kind);
Guy Benyei11169dd2012-12-18 14:30:41 +00005786 CXFile DefinitionFile;
5787 unsigned DefinitionLine, DefinitionColumn;
Michael Kruse7520cf02020-03-25 09:26:14 -05005788 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5789 &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005790 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005791 *Log << llvm::format(" -> %s(%s:%d:%d)",
Michael Kruse7520cf02020-03-25 09:26:14 -05005792 clang_getCString(DefinitionKindSpelling),
5793 clang_getCString(DefinitionFileName), DefinitionLine,
5794 DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005795 clang_disposeString(DefinitionFileName);
5796 clang_disposeString(DefinitionKindSpelling);
5797 }
5798 }
5799
5800 return Result;
5801}
5802
5803CXCursor clang_getNullCursor(void) {
5804 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5805}
5806
5807unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005808 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5809 // can't set consistently. For example, when visiting a DeclStmt we will set
5810 // it but we don't set it on the result of clang_getCursorDefinition for
5811 // a reference of the same declaration.
5812 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5813 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5814 // to provide that kind of info.
5815 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005816 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005817 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005818 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005819
Guy Benyei11169dd2012-12-18 14:30:41 +00005820 return X == Y;
5821}
5822
5823unsigned clang_hashCursor(CXCursor C) {
5824 unsigned Index = 0;
5825 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5826 Index = 1;
Michael Kruse7520cf02020-03-25 09:26:14 -05005827
5828 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5829 std::make_pair(C.kind, C.data[Index]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005830}
5831
5832unsigned clang_isInvalid(enum CXCursorKind K) {
5833 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5834}
5835
5836unsigned clang_isDeclaration(enum CXCursorKind K) {
5837 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005838 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5839}
5840
Ivan Donchevskii08ff9102018-01-04 10:59:50 +00005841unsigned clang_isInvalidDeclaration(CXCursor C) {
5842 if (clang_isDeclaration(C.kind)) {
5843 if (const Decl *D = getCursorDecl(C))
5844 return D->isInvalidDecl();
5845 }
5846
5847 return 0;
5848}
5849
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005850unsigned clang_isReference(enum CXCursorKind K) {
5851 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5852}
Guy Benyei11169dd2012-12-18 14:30:41 +00005853
5854unsigned clang_isExpression(enum CXCursorKind K) {
5855 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5856}
5857
5858unsigned clang_isStatement(enum CXCursorKind K) {
5859 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5860}
5861
5862unsigned clang_isAttribute(enum CXCursorKind K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005863 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005864}
5865
5866unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5867 return K == CXCursor_TranslationUnit;
5868}
5869
5870unsigned clang_isPreprocessing(enum CXCursorKind K) {
5871 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5872}
Michael Kruse7520cf02020-03-25 09:26:14 -05005873
Guy Benyei11169dd2012-12-18 14:30:41 +00005874unsigned clang_isUnexposed(enum CXCursorKind K) {
5875 switch (K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005876 case CXCursor_UnexposedDecl:
5877 case CXCursor_UnexposedExpr:
5878 case CXCursor_UnexposedStmt:
5879 case CXCursor_UnexposedAttr:
5880 return true;
5881 default:
5882 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005883 }
5884}
5885
Michael Kruse7520cf02020-03-25 09:26:14 -05005886CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005887
5888CXSourceLocation clang_getCursorLocation(CXCursor C) {
5889 if (clang_isReference(C.kind)) {
5890 switch (C.kind) {
5891 case CXCursor_ObjCSuperClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005892 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5893 getCursorObjCSuperClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005894 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5895 }
5896
5897 case CXCursor_ObjCProtocolRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005898 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5899 getCursorObjCProtocolRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005900 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5901 }
5902
5903 case CXCursor_ObjCClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005904 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5905 getCursorObjCClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005906 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5907 }
5908
5909 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005910 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005911 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5912 }
5913
5914 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005915 std::pair<const TemplateDecl *, SourceLocation> P =
5916 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005917 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5918 }
5919
5920 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005921 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5923 }
5924
5925 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005926 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005927 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5928 }
5929
5930 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005931 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005932 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5933 }
5934
5935 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005936 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005937 if (!BaseSpec)
5938 return clang_getNullLocation();
Michael Kruse7520cf02020-03-25 09:26:14 -05005939
Guy Benyei11169dd2012-12-18 14:30:41 +00005940 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
Michael Kruse7520cf02020-03-25 09:26:14 -05005941 return cxloc::translateSourceLocation(
5942 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005943
Guy Benyei11169dd2012-12-18 14:30:41 +00005944 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005945 BaseSpec->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005946 }
5947
5948 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005949 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005950 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5951 }
5952
5953 case CXCursor_OverloadedDeclRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005954 return cxloc::translateSourceLocation(
5955 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
Guy Benyei11169dd2012-12-18 14:30:41 +00005956
5957 default:
5958 // FIXME: Need a way to enumerate all non-reference cases.
5959 llvm_unreachable("Missed a reference kind");
5960 }
5961 }
5962
5963 if (clang_isExpression(C.kind))
Michael Kruse7520cf02020-03-25 09:26:14 -05005964 return cxloc::translateSourceLocation(
5965 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
Guy Benyei11169dd2012-12-18 14:30:41 +00005966
5967 if (clang_isStatement(C.kind))
5968 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005969 getCursorStmt(C)->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005970
5971 if (C.kind == CXCursor_PreprocessingDirective) {
5972 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5973 return cxloc::translateSourceLocation(getCursorContext(C), L);
5974 }
5975
5976 if (C.kind == CXCursor_MacroExpansion) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005977 SourceLocation L =
5978 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005979 return cxloc::translateSourceLocation(getCursorContext(C), L);
5980 }
5981
5982 if (C.kind == CXCursor_MacroDefinition) {
5983 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5984 return cxloc::translateSourceLocation(getCursorContext(C), L);
5985 }
5986
5987 if (C.kind == CXCursor_InclusionDirective) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005988 SourceLocation L =
5989 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005990 return cxloc::translateSourceLocation(getCursorContext(C), L);
5991 }
5992
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005993 if (clang_isAttribute(C.kind)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005994 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005995 return cxloc::translateSourceLocation(getCursorContext(C), L);
5996 }
5997
Guy Benyei11169dd2012-12-18 14:30:41 +00005998 if (!clang_isDeclaration(C.kind))
5999 return clang_getNullLocation();
6000
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006001 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006002 if (!D)
6003 return clang_getNullLocation();
6004
6005 SourceLocation Loc = D->getLocation();
6006 // FIXME: Multiple variables declared in a single declaration
6007 // currently lack the information needed to correctly determine their
6008 // ranges when accounting for the type-specifier. We use context
6009 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6010 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006011 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 if (!cxcursor::isFirstInDeclGroup(C))
6013 Loc = VD->getLocation();
6014 }
6015
6016 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006017 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 Loc = MD->getSelectorStartLoc();
6019
6020 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
6021}
6022
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00006023} // end extern "C"
6024
Guy Benyei11169dd2012-12-18 14:30:41 +00006025CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6026 assert(TU);
6027
6028 // Guard against an invalid SourceLocation, or we may assert in one
6029 // of the following calls.
6030 if (SLoc.isInvalid())
6031 return clang_getNullCursor();
6032
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006033 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006034
6035 // Translate the given source location to make it point at the beginning of
6036 // the token under the cursor.
6037 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6038 CXXUnit->getASTContext().getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05006039
Guy Benyei11169dd2012-12-18 14:30:41 +00006040 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6041 if (SLoc.isValid()) {
6042 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6043 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Michael Kruse7520cf02020-03-25 09:26:14 -05006044 /*VisitPreprocessorLast=*/true,
Guy Benyei11169dd2012-12-18 14:30:41 +00006045 /*VisitIncludedEntities=*/false,
6046 SourceLocation(SLoc));
6047 CursorVis.visitFileRegion();
6048 }
6049
6050 return Result;
6051}
6052
6053static SourceRange getRawCursorExtent(CXCursor C) {
6054 if (clang_isReference(C.kind)) {
6055 switch (C.kind) {
6056 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05006057 return getCursorObjCSuperClassRef(C).second;
Guy Benyei11169dd2012-12-18 14:30:41 +00006058
6059 case CXCursor_ObjCProtocolRef:
6060 return getCursorObjCProtocolRef(C).second;
6061
6062 case CXCursor_ObjCClassRef:
6063 return getCursorObjCClassRef(C).second;
6064
6065 case CXCursor_TypeRef:
6066 return getCursorTypeRef(C).second;
6067
6068 case CXCursor_TemplateRef:
6069 return getCursorTemplateRef(C).second;
6070
6071 case CXCursor_NamespaceRef:
6072 return getCursorNamespaceRef(C).second;
6073
6074 case CXCursor_MemberRef:
6075 return getCursorMemberRef(C).second;
6076
6077 case CXCursor_CXXBaseSpecifier:
6078 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6079
6080 case CXCursor_LabelRef:
6081 return getCursorLabelRef(C).second;
6082
6083 case CXCursor_OverloadedDeclRef:
6084 return getCursorOverloadedDeclRef(C).second;
6085
6086 case CXCursor_VariableRef:
6087 return getCursorVariableRef(C).second;
Michael Kruse7520cf02020-03-25 09:26:14 -05006088
Guy Benyei11169dd2012-12-18 14:30:41 +00006089 default:
6090 // FIXME: Need a way to enumerate all non-reference cases.
6091 llvm_unreachable("Missed a reference kind");
6092 }
6093 }
6094
6095 if (clang_isExpression(C.kind))
6096 return getCursorExpr(C)->getSourceRange();
6097
6098 if (clang_isStatement(C.kind))
6099 return getCursorStmt(C)->getSourceRange();
6100
6101 if (clang_isAttribute(C.kind))
6102 return getCursorAttr(C)->getRange();
6103
6104 if (C.kind == CXCursor_PreprocessingDirective)
6105 return cxcursor::getCursorPreprocessingDirective(C);
6106
6107 if (C.kind == CXCursor_MacroExpansion) {
6108 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006109 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006110 return TU->mapRangeFromPreamble(Range);
6111 }
6112
6113 if (C.kind == CXCursor_MacroDefinition) {
6114 ASTUnit *TU = getCursorASTUnit(C);
6115 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6116 return TU->mapRangeFromPreamble(Range);
6117 }
6118
6119 if (C.kind == CXCursor_InclusionDirective) {
6120 ASTUnit *TU = getCursorASTUnit(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05006121 SourceRange Range =
6122 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006123 return TU->mapRangeFromPreamble(Range);
6124 }
6125
6126 if (C.kind == CXCursor_TranslationUnit) {
6127 ASTUnit *TU = getCursorASTUnit(C);
6128 FileID MainID = TU->getSourceManager().getMainFileID();
6129 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6130 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6131 return SourceRange(Start, End);
6132 }
6133
6134 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006135 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006136 if (!D)
6137 return SourceRange();
6138
6139 SourceRange R = D->getSourceRange();
6140 // FIXME: Multiple variables declared in a single declaration
6141 // currently lack the information needed to correctly determine their
6142 // ranges when accounting for the type-specifier. We use context
6143 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6144 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006145 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006146 if (!cxcursor::isFirstInDeclGroup(C))
6147 R.setBegin(VD->getLocation());
6148 }
6149 return R;
6150 }
6151 return SourceRange();
6152}
6153
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006154/// Retrieves the "raw" cursor extent, which is then extended to include
Guy Benyei11169dd2012-12-18 14:30:41 +00006155/// the decl-specifier-seq for declarations.
6156static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6157 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006158 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006159 if (!D)
6160 return SourceRange();
6161
6162 SourceRange R = D->getSourceRange();
6163
6164 // Adjust the start of the location for declarations preceded by
6165 // declaration specifiers.
6166 SourceLocation StartLoc;
6167 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6168 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006169 StartLoc = TI->getTypeLoc().getBeginLoc();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006170 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006171 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006172 StartLoc = TI->getTypeLoc().getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00006173 }
6174
6175 if (StartLoc.isValid() && R.getBegin().isValid() &&
6176 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6177 R.setBegin(StartLoc);
6178
6179 // FIXME: Multiple variables declared in a single declaration
6180 // currently lack the information needed to correctly determine their
6181 // ranges when accounting for the type-specifier. We use context
6182 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6183 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006184 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006185 if (!cxcursor::isFirstInDeclGroup(C))
6186 R.setBegin(VD->getLocation());
6187 }
6188
Michael Kruse7520cf02020-03-25 09:26:14 -05006189 return R;
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006191
Guy Benyei11169dd2012-12-18 14:30:41 +00006192 return getRawCursorExtent(C);
6193}
6194
Guy Benyei11169dd2012-12-18 14:30:41 +00006195CXSourceRange clang_getCursorExtent(CXCursor C) {
6196 SourceRange R = getRawCursorExtent(C);
6197 if (R.isInvalid())
6198 return clang_getNullRange();
6199
6200 return cxloc::translateSourceRange(getCursorContext(C), R);
6201}
6202
6203CXCursor clang_getCursorReferenced(CXCursor C) {
6204 if (clang_isInvalid(C.kind))
6205 return clang_getNullCursor();
6206
6207 CXTranslationUnit tu = getCursorTU(C);
6208 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006209 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006210 if (!D)
6211 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006212 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006213 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006214 if (const ObjCPropertyImplDecl *PropImpl =
6215 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006216 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6217 return MakeCXCursor(Property, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006218
Guy Benyei11169dd2012-12-18 14:30:41 +00006219 return C;
6220 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006221
Guy Benyei11169dd2012-12-18 14:30:41 +00006222 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006223 const Expr *E = getCursorExpr(C);
6224 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00006225 if (D) {
6226 CXCursor declCursor = MakeCXCursor(D, tu);
6227 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6228 declCursor);
6229 return declCursor;
6230 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006231
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006232 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00006233 return MakeCursorOverloadedDeclRef(Ovl, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006234
Guy Benyei11169dd2012-12-18 14:30:41 +00006235 return clang_getNullCursor();
6236 }
6237
6238 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006239 const Stmt *S = getCursorStmt(C);
6240 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00006241 if (LabelDecl *label = Goto->getLabel())
6242 if (LabelStmt *labelS = label->getStmt())
Michael Kruse7520cf02020-03-25 09:26:14 -05006243 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006244
6245 return clang_getNullCursor();
6246 }
Richard Smith66a81862015-05-04 02:25:31 +00006247
Guy Benyei11169dd2012-12-18 14:30:41 +00006248 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00006249 if (const MacroDefinitionRecord *Def =
6250 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006251 return MakeMacroDefinitionCursor(Def, tu);
6252 }
6253
6254 if (!clang_isReference(C.kind))
6255 return clang_getNullCursor();
6256
6257 switch (C.kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006258 case CXCursor_ObjCSuperClassRef:
6259 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006260
Michael Kruse7520cf02020-03-25 09:26:14 -05006261 case CXCursor_ObjCProtocolRef: {
6262 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6263 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6264 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006265
Michael Kruse7520cf02020-03-25 09:26:14 -05006266 return MakeCXCursor(Prot, tu);
6267 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006268
Michael Kruse7520cf02020-03-25 09:26:14 -05006269 case CXCursor_ObjCClassRef: {
6270 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6271 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6272 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006273
Michael Kruse7520cf02020-03-25 09:26:14 -05006274 return MakeCXCursor(Class, tu);
6275 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006276
Michael Kruse7520cf02020-03-25 09:26:14 -05006277 case CXCursor_TypeRef:
6278 return MakeCXCursor(getCursorTypeRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006279
Michael Kruse7520cf02020-03-25 09:26:14 -05006280 case CXCursor_TemplateRef:
6281 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006282
Michael Kruse7520cf02020-03-25 09:26:14 -05006283 case CXCursor_NamespaceRef:
6284 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006285
Michael Kruse7520cf02020-03-25 09:26:14 -05006286 case CXCursor_MemberRef:
6287 return MakeCXCursor(getCursorMemberRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006288
Michael Kruse7520cf02020-03-25 09:26:14 -05006289 case CXCursor_CXXBaseSpecifier: {
6290 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6291 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6292 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006293
Michael Kruse7520cf02020-03-25 09:26:14 -05006294 case CXCursor_LabelRef:
6295 // FIXME: We end up faking the "parent" declaration here because we
6296 // don't want to make CXCursor larger.
6297 return MakeCXCursor(
6298 getCursorLabelRef(C).first,
6299 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006300
Michael Kruse7520cf02020-03-25 09:26:14 -05006301 case CXCursor_OverloadedDeclRef:
6302 return C;
Guy Benyei11169dd2012-12-18 14:30:41 +00006303
Michael Kruse7520cf02020-03-25 09:26:14 -05006304 case CXCursor_VariableRef:
6305 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6306
6307 default:
6308 // We would prefer to enumerate all non-reference cursor kinds here.
6309 llvm_unreachable("Unhandled reference cursor kind");
Guy Benyei11169dd2012-12-18 14:30:41 +00006310 }
6311}
6312
6313CXCursor clang_getCursorDefinition(CXCursor C) {
6314 if (clang_isInvalid(C.kind))
6315 return clang_getNullCursor();
6316
6317 CXTranslationUnit TU = getCursorTU(C);
6318
6319 bool WasReference = false;
6320 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6321 C = clang_getCursorReferenced(C);
6322 WasReference = true;
6323 }
6324
6325 if (C.kind == CXCursor_MacroExpansion)
6326 return clang_getCursorReferenced(C);
6327
6328 if (!clang_isDeclaration(C.kind))
6329 return clang_getNullCursor();
6330
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006331 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006332 if (!D)
6333 return clang_getNullCursor();
6334
6335 switch (D->getKind()) {
6336 // Declaration kinds that don't really separate the notions of
6337 // declaration and definition.
6338 case Decl::Namespace:
6339 case Decl::Typedef:
6340 case Decl::TypeAlias:
6341 case Decl::TypeAliasTemplate:
6342 case Decl::TemplateTypeParm:
6343 case Decl::EnumConstant:
6344 case Decl::Field:
Richard Smithbdb84f32016-07-22 23:36:59 +00006345 case Decl::Binding:
John McCall5e77d762013-04-16 07:28:30 +00006346 case Decl::MSProperty:
Richard Smithbab6df82020-04-11 22:15:29 -07006347 case Decl::MSGuid:
Guy Benyei11169dd2012-12-18 14:30:41 +00006348 case Decl::IndirectField:
6349 case Decl::ObjCIvar:
6350 case Decl::ObjCAtDefsField:
6351 case Decl::ImplicitParam:
6352 case Decl::ParmVar:
6353 case Decl::NonTypeTemplateParm:
6354 case Decl::TemplateTemplateParm:
6355 case Decl::ObjCCategoryImpl:
6356 case Decl::ObjCImplementation:
6357 case Decl::AccessSpec:
6358 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006359 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006360 case Decl::ObjCPropertyImpl:
6361 case Decl::FileScopeAsm:
6362 case Decl::StaticAssert:
6363 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006364 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006365 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006366 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006367 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006368 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006369 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006370 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006371 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006372 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006373 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006374 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006375 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006376 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006377 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006378 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006379 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006380 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006381 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006382 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006383 return C;
6384
6385 // Declaration kinds that don't make any sense here, but are
6386 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006387 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006388 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006389 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006390 break;
6391
6392 // Declaration kinds for which the definition is not resolvable.
6393 case Decl::UnresolvedUsingTypename:
6394 case Decl::UnresolvedUsingValue:
6395 break;
6396
6397 case Decl::UsingDirective:
6398 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6399 TU);
6400
6401 case Decl::NamespaceAlias:
6402 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6403
6404 case Decl::Enum:
6405 case Decl::Record:
6406 case Decl::CXXRecord:
6407 case Decl::ClassTemplateSpecialization:
6408 case Decl::ClassTemplatePartialSpecialization:
6409 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6410 return MakeCXCursor(Def, TU);
6411 return clang_getNullCursor();
6412
6413 case Decl::Function:
6414 case Decl::CXXMethod:
6415 case Decl::CXXConstructor:
6416 case Decl::CXXDestructor:
6417 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006418 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006419 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006420 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 return clang_getNullCursor();
6422 }
6423
Larisse Voufo39a1e502013-08-06 01:03:05 +00006424 case Decl::Var:
6425 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006426 case Decl::VarTemplatePartialSpecialization:
6427 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006428 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006429 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006430 return MakeCXCursor(Def, TU);
6431 return clang_getNullCursor();
6432 }
6433
6434 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006435 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006436 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6437 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6438 return clang_getNullCursor();
6439 }
6440
6441 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006442 if (RecordDecl *Def =
6443 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006444 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6445 TU);
6446 return clang_getNullCursor();
6447 }
6448
Larisse Voufo39a1e502013-08-06 01:03:05 +00006449 case Decl::VarTemplate: {
6450 if (VarDecl *Def =
6451 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6452 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6453 return clang_getNullCursor();
6454 }
6455
Guy Benyei11169dd2012-12-18 14:30:41 +00006456 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006457 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6458 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006459
6460 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006461 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006463 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006464
6465 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006466 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006467 if (Method->isThisDeclarationADefinition())
6468 return C;
6469
6470 // Dig out the method definition in the associated
6471 // @implementation, if we have it.
6472 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006473 if (const ObjCInterfaceDecl *Class =
6474 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006475 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006476 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6477 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006478 if (Def->isThisDeclarationADefinition())
6479 return MakeCXCursor(Def, TU);
6480
6481 return clang_getNullCursor();
6482 }
6483
6484 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006485 if (ObjCCategoryImplDecl *Impl =
6486 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006487 return MakeCXCursor(Impl, TU);
6488 return clang_getNullCursor();
6489
6490 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006491 if (const ObjCProtocolDecl *Def =
6492 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006493 return MakeCXCursor(Def, TU);
6494 return clang_getNullCursor();
6495
6496 case Decl::ObjCInterface: {
6497 // There are two notions of a "definition" for an Objective-C
6498 // class: the interface and its implementation. When we resolved a
6499 // reference to an Objective-C class, produce the @interface as
6500 // the definition; when we were provided with the interface,
6501 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006502 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006503 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006504 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006505 return MakeCXCursor(Def, TU);
6506 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6507 return MakeCXCursor(Impl, TU);
6508 return clang_getNullCursor();
6509 }
6510
6511 case Decl::ObjCProperty:
6512 // FIXME: We don't really know where to find the
6513 // ObjCPropertyImplDecls that implement this property.
6514 return clang_getNullCursor();
6515
6516 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006517 if (const ObjCInterfaceDecl *Class =
6518 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006519 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006520 return MakeCXCursor(Def, TU);
6521
6522 return clang_getNullCursor();
6523
6524 case Decl::Friend:
6525 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6526 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6527 return clang_getNullCursor();
6528
6529 case Decl::FriendTemplate:
6530 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6531 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6532 return clang_getNullCursor();
6533 }
6534
6535 return clang_getNullCursor();
6536}
6537
6538unsigned clang_isCursorDefinition(CXCursor C) {
6539 if (!clang_isDeclaration(C.kind))
6540 return 0;
6541
6542 return clang_getCursorDefinition(C) == C;
6543}
6544
6545CXCursor clang_getCanonicalCursor(CXCursor C) {
6546 if (!clang_isDeclaration(C.kind))
6547 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006548
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006549 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006550 if (const ObjCCategoryImplDecl *CatImplD =
6551 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006552 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6553 return MakeCXCursor(CatD, getCursorTU(C));
6554
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006555 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6556 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006557 return MakeCXCursor(IFD, getCursorTU(C));
6558
6559 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6560 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006561
Guy Benyei11169dd2012-12-18 14:30:41 +00006562 return C;
6563}
6564
6565int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6566 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6567}
Michael Kruse7520cf02020-03-25 09:26:14 -05006568
Guy Benyei11169dd2012-12-18 14:30:41 +00006569unsigned clang_getNumOverloadedDecls(CXCursor C) {
6570 if (C.kind != CXCursor_OverloadedDeclRef)
6571 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006572
Guy Benyei11169dd2012-12-18 14:30:41 +00006573 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006574 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006575 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006576
6577 if (OverloadedTemplateStorage *S =
6578 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006579 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006580
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006581 const Decl *D = Storage.get<const Decl *>();
6582 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006583 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006584
Guy Benyei11169dd2012-12-18 14:30:41 +00006585 return 0;
6586}
6587
6588CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6589 if (cursor.kind != CXCursor_OverloadedDeclRef)
6590 return clang_getNullCursor();
6591
6592 if (index >= clang_getNumOverloadedDecls(cursor))
6593 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006594
Guy Benyei11169dd2012-12-18 14:30:41 +00006595 CXTranslationUnit TU = getCursorTU(cursor);
6596 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006597 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006598 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006599
6600 if (OverloadedTemplateStorage *S =
6601 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006602 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006603
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006604 const Decl *D = Storage.get<const Decl *>();
6605 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006606 // FIXME: This is, unfortunately, linear time.
6607 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6608 std::advance(Pos, index);
6609 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6610 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006611
Guy Benyei11169dd2012-12-18 14:30:41 +00006612 return clang_getNullCursor();
6613}
Michael Kruse7520cf02020-03-25 09:26:14 -05006614
6615void clang_getDefinitionSpellingAndExtent(
6616 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6617 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006618 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006619 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006620 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6621
6622 SourceManager &SM = FD->getASTContext().getSourceManager();
6623 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6624 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6625 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6626 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6627 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6628 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6629}
6630
Guy Benyei11169dd2012-12-18 14:30:41 +00006631CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6632 unsigned PieceIndex) {
6633 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006634
Guy Benyei11169dd2012-12-18 14:30:41 +00006635 switch (C.kind) {
6636 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006637 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006638 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6639 E->getQualifierLoc().getSourceRange());
6640 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006641
Guy Benyei11169dd2012-12-18 14:30:41 +00006642 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006643 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6644 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6645 Pieces =
6646 buildPieces(NameFlags, false, E->getNameInfo(),
6647 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6648 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006649 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006650
Guy Benyei11169dd2012-12-18 14:30:41 +00006651 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006652 if (const CXXOperatorCallExpr *OCE =
6653 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006654 const Expr *Callee = OCE->getCallee();
6655 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006656 Callee = ICE->getSubExpr();
6657
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006658 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006659 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6660 DRE->getQualifierLoc().getSourceRange());
6661 }
6662 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006663
Guy Benyei11169dd2012-12-18 14:30:41 +00006664 default:
6665 break;
6666 }
6667
6668 if (Pieces.empty()) {
6669 if (PieceIndex == 0)
6670 return clang_getCursorExtent(C);
6671 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006672 SourceRange R = Pieces[PieceIndex];
6673 if (R.isValid())
6674 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006676
Guy Benyei11169dd2012-12-18 14:30:41 +00006677 return clang_getNullRange();
6678}
6679
6680void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006681 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6682 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006683}
6684
Michael Kruse7520cf02020-03-25 09:26:14 -05006685void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006686 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006687 llvm::llvm_execute_on_thread(fn, user_data,
6688 stack_size == 0
6689 ? clang::DesiredStackSize
6690 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006691}
6692
Guy Benyei11169dd2012-12-18 14:30:41 +00006693//===----------------------------------------------------------------------===//
6694// Token-based Operations.
6695//===----------------------------------------------------------------------===//
6696
6697/* CXToken layout:
6698 * int_data[0]: a CXTokenKind
6699 * int_data[1]: starting token location
6700 * int_data[2]: token length
6701 * int_data[3]: reserved
6702 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6703 * otherwise unused.
6704 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006705CXTokenKind clang_getTokenKind(CXToken CXTok) {
6706 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6707}
6708
6709CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6710 switch (clang_getTokenKind(CXTok)) {
6711 case CXToken_Identifier:
6712 case CXToken_Keyword:
6713 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006714 return cxstring::createRef(
6715 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006716
6717 case CXToken_Literal: {
6718 // We have stashed the starting pointer in the ptr_data field. Use it.
6719 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006720 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006721 }
6722
6723 case CXToken_Punctuation:
6724 case CXToken_Comment:
6725 break;
6726 }
6727
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006728 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006729 LOG_BAD_TU(TU);
6730 return cxstring::createEmpty();
6731 }
6732
Guy Benyei11169dd2012-12-18 14:30:41 +00006733 // We have to find the starting buffer pointer the hard way, by
6734 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006735 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006736 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006737 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006738
6739 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006740 std::pair<FileID, unsigned> LocInfo =
6741 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006742 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006743 StringRef Buffer =
6744 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006745 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006746 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006747
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006748 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006749}
6750
6751CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006752 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006753 LOG_BAD_TU(TU);
6754 return clang_getNullLocation();
6755 }
6756
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006757 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006758 if (!CXXUnit)
6759 return clang_getNullLocation();
6760
Michael Kruse7520cf02020-03-25 09:26:14 -05006761 return cxloc::translateSourceLocation(
6762 CXXUnit->getASTContext(),
6763 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006764}
6765
6766CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006767 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006768 LOG_BAD_TU(TU);
6769 return clang_getNullRange();
6770 }
6771
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006772 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006773 if (!CXXUnit)
6774 return clang_getNullRange();
6775
Michael Kruse7520cf02020-03-25 09:26:14 -05006776 return cxloc::translateSourceRange(
6777 CXXUnit->getASTContext(),
6778 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006779}
6780
6781static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6782 SmallVectorImpl<CXToken> &CXTokens) {
6783 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006784 std::pair<FileID, unsigned> BeginLocInfo =
6785 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6786 std::pair<FileID, unsigned> EndLocInfo =
6787 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006788
6789 // Cannot tokenize across files.
6790 if (BeginLocInfo.first != EndLocInfo.first)
6791 return;
6792
6793 // Create a lexer
6794 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006795 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006796 if (Invalid)
6797 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006798
Guy Benyei11169dd2012-12-18 14:30:41 +00006799 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006800 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6801 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006802 Lex.SetCommentRetentionState(true);
6803
6804 // Lex tokens until we hit the end of the range.
6805 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6806 Token Tok;
6807 bool previousWasAt = false;
6808 do {
6809 // Lex the next token
6810 Lex.LexFromRawLexer(Tok);
6811 if (Tok.is(tok::eof))
6812 break;
6813
6814 // Initialize the CXToken.
6815 CXToken CXTok;
6816
6817 // - Common fields
6818 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6819 CXTok.int_data[2] = Tok.getLength();
6820 CXTok.int_data[3] = 0;
6821
6822 // - Kind-specific fields
6823 if (Tok.isLiteral()) {
6824 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006825 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006826 } else if (Tok.is(tok::raw_identifier)) {
6827 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006828 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006829
6830 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6831 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006832 } else {
6833 CXTok.int_data[0] =
6834 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006835 }
6836 CXTok.ptr_data = II;
6837 } else if (Tok.is(tok::comment)) {
6838 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006839 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006840 } else {
6841 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006842 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006843 }
6844 CXTokens.push_back(CXTok);
6845 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006846 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006847}
6848
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006849CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006850 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006851
6852 if (isNotUsableTU(TU)) {
6853 LOG_BAD_TU(TU);
6854 return NULL;
6855 }
6856
6857 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6858 if (!CXXUnit)
6859 return NULL;
6860
6861 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6862 if (Begin.isInvalid())
6863 return NULL;
6864 SourceManager &SM = CXXUnit->getSourceManager();
6865 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006866 DecomposedEnd.second +=
6867 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006868
Michael Kruse7520cf02020-03-25 09:26:14 -05006869 SourceLocation End =
6870 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006871
6872 SmallVector<CXToken, 32> CXTokens;
6873 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6874
6875 if (CXTokens.empty())
6876 return NULL;
6877
6878 CXTokens.resize(1);
6879 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6880
6881 memmove(Token, CXTokens.data(), sizeof(CXToken));
6882 return Token;
6883}
6884
Michael Kruse7520cf02020-03-25 09:26:14 -05006885void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6886 unsigned *NumTokens) {
6887 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006888
Guy Benyei11169dd2012-12-18 14:30:41 +00006889 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006890 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006891 if (NumTokens)
6892 *NumTokens = 0;
6893
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006894 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006895 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006896 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006897 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006898
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006899 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006900 if (!CXXUnit || !Tokens || !NumTokens)
6901 return;
6902
6903 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006904
Guy Benyei11169dd2012-12-18 14:30:41 +00006905 SourceRange R = cxloc::translateCXSourceRange(Range);
6906 if (R.isInvalid())
6907 return;
6908
6909 SmallVector<CXToken, 32> CXTokens;
6910 getTokens(CXXUnit, R, CXTokens);
6911
6912 if (CXTokens.empty())
6913 return;
6914
Serge Pavlov52525732018-02-21 02:02:39 +00006915 *Tokens = static_cast<CXToken *>(
6916 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006917 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6918 *NumTokens = CXTokens.size();
6919}
6920
Michael Kruse7520cf02020-03-25 09:26:14 -05006921void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6922 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006923 free(Tokens);
6924}
6925
Guy Benyei11169dd2012-12-18 14:30:41 +00006926//===----------------------------------------------------------------------===//
6927// Token annotation APIs.
6928//===----------------------------------------------------------------------===//
6929
Guy Benyei11169dd2012-12-18 14:30:41 +00006930static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6931 CXCursor parent,
6932 CXClientData client_data);
6933static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6934 CXClientData client_data);
6935
6936namespace {
6937class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006938 CXToken *Tokens;
6939 CXCursor *Cursors;
6940 unsigned NumTokens;
6941 unsigned TokIdx;
6942 unsigned PreprocessingTokIdx;
6943 CursorVisitor AnnotateVis;
6944 SourceManager &SrcMgr;
6945 bool HasContextSensitiveKeywords;
6946
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006947 struct PostChildrenAction {
6948 CXCursor cursor;
6949 enum Action { Invalid, Ignore, Postpone } action;
6950 };
6951 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6952
Guy Benyei11169dd2012-12-18 14:30:41 +00006953 struct PostChildrenInfo {
6954 CXCursor Cursor;
6955 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006956 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006957 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006958 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006959 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006960 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006961
6962 CXToken &getTok(unsigned Idx) {
6963 assert(Idx < NumTokens);
6964 return Tokens[Idx];
6965 }
6966 const CXToken &getTok(unsigned Idx) const {
6967 assert(Idx < NumTokens);
6968 return Tokens[Idx];
6969 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006970 bool MoreTokens() const { return TokIdx < NumTokens; }
6971 unsigned NextToken() const { return TokIdx; }
6972 void AdvanceToken() { ++TokIdx; }
6973 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006974 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006975 }
6976 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006977 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006978 }
6979 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006980 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006981 }
6982
6983 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006984 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006985 SourceRange);
6986
6987public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006988 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006989 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05006990 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
6991 PreprocessingTokIdx(0),
6992 AnnotateVis(TU, AnnotateTokensVisitor, this,
6993 /*VisitPreprocessorLast=*/true,
6994 /*VisitIncludedEntities=*/false, RegionOfInterest,
6995 /*VisitDeclsOnly=*/false,
6996 AnnotateTokensPostChildrenVisitor),
6997 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
6998 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00006999
7000 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
7001 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007002 bool IsIgnoredChildCursor(CXCursor cursor) const;
7003 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
7004
Guy Benyei11169dd2012-12-18 14:30:41 +00007005 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007006 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
7007 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
7008
Guy Benyei11169dd2012-12-18 14:30:41 +00007009 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05007010
7011 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00007012 /// context-sensitive keywords.
7013 bool hasContextSensitiveKeywords() const {
7014 return HasContextSensitiveKeywords;
7015 }
7016
Michael Kruse7520cf02020-03-25 09:26:14 -05007017 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00007018};
Michael Kruse7520cf02020-03-25 09:26:14 -05007019} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00007020
7021void AnnotateTokensWorker::AnnotateTokens() {
7022 // Walk the AST within the region of interest, annotating tokens
7023 // along the way.
7024 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007025}
Guy Benyei11169dd2012-12-18 14:30:41 +00007026
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007027bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7028 if (PostChildrenInfos.empty())
7029 return false;
7030
7031 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7032 if (ChildAction.cursor == cursor &&
7033 ChildAction.action == PostChildrenAction::Ignore) {
7034 return true;
7035 }
7036 }
7037
7038 return false;
7039}
7040
7041const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7042 if (!clang_isExpression(Cursor.kind))
7043 return nullptr;
7044
7045 const Expr *E = getCursorExpr(Cursor);
7046 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7047 const OverloadedOperatorKind Kind = OCE->getOperator();
7048 if (Kind == OO_Call || Kind == OO_Subscript)
7049 return OCE;
7050 }
7051
7052 return nullptr;
7053}
7054
7055AnnotateTokensWorker::PostChildrenActions
7056AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7057 PostChildrenActions actions;
7058
7059 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7060 // visited before the arguments to the operator call. For the Call and
7061 // Subscript operator the range of this DeclRefExpr includes the whole call
7062 // expression, so that all tokens in that range would be mapped to the
7063 // operator function, including the tokens of the arguments. To avoid that,
7064 // ensure to visit this DeclRefExpr as last node.
7065 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7066 const Expr *Callee = OCE->getCallee();
7067 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7068 const Expr *SubExpr = ICE->getSubExpr();
7069 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007070 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007071 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7072
7073 // Visit the DeclRefExpr as last.
7074 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7075 actions.push_back({cxChild, PostChildrenAction::Postpone});
7076
7077 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7078 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7079 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7080 actions.push_back({cxChild, PostChildrenAction::Ignore});
7081 }
7082 }
7083 }
7084
7085 return actions;
7086}
7087
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007088static inline void updateCursorAnnotation(CXCursor &Cursor,
7089 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007090 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007091 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007092 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007093}
7094
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007095/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007096//// between the cursor location and the source range is the same as
7097/// \arg compResult.
7098///
7099/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7100/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007101void AnnotateTokensWorker::annotateAndAdvanceTokens(
7102 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007103 while (MoreTokens()) {
7104 const unsigned I = NextToken();
7105 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007106 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7107 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007108
7109 SourceLocation TokLoc = GetTokenLoc(I);
7110 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007111 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007112 AdvanceToken();
7113 continue;
7114 }
7115 break;
7116 }
7117}
7118
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007119/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007120/// \returns true if it advanced beyond all macro tokens, false otherwise.
7121bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007122 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007123 assert(MoreTokens());
7124 assert(isFunctionMacroToken(NextToken()) &&
7125 "Should be called only for macro arg tokens");
7126
7127 // This works differently than annotateAndAdvanceTokens; because expanded
7128 // macro arguments can have arbitrary translation-unit source order, we do not
7129 // advance the token index one by one until a token fails the range test.
7130 // We only advance once past all of the macro arg tokens if all of them
7131 // pass the range test. If one of them fails we keep the token index pointing
7132 // at the start of the macro arg tokens so that the failing token will be
7133 // annotated by a subsequent annotation try.
7134
7135 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007136
Guy Benyei11169dd2012-12-18 14:30:41 +00007137 unsigned I = NextToken();
7138 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7139 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7140 if (TokLoc.isFileID())
7141 continue; // not macro arg token, it's parens or comma.
7142 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7143 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7144 Cursors[I] = updateC;
7145 } else
7146 atLeastOneCompFail = true;
7147 }
7148
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007149 if (atLeastOneCompFail)
7150 return false;
7151
7152 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7153 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007154}
7155
Michael Kruse7520cf02020-03-25 09:26:14 -05007156enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7157 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007158 SourceRange cursorRange = getRawCursorExtent(cursor);
7159 if (cursorRange.isInvalid())
7160 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007161
7162 if (IsIgnoredChildCursor(cursor))
7163 return CXChildVisit_Continue;
7164
Guy Benyei11169dd2012-12-18 14:30:41 +00007165 if (!HasContextSensitiveKeywords) {
7166 // Objective-C properties can have context-sensitive keywords.
7167 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007168 if (const ObjCPropertyDecl *Property =
7169 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7170 HasContextSensitiveKeywords =
7171 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007172 }
7173 // Objective-C methods can have context-sensitive keywords.
7174 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7175 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007176 if (const ObjCMethodDecl *Method =
7177 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007178 if (Method->getObjCDeclQualifier())
7179 HasContextSensitiveKeywords = true;
7180 else {
David Majnemer59f77922016-06-24 04:05:48 +00007181 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007182 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007183 HasContextSensitiveKeywords = true;
7184 break;
7185 }
7186 }
7187 }
7188 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007189 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007190 // C++ methods can have context-sensitive keywords.
7191 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007192 if (const CXXMethodDecl *Method =
7193 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007194 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7195 HasContextSensitiveKeywords = true;
7196 }
7197 }
7198 // C++ classes can have context-sensitive keywords.
7199 else if (cursor.kind == CXCursor_StructDecl ||
7200 cursor.kind == CXCursor_ClassDecl ||
7201 cursor.kind == CXCursor_ClassTemplate ||
7202 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007203 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007204 if (D->hasAttr<FinalAttr>())
7205 HasContextSensitiveKeywords = true;
7206 }
7207 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007208
7209 // Don't override a property annotation with its getter/setter method.
7210 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7211 parent.kind == CXCursor_ObjCPropertyDecl)
7212 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007213
7214 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007215 // Items in the preprocessing record are kept separate from items in
7216 // declarations, so we keep a separate token index.
7217 unsigned SavedTokIdx = TokIdx;
7218 TokIdx = PreprocessingTokIdx;
7219
7220 // Skip tokens up until we catch up to the beginning of the preprocessing
7221 // entry.
7222 while (MoreTokens()) {
7223 const unsigned I = NextToken();
7224 SourceLocation TokLoc = GetTokenLoc(I);
7225 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7226 case RangeBefore:
7227 AdvanceToken();
7228 continue;
7229 case RangeAfter:
7230 case RangeOverlap:
7231 break;
7232 }
7233 break;
7234 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007235
Guy Benyei11169dd2012-12-18 14:30:41 +00007236 // Look at all of the tokens within this range.
7237 while (MoreTokens()) {
7238 const unsigned I = NextToken();
7239 SourceLocation TokLoc = GetTokenLoc(I);
7240 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7241 case RangeBefore:
7242 llvm_unreachable("Infeasible");
7243 case RangeAfter:
7244 break;
7245 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007246 // For macro expansions, just note where the beginning of the macro
7247 // expansion occurs.
7248 if (cursor.kind == CXCursor_MacroExpansion) {
7249 if (TokLoc == cursorRange.getBegin())
7250 Cursors[I] = cursor;
7251 AdvanceToken();
7252 break;
7253 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007254 // We may have already annotated macro names inside macro definitions.
7255 if (Cursors[I].kind != CXCursor_MacroExpansion)
7256 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007257 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007258 continue;
7259 }
7260 break;
7261 }
7262
7263 // Save the preprocessing token index; restore the non-preprocessing
7264 // token index.
7265 PreprocessingTokIdx = TokIdx;
7266 TokIdx = SavedTokIdx;
7267 return CXChildVisit_Recurse;
7268 }
7269
7270 if (cursorRange.isInvalid())
7271 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007272
7273 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007274 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007275 const enum CXCursorKind K = clang_getCursorKind(parent);
7276 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007277 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7278 // Attributes are annotated out-of-order, skip tokens until we reach it.
7279 clang_isAttribute(cursor.kind))
7280 ? clang_getNullCursor()
7281 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007282
7283 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7284
7285 // Avoid having the cursor of an expression "overwrite" the annotation of the
7286 // variable declaration that it belongs to.
7287 // This can happen for C++ constructor expressions whose range generally
7288 // include the variable declaration, e.g.:
7289 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007290 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007291 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007292 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007293 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007294 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7295 E->getBeginLoc() == D->getLocation() &&
7296 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007297 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007298 AdvanceToken();
7299 }
7300 }
7301 }
7302
7303 // Before recursing into the children keep some state that we are going
7304 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7305 // extra work after the child nodes are visited.
7306 // Note that we don't call VisitChildren here to avoid traversing statements
7307 // code-recursively which can blow the stack.
7308
7309 PostChildrenInfo Info;
7310 Info.Cursor = cursor;
7311 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007312 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007313 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007314 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007315 PostChildrenInfos.push_back(Info);
7316
7317 return CXChildVisit_Recurse;
7318}
7319
7320bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7321 if (PostChildrenInfos.empty())
7322 return false;
7323 const PostChildrenInfo &Info = PostChildrenInfos.back();
7324 if (!clang_equalCursors(Info.Cursor, cursor))
7325 return false;
7326
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007327 HandlePostPonedChildCursors(Info);
7328
Guy Benyei11169dd2012-12-18 14:30:41 +00007329 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7330 const unsigned AfterChildren = NextToken();
7331 SourceRange cursorRange = Info.CursorRange;
7332
7333 // Scan the tokens that are at the end of the cursor, but are not captured
7334 // but the child cursors.
7335 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7336
7337 // Scan the tokens that are at the beginning of the cursor, but are not
7338 // capture by the child cursors.
7339 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7340 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7341 break;
7342
7343 Cursors[I] = cursor;
7344 }
7345
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007346 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7347 // encountered the attribute cursor.
7348 if (clang_isAttribute(cursor.kind))
7349 TokIdx = Info.BeforeReachingCursorIdx;
7350
Guy Benyei11169dd2012-12-18 14:30:41 +00007351 PostChildrenInfos.pop_back();
7352 return false;
7353}
7354
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007355void AnnotateTokensWorker::HandlePostPonedChildCursors(
7356 const PostChildrenInfo &Info) {
7357 for (const auto &ChildAction : Info.ChildActions) {
7358 if (ChildAction.action == PostChildrenAction::Postpone) {
7359 HandlePostPonedChildCursor(ChildAction.cursor,
7360 Info.BeforeChildrenTokenIdx);
7361 }
7362 }
7363}
7364
7365void AnnotateTokensWorker::HandlePostPonedChildCursor(
7366 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007367 unsigned I = StartTokenIndex;
7368
7369 // The bracket tokens of a Call or Subscript operator are mapped to
7370 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7371 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7372 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007373 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7374 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007375 if (clang_Range_isNull(CXRefNameRange))
7376 break; // All ranges handled.
7377
7378 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7379 while (I < NumTokens) {
7380 const SourceLocation TokenLocation = GetTokenLoc(I);
7381 if (!TokenLocation.isValid())
7382 break;
7383
7384 // Adapt the end range, because LocationCompare() reports
7385 // RangeOverlap even for the not-inclusive end location.
7386 const SourceLocation fixedEnd =
7387 RefNameRange.getEnd().getLocWithOffset(-1);
7388 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7389
7390 const RangeComparisonResult ComparisonResult =
7391 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7392
7393 if (ComparisonResult == RangeOverlap) {
7394 Cursors[I++] = Cursor;
7395 } else if (ComparisonResult == RangeBefore) {
7396 ++I; // Not relevant token, check next one.
7397 } else if (ComparisonResult == RangeAfter) {
7398 break; // All tokens updated for current range, check next.
7399 }
7400 }
7401 }
7402}
7403
Guy Benyei11169dd2012-12-18 14:30:41 +00007404static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7405 CXCursor parent,
7406 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007407 return static_cast<AnnotateTokensWorker *>(client_data)
7408 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007409}
7410
7411static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7412 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007413 return static_cast<AnnotateTokensWorker *>(client_data)
7414 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007415}
7416
7417namespace {
7418
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007419/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007420/// and mark tokens that are macro arguments. This info is used by the
7421/// AnnotateTokensWorker.
7422class MarkMacroArgTokensVisitor {
7423 SourceManager &SM;
7424 CXToken *Tokens;
7425 unsigned NumTokens;
7426 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007427
Guy Benyei11169dd2012-12-18 14:30:41 +00007428public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007429 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7430 unsigned numTokens)
7431 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007432
7433 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7434 if (cursor.kind != CXCursor_MacroExpansion)
7435 return CXChildVisit_Continue;
7436
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007437 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007438 if (macroRange.getBegin() == macroRange.getEnd())
7439 return CXChildVisit_Continue; // it's not a function macro.
7440
7441 for (; CurIdx < NumTokens; ++CurIdx) {
7442 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7443 macroRange.getBegin()))
7444 break;
7445 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007446
Guy Benyei11169dd2012-12-18 14:30:41 +00007447 if (CurIdx == NumTokens)
7448 return CXChildVisit_Break;
7449
7450 for (; CurIdx < NumTokens; ++CurIdx) {
7451 SourceLocation tokLoc = getTokenLoc(CurIdx);
7452 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7453 break;
7454
7455 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7456 }
7457
7458 if (CurIdx == NumTokens)
7459 return CXChildVisit_Break;
7460
7461 return CXChildVisit_Continue;
7462 }
7463
7464private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007465 CXToken &getTok(unsigned Idx) {
7466 assert(Idx < NumTokens);
7467 return Tokens[Idx];
7468 }
7469 const CXToken &getTok(unsigned Idx) const {
7470 assert(Idx < NumTokens);
7471 return Tokens[Idx];
7472 }
7473
Guy Benyei11169dd2012-12-18 14:30:41 +00007474 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007475 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007476 }
7477
7478 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7479 // The third field is reserved and currently not used. Use it here
7480 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007481 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007482 }
7483};
7484
7485} // end anonymous namespace
7486
7487static CXChildVisitResult
7488MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7489 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007490 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7491 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007492}
7493
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007494/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007495/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007496static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7497 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007498 if (NextIdx >= NumTokens)
7499 return true;
7500
7501 ++NextIdx;
7502 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007503 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007504}
7505
Guy Benyei11169dd2012-12-18 14:30:41 +00007506static void annotatePreprocessorTokens(CXTranslationUnit TU,
7507 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007508 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007509 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007510 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007511
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007512 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007513 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007514 std::pair<FileID, unsigned> BeginLocInfo =
7515 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7516 std::pair<FileID, unsigned> EndLocInfo =
7517 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007518
7519 if (BeginLocInfo.first != EndLocInfo.first)
7520 return;
7521
7522 StringRef Buffer;
7523 bool Invalid = false;
7524 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7525 if (Buffer.empty() || Invalid)
7526 return;
7527
7528 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007529 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7530 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007531 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007532
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007533 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007534 // Lex tokens in raw mode until we hit the end of the range, to avoid
7535 // entering #includes or expanding macros.
7536 while (true) {
7537 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007538 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7539 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007540 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007541 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007542 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7543
Guy Benyei11169dd2012-12-18 14:30:41 +00007544 reprocess:
7545 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007546 // We have found a preprocessing directive. Annotate the tokens
7547 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007548 //
7549 // FIXME: Some simple tests here could identify macro definitions and
7550 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007551
7552 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007553 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7554 break;
7555
Craig Topper69186e72014-06-08 08:38:04 +00007556 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007557 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007558 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7559 break;
7560
7561 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007562 IdentifierInfo &II =
7563 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007564 SourceLocation MappedTokLoc =
7565 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7566 MI = getMacroInfo(II, MappedTokLoc, TU);
7567 }
7568 }
7569
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007570 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007571 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007572 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7573 finished = true;
7574 break;
7575 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007576 // If we are in a macro definition, check if the token was ever a
7577 // macro name and annotate it if that's the case.
7578 if (MI) {
7579 SourceLocation SaveLoc = Tok.getLocation();
7580 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007581 MacroDefinitionRecord *MacroDef =
7582 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007583 Tok.setLocation(SaveLoc);
7584 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007585 Cursors[NextIdx - 1] =
7586 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007587 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007588 } while (!Tok.isAtStartOfLine());
7589
Michael Kruse7520cf02020-03-25 09:26:14 -05007590 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007591 assert(TokIdx <= LastIdx);
7592 SourceLocation EndLoc =
7593 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7594 CXCursor Cursor =
7595 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7596
7597 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007598 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007599
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007600 if (finished)
7601 break;
7602 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007603 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007604 }
7605}
7606
7607// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007608static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7609 CXToken *Tokens, unsigned NumTokens,
7610 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007611 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007612 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7613 setThreadBackgroundPriority();
7614
7615 // Determine the region of interest, which contains all of the tokens.
7616 SourceRange RegionOfInterest;
7617 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007618 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7619 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7620 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007621
Guy Benyei11169dd2012-12-18 14:30:41 +00007622 // Relex the tokens within the source range to look for preprocessing
7623 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007624 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007625
7626 // If begin location points inside a macro argument, set it to the expansion
7627 // location so we can have the full context when annotating semantically.
7628 {
7629 SourceManager &SM = CXXUnit->getSourceManager();
7630 SourceLocation Loc =
7631 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7632 if (Loc.isMacroID())
7633 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7634 }
7635
Guy Benyei11169dd2012-12-18 14:30:41 +00007636 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7637 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007638 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7639 NumTokens);
7640 CursorVisitor MacroArgMarker(
7641 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7642 /*VisitPreprocessorLast=*/true,
7643 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007644 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7645 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007646
Guy Benyei11169dd2012-12-18 14:30:41 +00007647 // Annotate all of the source locations in the region of interest that map to
7648 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007649 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007650
Guy Benyei11169dd2012-12-18 14:30:41 +00007651 // FIXME: We use a ridiculous stack size here because the data-recursion
7652 // algorithm uses a large stack frame than the non-data recursive version,
7653 // and AnnotationTokensWorker currently transforms the data-recursion
7654 // algorithm back into a traditional recursion by explicitly calling
7655 // VisitChildren(). We will need to remove this explicit recursive call.
7656 W.AnnotateTokens();
7657
7658 // If we ran into any entities that involve context-sensitive keywords,
7659 // take another pass through the tokens to mark them as such.
7660 if (W.hasContextSensitiveKeywords()) {
7661 for (unsigned I = 0; I != NumTokens; ++I) {
7662 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7663 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007664
Guy Benyei11169dd2012-12-18 14:30:41 +00007665 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7666 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007667 if (const ObjCPropertyDecl *Property =
7668 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007669 if (Property->getPropertyAttributesAsWritten() != 0 &&
7670 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007671 .Case("readonly", true)
7672 .Case("assign", true)
7673 .Case("unsafe_unretained", true)
7674 .Case("readwrite", true)
7675 .Case("retain", true)
7676 .Case("copy", true)
7677 .Case("nonatomic", true)
7678 .Case("atomic", true)
7679 .Case("getter", true)
7680 .Case("setter", true)
7681 .Case("strong", true)
7682 .Case("weak", true)
7683 .Case("class", true)
7684 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007685 Tokens[I].int_data[0] = CXToken_Keyword;
7686 }
7687 continue;
7688 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007689
Guy Benyei11169dd2012-12-18 14:30:41 +00007690 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7691 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7692 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7693 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007694 .Case("in", true)
7695 .Case("out", true)
7696 .Case("inout", true)
7697 .Case("oneway", true)
7698 .Case("bycopy", true)
7699 .Case("byref", true)
7700 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007701 Tokens[I].int_data[0] = CXToken_Keyword;
7702 continue;
7703 }
7704
7705 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7706 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7707 Tokens[I].int_data[0] = CXToken_Keyword;
7708 continue;
7709 }
7710 }
7711 }
7712}
7713
Michael Kruse7520cf02020-03-25 09:26:14 -05007714void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7715 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007716 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007717 LOG_BAD_TU(TU);
7718 return;
7719 }
7720 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007721 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007722 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007723 }
7724
7725 LOG_FUNC_SECTION {
7726 *Log << TU << ' ';
7727 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007728 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007729 *Log << clang_getRange(bloc, eloc);
7730 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007731
7732 // Any token we don't specifically annotate will have a NULL cursor.
7733 CXCursor C = clang_getNullCursor();
7734 for (unsigned I = 0; I != NumTokens; ++I)
7735 Cursors[I] = C;
7736
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007737 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007738 if (!CXXUnit)
7739 return;
7740
7741 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007742
7743 auto AnnotateTokensImpl = [=]() {
7744 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7745 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007746 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007747 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007748 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7749 }
7750}
7751
Guy Benyei11169dd2012-12-18 14:30:41 +00007752//===----------------------------------------------------------------------===//
7753// Operations for querying linkage of a cursor.
7754//===----------------------------------------------------------------------===//
7755
Guy Benyei11169dd2012-12-18 14:30:41 +00007756CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7757 if (!clang_isDeclaration(cursor.kind))
7758 return CXLinkage_Invalid;
7759
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007760 const Decl *D = cxcursor::getCursorDecl(cursor);
7761 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007762 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007763 case NoLinkage:
7764 case VisibleNoLinkage:
7765 return CXLinkage_NoLinkage;
7766 case ModuleInternalLinkage:
7767 case InternalLinkage:
7768 return CXLinkage_Internal;
7769 case UniqueExternalLinkage:
7770 return CXLinkage_UniqueExternal;
7771 case ModuleLinkage:
7772 case ExternalLinkage:
7773 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007774 };
7775
7776 return CXLinkage_Invalid;
7777}
Guy Benyei11169dd2012-12-18 14:30:41 +00007778
7779//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007780// Operations for querying visibility of a cursor.
7781//===----------------------------------------------------------------------===//
7782
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007783CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7784 if (!clang_isDeclaration(cursor.kind))
7785 return CXVisibility_Invalid;
7786
7787 const Decl *D = cxcursor::getCursorDecl(cursor);
7788 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7789 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007790 case HiddenVisibility:
7791 return CXVisibility_Hidden;
7792 case ProtectedVisibility:
7793 return CXVisibility_Protected;
7794 case DefaultVisibility:
7795 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007796 };
7797
7798 return CXVisibility_Invalid;
7799}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007800
7801//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007802// Operations for querying language of a cursor.
7803//===----------------------------------------------------------------------===//
7804
7805static CXLanguageKind getDeclLanguage(const Decl *D) {
7806 if (!D)
7807 return CXLanguage_C;
7808
7809 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007810 default:
7811 break;
7812 case Decl::ImplicitParam:
7813 case Decl::ObjCAtDefsField:
7814 case Decl::ObjCCategory:
7815 case Decl::ObjCCategoryImpl:
7816 case Decl::ObjCCompatibleAlias:
7817 case Decl::ObjCImplementation:
7818 case Decl::ObjCInterface:
7819 case Decl::ObjCIvar:
7820 case Decl::ObjCMethod:
7821 case Decl::ObjCProperty:
7822 case Decl::ObjCPropertyImpl:
7823 case Decl::ObjCProtocol:
7824 case Decl::ObjCTypeParam:
7825 return CXLanguage_ObjC;
7826 case Decl::CXXConstructor:
7827 case Decl::CXXConversion:
7828 case Decl::CXXDestructor:
7829 case Decl::CXXMethod:
7830 case Decl::CXXRecord:
7831 case Decl::ClassTemplate:
7832 case Decl::ClassTemplatePartialSpecialization:
7833 case Decl::ClassTemplateSpecialization:
7834 case Decl::Friend:
7835 case Decl::FriendTemplate:
7836 case Decl::FunctionTemplate:
7837 case Decl::LinkageSpec:
7838 case Decl::Namespace:
7839 case Decl::NamespaceAlias:
7840 case Decl::NonTypeTemplateParm:
7841 case Decl::StaticAssert:
7842 case Decl::TemplateTemplateParm:
7843 case Decl::TemplateTypeParm:
7844 case Decl::UnresolvedUsingTypename:
7845 case Decl::UnresolvedUsingValue:
7846 case Decl::Using:
7847 case Decl::UsingDirective:
7848 case Decl::UsingShadow:
7849 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007850 }
7851
7852 return CXLanguage_C;
7853}
7854
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007855static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7856 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007857 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007858
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007859 switch (D->getAvailability()) {
7860 case AR_Available:
7861 case AR_NotYetIntroduced:
7862 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007863 return getCursorAvailabilityForDecl(
7864 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007865 return CXAvailability_Available;
7866
7867 case AR_Deprecated:
7868 return CXAvailability_Deprecated;
7869
7870 case AR_Unavailable:
7871 return CXAvailability_NotAvailable;
7872 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007873
7874 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007875}
7876
Guy Benyei11169dd2012-12-18 14:30:41 +00007877enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7878 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007879 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7880 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007881
7882 return CXAvailability_Available;
7883}
7884
7885static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007886 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007887 if (In.empty())
7888 return Out;
7889
7890 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007891
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007892 Optional<unsigned> Minor = In.getMinor();
7893 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007894 Out.Minor = *Minor;
7895 else
7896 return Out;
7897
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007898 Optional<unsigned> Subminor = In.getSubminor();
7899 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007900 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007901
Guy Benyei11169dd2012-12-18 14:30:41 +00007902 return Out;
7903}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007904
Alex Lorenz1345ea22017-06-12 19:06:30 +00007905static void getCursorPlatformAvailabilityForDecl(
7906 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7907 int *always_unavailable, CXString *unavailable_message,
7908 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007909 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007910 for (auto A : D->attrs()) {
7911 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007912 HadAvailAttr = true;
7913 if (always_deprecated)
7914 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007915 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007916 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007917 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007918 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007919 continue;
7920 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007921
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007922 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007923 HadAvailAttr = true;
7924 if (always_unavailable)
7925 *always_unavailable = 1;
7926 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007927 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007928 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7929 }
7930 continue;
7931 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007932
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007933 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007934 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007935 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007936 }
7937 }
7938
7939 if (!HadAvailAttr)
7940 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7941 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007942 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7943 deprecated_message, always_unavailable, unavailable_message,
7944 AvailabilityAttrs);
7945
7946 if (AvailabilityAttrs.empty())
7947 return;
7948
Michael Kruse7520cf02020-03-25 09:26:14 -05007949 llvm::sort(
7950 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7951 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7952 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007953 ASTContext &Ctx = D->getASTContext();
7954 auto It = std::unique(
7955 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7956 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7957 if (LHS->getPlatform() != RHS->getPlatform())
7958 return false;
7959
7960 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7961 LHS->getDeprecated() == RHS->getDeprecated() &&
7962 LHS->getObsoleted() == RHS->getObsoleted() &&
7963 LHS->getMessage() == RHS->getMessage() &&
7964 LHS->getReplacement() == RHS->getReplacement())
7965 return true;
7966
7967 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
7968 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
7969 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
7970 return false;
7971
7972 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
7973 LHS->setIntroduced(Ctx, RHS->getIntroduced());
7974
7975 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
7976 LHS->setDeprecated(Ctx, RHS->getDeprecated());
7977 if (LHS->getMessage().empty())
7978 LHS->setMessage(Ctx, RHS->getMessage());
7979 if (LHS->getReplacement().empty())
7980 LHS->setReplacement(Ctx, RHS->getReplacement());
7981 }
7982
7983 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
7984 LHS->setObsoleted(Ctx, RHS->getObsoleted());
7985 if (LHS->getMessage().empty())
7986 LHS->setMessage(Ctx, RHS->getMessage());
7987 if (LHS->getReplacement().empty())
7988 LHS->setReplacement(Ctx, RHS->getReplacement());
7989 }
7990
7991 return true;
7992 });
7993 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007994}
7995
Alex Lorenz1345ea22017-06-12 19:06:30 +00007996int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00007997 CXString *deprecated_message,
7998 int *always_unavailable,
7999 CXString *unavailable_message,
8000 CXPlatformAvailability *availability,
8001 int availability_size) {
8002 if (always_deprecated)
8003 *always_deprecated = 0;
8004 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008005 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00008006 if (always_unavailable)
8007 *always_unavailable = 0;
8008 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008009 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008010
Guy Benyei11169dd2012-12-18 14:30:41 +00008011 if (!clang_isDeclaration(cursor.kind))
8012 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008013
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008014 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00008015 if (!D)
8016 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008017
Alex Lorenz1345ea22017-06-12 19:06:30 +00008018 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
8019 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8020 always_unavailable, unavailable_message,
8021 AvailabilityAttrs);
8022 for (const auto &Avail :
8023 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8024 .take_front(availability_size))) {
8025 availability[Avail.index()].Platform =
8026 cxstring::createDup(Avail.value()->getPlatform()->getName());
8027 availability[Avail.index()].Introduced =
8028 convertVersion(Avail.value()->getIntroduced());
8029 availability[Avail.index()].Deprecated =
8030 convertVersion(Avail.value()->getDeprecated());
8031 availability[Avail.index()].Obsoleted =
8032 convertVersion(Avail.value()->getObsoleted());
8033 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8034 availability[Avail.index()].Message =
8035 cxstring::createDup(Avail.value()->getMessage());
8036 }
8037
8038 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008039}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008040
Guy Benyei11169dd2012-12-18 14:30:41 +00008041void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8042 clang_disposeString(availability->Platform);
8043 clang_disposeString(availability->Message);
8044}
8045
8046CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8047 if (clang_isDeclaration(cursor.kind))
8048 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8049
8050 return CXLanguage_Invalid;
8051}
8052
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008053CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8054 const Decl *D = cxcursor::getCursorDecl(cursor);
8055 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8056 switch (VD->getTLSKind()) {
8057 case VarDecl::TLS_None:
8058 return CXTLS_None;
8059 case VarDecl::TLS_Dynamic:
8060 return CXTLS_Dynamic;
8061 case VarDecl::TLS_Static:
8062 return CXTLS_Static;
8063 }
8064 }
8065
8066 return CXTLS_None;
8067}
8068
Michael Kruse7520cf02020-03-25 09:26:14 -05008069/// If the given cursor is the "templated" declaration
8070/// describing a class or function template, return the class or
8071/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008072static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008073 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008074 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008075
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008076 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008077 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8078 return FunTmpl;
8079
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008080 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008081 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8082 return ClassTmpl;
8083
8084 return D;
8085}
8086
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008087enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8088 StorageClass sc = SC_None;
8089 const Decl *D = getCursorDecl(C);
8090 if (D) {
8091 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8092 sc = FD->getStorageClass();
8093 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8094 sc = VD->getStorageClass();
8095 } else {
8096 return CX_SC_Invalid;
8097 }
8098 } else {
8099 return CX_SC_Invalid;
8100 }
8101 switch (sc) {
8102 case SC_None:
8103 return CX_SC_None;
8104 case SC_Extern:
8105 return CX_SC_Extern;
8106 case SC_Static:
8107 return CX_SC_Static;
8108 case SC_PrivateExtern:
8109 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008110 case SC_Auto:
8111 return CX_SC_Auto;
8112 case SC_Register:
8113 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008114 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008115 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008116}
8117
Guy Benyei11169dd2012-12-18 14:30:41 +00008118CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8119 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008120 if (const Decl *D = getCursorDecl(cursor)) {
8121 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008122 if (!DC)
8123 return clang_getNullCursor();
8124
Michael Kruse7520cf02020-03-25 09:26:14 -05008125 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008126 getCursorTU(cursor));
8127 }
8128 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008129
Guy Benyei11169dd2012-12-18 14:30:41 +00008130 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008131 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008132 return MakeCXCursor(D, getCursorTU(cursor));
8133 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008134
Guy Benyei11169dd2012-12-18 14:30:41 +00008135 return clang_getNullCursor();
8136}
8137
8138CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8139 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008140 if (const Decl *D = getCursorDecl(cursor)) {
8141 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008142 if (!DC)
8143 return clang_getNullCursor();
8144
Michael Kruse7520cf02020-03-25 09:26:14 -05008145 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008146 getCursorTU(cursor));
8147 }
8148 }
8149
Michael Kruse7520cf02020-03-25 09:26:14 -05008150 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008151 // statement or expression, so we return nothing.
8152 return clang_getNullCursor();
8153}
8154
8155CXFile clang_getIncludedFile(CXCursor cursor) {
8156 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008157 return nullptr;
8158
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008159 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008160 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008161}
8162
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008163unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8164 if (C.kind != CXCursor_ObjCPropertyDecl)
8165 return CXObjCPropertyAttr_noattr;
8166
8167 unsigned Result = CXObjCPropertyAttr_noattr;
8168 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008169 ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008170
Michael Kruse7520cf02020-03-25 09:26:14 -05008171#define SET_CXOBJCPROP_ATTR(A) \
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008172 if (Attr & ObjCPropertyAttribute::kind_##A) \
Michael Kruse7520cf02020-03-25 09:26:14 -05008173 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008174 SET_CXOBJCPROP_ATTR(readonly);
8175 SET_CXOBJCPROP_ATTR(getter);
8176 SET_CXOBJCPROP_ATTR(assign);
8177 SET_CXOBJCPROP_ATTR(readwrite);
8178 SET_CXOBJCPROP_ATTR(retain);
8179 SET_CXOBJCPROP_ATTR(copy);
8180 SET_CXOBJCPROP_ATTR(nonatomic);
8181 SET_CXOBJCPROP_ATTR(setter);
8182 SET_CXOBJCPROP_ATTR(atomic);
8183 SET_CXOBJCPROP_ATTR(weak);
8184 SET_CXOBJCPROP_ATTR(strong);
8185 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008186 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008187#undef SET_CXOBJCPROP_ATTR
8188
8189 return Result;
8190}
8191
Michael Wu6e88f532018-08-03 05:38:29 +00008192CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8193 if (C.kind != CXCursor_ObjCPropertyDecl)
8194 return cxstring::createNull();
8195
8196 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8197 Selector sel = PD->getGetterName();
8198 if (sel.isNull())
8199 return cxstring::createNull();
8200
8201 return cxstring::createDup(sel.getAsString());
8202}
8203
8204CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8205 if (C.kind != CXCursor_ObjCPropertyDecl)
8206 return cxstring::createNull();
8207
8208 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8209 Selector sel = PD->getSetterName();
8210 if (sel.isNull())
8211 return cxstring::createNull();
8212
8213 return cxstring::createDup(sel.getAsString());
8214}
8215
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008216unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8217 if (!clang_isDeclaration(C.kind))
8218 return CXObjCDeclQualifier_None;
8219
8220 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8221 const Decl *D = getCursorDecl(C);
8222 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8223 QT = MD->getObjCDeclQualifier();
8224 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8225 QT = PD->getObjCDeclQualifier();
8226 if (QT == Decl::OBJC_TQ_None)
8227 return CXObjCDeclQualifier_None;
8228
8229 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008230 if (QT & Decl::OBJC_TQ_In)
8231 Result |= CXObjCDeclQualifier_In;
8232 if (QT & Decl::OBJC_TQ_Inout)
8233 Result |= CXObjCDeclQualifier_Inout;
8234 if (QT & Decl::OBJC_TQ_Out)
8235 Result |= CXObjCDeclQualifier_Out;
8236 if (QT & Decl::OBJC_TQ_Bycopy)
8237 Result |= CXObjCDeclQualifier_Bycopy;
8238 if (QT & Decl::OBJC_TQ_Byref)
8239 Result |= CXObjCDeclQualifier_Byref;
8240 if (QT & Decl::OBJC_TQ_Oneway)
8241 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008242
8243 return Result;
8244}
8245
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008246unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8247 if (!clang_isDeclaration(C.kind))
8248 return 0;
8249
8250 const Decl *D = getCursorDecl(C);
8251 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8252 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8253 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8254 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8255
8256 return 0;
8257}
8258
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008259unsigned clang_Cursor_isVariadic(CXCursor C) {
8260 if (!clang_isDeclaration(C.kind))
8261 return 0;
8262
8263 const Decl *D = getCursorDecl(C);
8264 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8265 return FD->isVariadic();
8266 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8267 return MD->isVariadic();
8268
8269 return 0;
8270}
8271
Michael Kruse7520cf02020-03-25 09:26:14 -05008272unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8273 CXString *definedIn,
8274 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008275 if (!clang_isDeclaration(C.kind))
8276 return 0;
8277
8278 const Decl *D = getCursorDecl(C);
8279
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008280 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008281 if (language)
8282 *language = cxstring::createDup(attr->getLanguage());
8283 if (definedIn)
8284 *definedIn = cxstring::createDup(attr->getDefinedIn());
8285 if (isGenerated)
8286 *isGenerated = attr->getGeneratedDeclaration();
8287 return 1;
8288 }
8289 return 0;
8290}
8291
Guy Benyei11169dd2012-12-18 14:30:41 +00008292CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8293 if (!clang_isDeclaration(C.kind))
8294 return clang_getNullRange();
8295
8296 const Decl *D = getCursorDecl(C);
8297 ASTContext &Context = getCursorContext(C);
8298 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8299 if (!RC)
8300 return clang_getNullRange();
8301
8302 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8303}
8304
8305CXString clang_Cursor_getRawCommentText(CXCursor C) {
8306 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008307 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008308
8309 const Decl *D = getCursorDecl(C);
8310 ASTContext &Context = getCursorContext(C);
8311 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008312 StringRef RawText =
8313 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008314
8315 // Don't duplicate the string because RawText points directly into source
8316 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008317 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008318}
8319
8320CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8321 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008322 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008323
8324 const Decl *D = getCursorDecl(C);
8325 const ASTContext &Context = getCursorContext(C);
8326 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8327
8328 if (RC) {
8329 StringRef BriefText = RC->getBriefText(Context);
8330
8331 // Don't duplicate the string because RawComment ensures that this memory
8332 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008333 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008334 }
8335
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008336 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008337}
8338
Guy Benyei11169dd2012-12-18 14:30:41 +00008339CXModule clang_Cursor_getModule(CXCursor C) {
8340 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008341 if (const ImportDecl *ImportD =
8342 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008343 return ImportD->getImportedModule();
8344 }
8345
Craig Topper69186e72014-06-08 08:38:04 +00008346 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008347}
8348
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008349CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8350 if (isNotUsableTU(TU)) {
8351 LOG_BAD_TU(TU);
8352 return nullptr;
8353 }
8354 if (!File)
8355 return nullptr;
8356 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008357
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008358 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8359 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8360 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008361
Richard Smithfeb54b62014-10-23 02:01:19 +00008362 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008363}
8364
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008365CXFile clang_Module_getASTFile(CXModule CXMod) {
8366 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008367 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008368 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008369 return const_cast<FileEntry *>(Mod->getASTFile());
8370}
8371
Guy Benyei11169dd2012-12-18 14:30:41 +00008372CXModule clang_Module_getParent(CXModule CXMod) {
8373 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008374 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008375 Module *Mod = static_cast<Module *>(CXMod);
Guy Benyei11169dd2012-12-18 14:30:41 +00008376 return Mod->Parent;
8377}
8378
8379CXString clang_Module_getName(CXModule CXMod) {
8380 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008381 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008382 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008383 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008384}
8385
8386CXString clang_Module_getFullName(CXModule CXMod) {
8387 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008388 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008389 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008390 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008391}
8392
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008393int clang_Module_isSystem(CXModule CXMod) {
8394 if (!CXMod)
8395 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008396 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008397 return Mod->IsSystem;
8398}
8399
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008400unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8401 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008402 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008403 LOG_BAD_TU(TU);
8404 return 0;
8405 }
8406 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008407 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008408 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008409 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8410 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8411 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008412}
8413
Michael Kruse7520cf02020-03-25 09:26:14 -05008414CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8415 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008416 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008417 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008418 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008419 }
8420 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008421 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008422 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008423 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008424
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008425 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8426 if (Index < TopHeaders.size())
8427 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008428
Craig Topper69186e72014-06-08 08:38:04 +00008429 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008430}
8431
Guy Benyei11169dd2012-12-18 14:30:41 +00008432//===----------------------------------------------------------------------===//
8433// C++ AST instrospection.
8434//===----------------------------------------------------------------------===//
8435
Jonathan Coe29565352016-04-27 12:48:25 +00008436unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8437 if (!clang_isDeclaration(C.kind))
8438 return 0;
8439
8440 const Decl *D = cxcursor::getCursorDecl(C);
8441 const CXXConstructorDecl *Constructor =
8442 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8443 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8444}
8445
8446unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8447 if (!clang_isDeclaration(C.kind))
8448 return 0;
8449
8450 const Decl *D = cxcursor::getCursorDecl(C);
8451 const CXXConstructorDecl *Constructor =
8452 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8453 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8454}
8455
8456unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8457 if (!clang_isDeclaration(C.kind))
8458 return 0;
8459
8460 const Decl *D = cxcursor::getCursorDecl(C);
8461 const CXXConstructorDecl *Constructor =
8462 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8463 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8464}
8465
8466unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8467 if (!clang_isDeclaration(C.kind))
8468 return 0;
8469
8470 const Decl *D = cxcursor::getCursorDecl(C);
8471 const CXXConstructorDecl *Constructor =
8472 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8473 // Passing 'false' excludes constructors marked 'explicit'.
8474 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8475}
8476
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008477unsigned clang_CXXField_isMutable(CXCursor C) {
8478 if (!clang_isDeclaration(C.kind))
8479 return 0;
8480
8481 if (const auto D = cxcursor::getCursorDecl(C))
8482 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8483 return FD->isMutable() ? 1 : 0;
8484 return 0;
8485}
8486
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008487unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8488 if (!clang_isDeclaration(C.kind))
8489 return 0;
8490
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008491 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008492 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008493 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008494 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8495}
8496
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008497unsigned clang_CXXMethod_isConst(CXCursor C) {
8498 if (!clang_isDeclaration(C.kind))
8499 return 0;
8500
8501 const Decl *D = cxcursor::getCursorDecl(C);
8502 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008503 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008504 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008505}
8506
Jonathan Coe29565352016-04-27 12:48:25 +00008507unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8508 if (!clang_isDeclaration(C.kind))
8509 return 0;
8510
8511 const Decl *D = cxcursor::getCursorDecl(C);
8512 const CXXMethodDecl *Method =
8513 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8514 return (Method && Method->isDefaulted()) ? 1 : 0;
8515}
8516
Guy Benyei11169dd2012-12-18 14:30:41 +00008517unsigned clang_CXXMethod_isStatic(CXCursor C) {
8518 if (!clang_isDeclaration(C.kind))
8519 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008520
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008521 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008522 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008523 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008524 return (Method && Method->isStatic()) ? 1 : 0;
8525}
8526
8527unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8528 if (!clang_isDeclaration(C.kind))
8529 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008530
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008531 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008532 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008533 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008534 return (Method && Method->isVirtual()) ? 1 : 0;
8535}
Guy Benyei11169dd2012-12-18 14:30:41 +00008536
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008537unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8538 if (!clang_isDeclaration(C.kind))
8539 return 0;
8540
8541 const auto *D = cxcursor::getCursorDecl(C);
8542 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8543 if (RD)
8544 RD = RD->getDefinition();
8545 return (RD && RD->isAbstract()) ? 1 : 0;
8546}
8547
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008548unsigned clang_EnumDecl_isScoped(CXCursor C) {
8549 if (!clang_isDeclaration(C.kind))
8550 return 0;
8551
8552 const Decl *D = cxcursor::getCursorDecl(C);
8553 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8554 return (Enum && Enum->isScoped()) ? 1 : 0;
8555}
8556
Guy Benyei11169dd2012-12-18 14:30:41 +00008557//===----------------------------------------------------------------------===//
8558// Attribute introspection.
8559//===----------------------------------------------------------------------===//
8560
Guy Benyei11169dd2012-12-18 14:30:41 +00008561CXType clang_getIBOutletCollectionType(CXCursor C) {
8562 if (C.kind != CXCursor_IBOutletCollectionAttr)
8563 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008564
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008565 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008566 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8567
8568 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008569}
Guy Benyei11169dd2012-12-18 14:30:41 +00008570
8571//===----------------------------------------------------------------------===//
8572// Inspecting memory usage.
8573//===----------------------------------------------------------------------===//
8574
8575typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8576
8577static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008578 enum CXTUResourceUsageKind k,
8579 unsigned long amount) {
8580 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008581 entries.push_back(entry);
8582}
8583
Guy Benyei11169dd2012-12-18 14:30:41 +00008584const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8585 const char *str = "";
8586 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008587 case CXTUResourceUsage_AST:
8588 str = "ASTContext: expressions, declarations, and types";
8589 break;
8590 case CXTUResourceUsage_Identifiers:
8591 str = "ASTContext: identifiers";
8592 break;
8593 case CXTUResourceUsage_Selectors:
8594 str = "ASTContext: selectors";
8595 break;
8596 case CXTUResourceUsage_GlobalCompletionResults:
8597 str = "Code completion: cached global results";
8598 break;
8599 case CXTUResourceUsage_SourceManagerContentCache:
8600 str = "SourceManager: content cache allocator";
8601 break;
8602 case CXTUResourceUsage_AST_SideTables:
8603 str = "ASTContext: side tables";
8604 break;
8605 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8606 str = "SourceManager: malloc'ed memory buffers";
8607 break;
8608 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8609 str = "SourceManager: mmap'ed memory buffers";
8610 break;
8611 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8612 str = "ExternalASTSource: malloc'ed memory buffers";
8613 break;
8614 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8615 str = "ExternalASTSource: mmap'ed memory buffers";
8616 break;
8617 case CXTUResourceUsage_Preprocessor:
8618 str = "Preprocessor: malloc'ed memory";
8619 break;
8620 case CXTUResourceUsage_PreprocessingRecord:
8621 str = "Preprocessor: PreprocessingRecord";
8622 break;
8623 case CXTUResourceUsage_SourceManager_DataStructures:
8624 str = "SourceManager: data structures and tables";
8625 break;
8626 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8627 str = "Preprocessor: header search tables";
8628 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008629 }
8630 return str;
8631}
8632
8633CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008634 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008635 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008636 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008637 return usage;
8638 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008639
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008640 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008641 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008642 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008643
Guy Benyei11169dd2012-12-18 14:30:41 +00008644 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008645 createCXTUResourceUsageEntry(
8646 *entries, CXTUResourceUsage_AST,
8647 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008648
8649 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008650 createCXTUResourceUsageEntry(
8651 *entries, CXTUResourceUsage_Identifiers,
8652 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008653
8654 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008655 createCXTUResourceUsageEntry(
8656 *entries, CXTUResourceUsage_Selectors,
8657 (unsigned long)astContext.Selectors.getTotalMemory());
8658
Guy Benyei11169dd2012-12-18 14:30:41 +00008659 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008660 createCXTUResourceUsageEntry(
8661 *entries, CXTUResourceUsage_AST_SideTables,
8662 (unsigned long)astContext.getSideTableAllocatedMemory());
8663
Guy Benyei11169dd2012-12-18 14:30:41 +00008664 // How much memory is used for caching global code completion results?
8665 unsigned long completionBytes = 0;
8666 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008667 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008668 completionBytes = completionAllocator->getTotalMemory();
8669 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008670 createCXTUResourceUsageEntry(
8671 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8672
Guy Benyei11169dd2012-12-18 14:30:41 +00008673 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008674 createCXTUResourceUsageEntry(
8675 *entries, CXTUResourceUsage_SourceManagerContentCache,
8676 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8677
Guy Benyei11169dd2012-12-18 14:30:41 +00008678 // How much memory is being used by the MemoryBuffer's in SourceManager?
8679 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008680 astUnit->getSourceManager().getMemoryBufferSizes();
8681
Guy Benyei11169dd2012-12-18 14:30:41 +00008682 createCXTUResourceUsageEntry(*entries,
8683 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008684 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008685 createCXTUResourceUsageEntry(*entries,
8686 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008687 (unsigned long)srcBufs.mmap_bytes);
8688 createCXTUResourceUsageEntry(
8689 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8690 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8691
Guy Benyei11169dd2012-12-18 14:30:41 +00008692 // How much memory is being used by the ExternalASTSource?
8693 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8694 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008695 esrc->getMemoryBufferSizes();
8696
8697 createCXTUResourceUsageEntry(
8698 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8699 (unsigned long)sizes.malloc_bytes);
8700 createCXTUResourceUsageEntry(
8701 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8702 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008703 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008704
Guy Benyei11169dd2012-12-18 14:30:41 +00008705 // How much memory is being used by the Preprocessor?
8706 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008707 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008708 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008709
Guy Benyei11169dd2012-12-18 14:30:41 +00008710 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8711 createCXTUResourceUsageEntry(*entries,
8712 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008713 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008714 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008715
Guy Benyei11169dd2012-12-18 14:30:41 +00008716 createCXTUResourceUsageEntry(*entries,
8717 CXTUResourceUsage_Preprocessor_HeaderSearch,
8718 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008719
Michael Kruse7520cf02020-03-25 09:26:14 -05008720 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8721 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008722 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008723 return usage;
8724}
8725
8726void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8727 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008728 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008729}
8730
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008731CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8732 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008733 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008734 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008735
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008736 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008737 LOG_BAD_TU(TU);
8738 return skipped;
8739 }
8740
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008741 if (!file)
8742 return skipped;
8743
8744 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008745 PreprocessingRecord *ppRec =
8746 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008747 if (!ppRec)
8748 return skipped;
8749
8750 ASTContext &Ctx = astUnit->getASTContext();
8751 SourceManager &sm = Ctx.getSourceManager();
8752 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8753 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008754 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008755
8756 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8757 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008758 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8759 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008760 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008761 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8762 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008763 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008764 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8765 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008766 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008767 }
8768
8769 skipped->count = wantedRanges.size();
8770 skipped->ranges = new CXSourceRange[skipped->count];
8771 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8772 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8773
8774 return skipped;
8775}
8776
Cameron Desrochersd8091282016-08-18 15:43:55 +00008777CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8778 CXSourceRangeList *skipped = new CXSourceRangeList;
8779 skipped->count = 0;
8780 skipped->ranges = nullptr;
8781
8782 if (isNotUsableTU(TU)) {
8783 LOG_BAD_TU(TU);
8784 return skipped;
8785 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008786
Cameron Desrochersd8091282016-08-18 15:43:55 +00008787 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008788 PreprocessingRecord *ppRec =
8789 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008790 if (!ppRec)
8791 return skipped;
8792
8793 ASTContext &Ctx = astUnit->getASTContext();
8794
8795 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8796
8797 skipped->count = SkippedRanges.size();
8798 skipped->ranges = new CXSourceRange[skipped->count];
8799 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8800 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8801
8802 return skipped;
8803}
8804
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008805void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8806 if (ranges) {
8807 delete[] ranges->ranges;
8808 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008809 }
8810}
8811
Guy Benyei11169dd2012-12-18 14:30:41 +00008812void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8813 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8814 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008815 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008816 clang_getTUResourceUsageName(Usage.entries[I].kind),
8817 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008818
Guy Benyei11169dd2012-12-18 14:30:41 +00008819 clang_disposeCXTUResourceUsage(Usage);
8820}
8821
8822//===----------------------------------------------------------------------===//
8823// Misc. utility functions.
8824//===----------------------------------------------------------------------===//
8825
Richard Smith0a7b2972018-07-03 21:34:13 +00008826/// Default to using our desired 8 MB stack size on "safety" threads.
8827static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008828
8829namespace clang {
8830
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008831bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008832 unsigned Size) {
8833 if (!Size)
8834 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008835 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008836 return CRC.RunSafelyOnThread(Fn, Size);
8837 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008838}
8839
Michael Kruse7520cf02020-03-25 09:26:14 -05008840unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008841
Michael Kruse7520cf02020-03-25 09:26:14 -05008842void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008843
Michael Kruse7520cf02020-03-25 09:26:14 -05008844} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008845
8846void clang::setThreadBackgroundPriority() {
8847 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8848 return;
8849
Nico Weber18cfd9f2019-04-21 19:18:41 +00008850#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008851 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008852#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008853}
8854
8855void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8856 if (!Unit)
8857 return;
8858
Michael Kruse7520cf02020-03-25 09:26:14 -05008859 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8860 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008861 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008862 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008863 CXString Msg =
8864 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008865 fprintf(stderr, "%s\n", clang_getCString(Msg));
8866 clang_disposeString(Msg);
8867 }
Nico Weber1865df42018-04-27 19:11:14 +00008868#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008869 // On Windows, force a flush, since there may be multiple copies of
8870 // stderr and stdout in the file system, all with different buffers
8871 // but writing to the same device.
8872 fflush(stderr);
8873#endif
8874}
8875
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008876MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8877 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008878 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008879 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008880 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008881 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008882 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008883
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008884 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008885 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008886 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008887 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008888 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8889 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008890 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8891 return Def.getMacroInfo();
8892 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008893 }
8894
Craig Topper69186e72014-06-08 08:38:04 +00008895 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008896}
8897
Richard Smith66a81862015-05-04 02:25:31 +00008898const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008899 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008900 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008901 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008902 const IdentifierInfo *II = MacroDef->getName();
8903 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008904 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008905
8906 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8907}
8908
Richard Smith66a81862015-05-04 02:25:31 +00008909MacroDefinitionRecord *
8910cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8911 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008912 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008913 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008914 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008915 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008916
8917 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008918 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008919 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8920 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008921 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008922
8923 // Check that the token is inside the definition and not its argument list.
8924 SourceManager &SM = Unit->getSourceManager();
8925 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008926 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008927 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00008928 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008929
8930 Preprocessor &PP = Unit->getPreprocessor();
8931 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
8932 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00008933 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008934
Alp Toker2d57cea2014-05-17 04:53:25 +00008935 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008936 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008937 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008938
8939 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00008940 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00008941 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008942
Richard Smith20e883e2015-04-29 23:20:19 +00008943 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00008944 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00008945 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008946
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008947 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008948}
8949
Richard Smith66a81862015-05-04 02:25:31 +00008950MacroDefinitionRecord *
8951cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
8952 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008953 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008954 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008955
8956 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008957 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008958 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008959 Preprocessor &PP = Unit->getPreprocessor();
8960 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00008961 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008962 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
8963 Token Tok;
8964 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00008965 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008966
8967 return checkForMacroInMacroDefinition(MI, Tok, TU);
8968}
8969
Guy Benyei11169dd2012-12-18 14:30:41 +00008970CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008971 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00008972}
8973
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008974Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
8975 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008976 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008977 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00008978 if (Unit->isMainFileAST())
8979 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008980 return *this;
8981 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00008982 } else {
8983 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008984 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008985 return *this;
8986}
8987
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00008988Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
8989 *this << FE->getName();
8990 return *this;
8991}
8992
8993Logger &cxindex::Logger::operator<<(CXCursor cursor) {
8994 CXString cursorName = clang_getCursorDisplayName(cursor);
8995 *this << cursorName << "@" << clang_getCursorLocation(cursor);
8996 clang_disposeString(cursorName);
8997 return *this;
8998}
8999
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009000Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
9001 CXFile File;
9002 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00009003 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009004 CXString FileName = clang_getFileName(File);
9005 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
9006 clang_disposeString(FileName);
9007 return *this;
9008}
9009
9010Logger &cxindex::Logger::operator<<(CXSourceRange range) {
9011 CXSourceLocation BLoc = clang_getRangeStart(range);
9012 CXSourceLocation ELoc = clang_getRangeEnd(range);
9013
9014 CXFile BFile;
9015 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009016 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009017
9018 CXFile EFile;
9019 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009020 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009021
9022 CXString BFileName = clang_getFileName(BFile);
9023 if (BFile == EFile) {
9024 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05009025 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009026 } else {
9027 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009028 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9029 BColumn)
9030 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9031 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009032 clang_disposeString(EFileName);
9033 }
9034 clang_disposeString(BFileName);
9035 return *this;
9036}
9037
9038Logger &cxindex::Logger::operator<<(CXString Str) {
9039 *this << clang_getCString(Str);
9040 return *this;
9041}
9042
9043Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9044 LogOS << Fmt;
9045 return *this;
9046}
9047
Benjamin Kramer762bc332019-08-07 14:44:40 +00009048static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009049
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009050cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009051 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009052
9053 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9054
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009055 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009056 OS << "[libclang:" << Name << ':';
9057
Alp Toker1a86ad22014-07-06 06:24:00 +00009058#ifdef USE_DARWIN_THREADS
9059 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009060 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9061 OS << tid << ':';
9062#endif
9063
9064 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9065 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009066 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009067
9068 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009069 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009070 OS << "--------------------------------------------------\n";
9071 }
9072}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009073
9074#ifdef CLANG_TOOL_EXTRA_BUILD
9075// This anchor is used to force the linker to link the clang-tidy plugin.
9076extern volatile int ClangTidyPluginAnchorSource;
9077static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9078 ClangTidyPluginAnchorSource;
9079
9080// This anchor is used to force the linker to link the clang-include-fixer
9081// plugin.
9082extern volatile int ClangIncludeFixerPluginAnchorSource;
9083static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9084 ClangIncludeFixerPluginAnchorSource;
9085#endif