blob: 2afc5a4eb842cb5c49bddde7a67c915d43b6c368 [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)
1798DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1799DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1800DEFAULT_TYPELOC_IMPL(Record, TagType)
1801DEFAULT_TYPELOC_IMPL(Enum, TagType)
1802DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1803DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1804DEFAULT_TYPELOC_IMPL(Auto, Type)
Erich Keane5f0903e2020-04-17 10:44:19 -07001805DEFAULT_TYPELOC_IMPL(ExtInt, Type)
1806DEFAULT_TYPELOC_IMPL(DependentExtInt, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001807
1808bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1809 // Visit the nested-name-specifier, if present.
1810 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1811 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1812 return true;
1813
1814 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001815 for (const auto &I : D->bases()) {
1816 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001817 return true;
1818 }
1819 }
1820
1821 return VisitTagDecl(D);
1822}
1823
1824bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001825 for (const auto *I : D->attrs())
Michael Wu40ff1052018-08-03 05:20:23 +00001826 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1827 !I->isImplicit()) &&
1828 Visit(MakeCXCursor(I, D, TU)))
Michael Kruse7520cf02020-03-25 09:26:14 -05001829 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00001830
1831 return false;
1832}
1833
1834//===----------------------------------------------------------------------===//
1835// Data-recursive visitor methods.
1836//===----------------------------------------------------------------------===//
1837
1838namespace {
Michael Kruse7520cf02020-03-25 09:26:14 -05001839#define DEF_JOB(NAME, DATA, KIND) \
1840 class NAME : public VisitorJob { \
1841 public: \
1842 NAME(const DATA *d, CXCursor parent) \
1843 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1844 static bool classof(const VisitorJob *VJ) { \
1845 return VJ->getKind() == KIND; \
1846 } \
1847 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1848 };
Guy Benyei11169dd2012-12-18 14:30:41 +00001849
1850DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1851DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1852DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1853DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001854DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1855DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1856DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1857#undef DEF_JOB
1858
James Y Knight04ec5bf2015-12-24 02:59:37 +00001859class ExplicitTemplateArgsVisit : public VisitorJob {
1860public:
1861 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1862 const TemplateArgumentLoc *End, CXCursor parent)
1863 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1864 End) {}
1865 static bool classof(const VisitorJob *VJ) {
1866 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1867 }
1868 const TemplateArgumentLoc *begin() const {
1869 return static_cast<const TemplateArgumentLoc *>(data[0]);
1870 }
1871 const TemplateArgumentLoc *end() {
1872 return static_cast<const TemplateArgumentLoc *>(data[1]);
1873 }
1874};
Guy Benyei11169dd2012-12-18 14:30:41 +00001875class DeclVisit : public VisitorJob {
1876public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001877 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1878 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1879 isFirst ? (void *)1 : (void *)nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001880 static bool classof(const VisitorJob *VJ) {
1881 return VJ->getKind() == DeclVisitKind;
1882 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001884 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001885};
1886class TypeLocVisit : public VisitorJob {
1887public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001888 TypeLocVisit(TypeLoc tl, CXCursor parent)
1889 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1890 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001891
1892 static bool classof(const VisitorJob *VJ) {
1893 return VJ->getKind() == TypeLocVisitKind;
1894 }
1895
Michael Kruse7520cf02020-03-25 09:26:14 -05001896 TypeLoc get() const {
Guy Benyei11169dd2012-12-18 14:30:41 +00001897 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001898 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 }
1900};
1901
1902class LabelRefVisit : public VisitorJob {
1903public:
1904 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001905 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1906 labelLoc.getPtrEncoding()) {}
1907
Guy Benyei11169dd2012-12-18 14:30:41 +00001908 static bool classof(const VisitorJob *VJ) {
1909 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1910 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001911 const LabelDecl *get() const {
1912 return static_cast<const LabelDecl *>(data[0]);
1913 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001914 SourceLocation getLoc() const {
1915 return SourceLocation::getFromPtrEncoding(data[1]);
1916 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001917};
Michael Kruse7520cf02020-03-25 09:26:14 -05001918
Guy Benyei11169dd2012-12-18 14:30:41 +00001919class NestedNameSpecifierLocVisit : public VisitorJob {
1920public:
1921 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001922 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1923 Qualifier.getNestedNameSpecifier(),
1924 Qualifier.getOpaqueData()) {}
1925
Guy Benyei11169dd2012-12-18 14:30:41 +00001926 static bool classof(const VisitorJob *VJ) {
1927 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1928 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001929
Guy Benyei11169dd2012-12-18 14:30:41 +00001930 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001931 return NestedNameSpecifierLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001932 const_cast<NestedNameSpecifier *>(
1933 static_cast<const NestedNameSpecifier *>(data[0])),
1934 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001935 }
1936};
Michael Kruse7520cf02020-03-25 09:26:14 -05001937
Guy Benyei11169dd2012-12-18 14:30:41 +00001938class DeclarationNameInfoVisit : public VisitorJob {
1939public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001940 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001941 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001942 static bool classof(const VisitorJob *VJ) {
1943 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1944 }
1945 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001946 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001947 switch (S->getStmtClass()) {
1948 default:
1949 llvm_unreachable("Unhandled Stmt");
1950 case clang::Stmt::MSDependentExistsStmtClass:
1951 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1952 case Stmt::CXXDependentScopeMemberExprClass:
1953 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1954 case Stmt::DependentScopeDeclRefExprClass:
1955 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001956 case Stmt::OMPCriticalDirectiveClass:
1957 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001958 }
1959 }
1960};
1961class MemberRefVisit : public VisitorJob {
1962public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001963 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001964 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1965 L.getPtrEncoding()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001966 static bool classof(const VisitorJob *VJ) {
1967 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1968 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001969 const FieldDecl *get() const {
1970 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001971 }
1972 SourceLocation getLoc() const {
Michael Kruse7520cf02020-03-25 09:26:14 -05001973 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 }
1975};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001977 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 VisitorWorkList &WL;
1979 CXCursor Parent;
Michael Kruse7520cf02020-03-25 09:26:14 -05001980
Guy Benyei11169dd2012-12-18 14:30:41 +00001981public:
1982 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001983 : WL(wl), Parent(parent) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001984
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1986 void VisitBlockExpr(const BlockExpr *B);
1987 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1988 void VisitCompoundStmt(const CompoundStmt *S);
Michael Kruse7520cf02020-03-25 09:26:14 -05001989 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
1990 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001991 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1992 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1993 void VisitCXXNewExpr(const CXXNewExpr *E);
1994 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1995 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1996 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1997 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1998 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1999 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
2000 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
2001 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002002 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002003 void VisitDeclRefExpr(const DeclRefExpr *D);
2004 void VisitDeclStmt(const DeclStmt *S);
2005 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
2006 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
2007 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
2008 void VisitForStmt(const ForStmt *FS);
2009 void VisitGotoStmt(const GotoStmt *GS);
2010 void VisitIfStmt(const IfStmt *If);
2011 void VisitInitListExpr(const InitListExpr *IE);
2012 void VisitMemberExpr(const MemberExpr *M);
2013 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2014 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2015 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2016 void VisitOverloadExpr(const OverloadExpr *E);
2017 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2018 void VisitStmt(const Stmt *S);
2019 void VisitSwitchStmt(const SwitchStmt *S);
2020 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002021 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2022 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2023 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2024 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2025 void VisitVAArgExpr(const VAArgExpr *E);
2026 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2027 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2028 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2029 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002030 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00002031 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002032 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002033 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002034 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00002035 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002036 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002037 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002038 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00002039 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002040 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002041 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002042 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
cchen47d60942019-12-05 13:43:48 -05002043 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002044 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002045 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00002046 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002047 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00002048 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002049 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002050 void
2051 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00002052 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00002053 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataevc112e942020-02-28 09:52:15 -05002054 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002055 void VisitOMPScanDirective(const OMPScanDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002056 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00002057 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002058 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00002059 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00002060 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00002061 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002062 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002063 void
2064 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00002065 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00002066 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002067 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Alexey Bataev60e51c42019-10-10 20:13:02 +00002068 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002069 void
2070 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002071 void VisitOMPParallelMasterTaskLoopDirective(
2072 const OMPParallelMasterTaskLoopDirective *D);
Alexey Bataev14a388f2019-10-25 10:27:13 -04002073 void VisitOMPParallelMasterTaskLoopSimdDirective(
2074 const OMPParallelMasterTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002075 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002076 void VisitOMPDistributeParallelForDirective(
2077 const OMPDistributeParallelForDirective *D);
Kelvin Li4a39add2016-07-05 05:00:15 +00002078 void VisitOMPDistributeParallelForSimdDirective(
2079 const OMPDistributeParallelForSimdDirective *D);
Kelvin Li787f3fc2016-07-06 04:45:38 +00002080 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
Kelvin Lia579b912016-07-14 02:54:56 +00002081 void VisitOMPTargetParallelForSimdDirective(
2082 const OMPTargetParallelForSimdDirective *D);
Kelvin Li986330c2016-07-20 22:57:10 +00002083 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
Kelvin Li02532872016-08-05 14:37:37 +00002084 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
Kelvin Li4e325f72016-10-25 12:50:55 +00002085 void VisitOMPTeamsDistributeSimdDirective(
2086 const OMPTeamsDistributeSimdDirective *D);
Kelvin Li579e41c2016-11-30 23:51:03 +00002087 void VisitOMPTeamsDistributeParallelForSimdDirective(
2088 const OMPTeamsDistributeParallelForSimdDirective *D);
Kelvin Li7ade93f2016-12-09 03:24:30 +00002089 void VisitOMPTeamsDistributeParallelForDirective(
2090 const OMPTeamsDistributeParallelForDirective *D);
Kelvin Libf594a52016-12-17 05:48:59 +00002091 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
Kelvin Li83c451e2016-12-25 04:52:54 +00002092 void VisitOMPTargetTeamsDistributeDirective(
2093 const OMPTargetTeamsDistributeDirective *D);
Kelvin Li80e8f562016-12-29 22:16:30 +00002094 void VisitOMPTargetTeamsDistributeParallelForDirective(
2095 const OMPTargetTeamsDistributeParallelForDirective *D);
Kelvin Li1851df52017-01-03 05:23:48 +00002096 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2097 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
Kelvin Lida681182017-01-10 18:08:18 +00002098 void VisitOMPTargetTeamsDistributeSimdDirective(
2099 const OMPTargetTeamsDistributeSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002100
Guy Benyei11169dd2012-12-18 14:30:41 +00002101private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002103 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00002104 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2105 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002106 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2107 void AddStmt(const Stmt *S);
2108 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002111 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002112};
Michael Kruse7520cf02020-03-25 09:26:14 -05002113} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00002114
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 // 'S' should always be non-null, since it comes from the
2117 // statement we are visiting.
2118 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2119}
2120
Michael Kruse7520cf02020-03-25 09:26:14 -05002121void EnqueueVisitor::AddNestedNameSpecifierLoc(
2122 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 if (Qualifier)
2124 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2125}
2126
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002127void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 if (S)
2129 WL.push_back(StmtVisit(S, Parent));
2130}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 if (D)
2133 WL.push_back(DeclVisit(D, Parent, isFirst));
2134}
James Y Knight04ec5bf2015-12-24 02:59:37 +00002135void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2136 unsigned NumTemplateArgs) {
2137 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002138}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002139void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 if (D)
2141 WL.push_back(MemberRefVisit(D, L, Parent));
2142}
2143void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2144 if (TI)
2145 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002146}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002149 for (const Stmt *SubStmt : S->children()) {
2150 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002151 }
2152 if (size == WL.size())
2153 return;
2154 // Now reverse the entries we just added. This will match the DFS
2155 // ordering performed by the worklist.
2156 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2157 std::reverse(I, E);
2158}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002159namespace {
2160class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2161 EnqueueVisitor *Visitor;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002162 /// Process clauses with list of variables.
Michael Kruse7520cf02020-03-25 09:26:14 -05002163 template <typename T> void VisitOMPClauseList(T *Node);
2164
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002165public:
Michael Kruse7520cf02020-03-25 09:26:14 -05002166 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
Johannes Doerfert419a5592020-03-30 19:58:40 -05002167#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2168#include "llvm/Frontend/OpenMP/OMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002169 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002170 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002171};
2172
Alexey Bataev3392d762016-02-16 11:18:12 +00002173void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2174 const OMPClauseWithPreInit *C) {
2175 Visitor->AddStmt(C->getPreInitStmt());
2176}
2177
Alexey Bataev005248a2016-02-25 05:25:57 +00002178void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2179 const OMPClauseWithPostUpdate *C) {
Alexey Bataev37e594c2016-03-04 07:21:16 +00002180 VisitOMPClauseWithPreInit(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002181 Visitor->AddStmt(C->getPostUpdateExpr());
2182}
2183
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002184void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00002185 VisitOMPClauseWithPreInit(C);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002186 Visitor->AddStmt(C->getCondition());
2187}
2188
Alexey Bataev3778b602014-07-17 07:32:53 +00002189void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2190 Visitor->AddStmt(C->getCondition());
2191}
2192
Alexey Bataev568a8332014-03-06 06:15:19 +00002193void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00002194 VisitOMPClauseWithPreInit(C);
Alexey Bataev568a8332014-03-06 06:15:19 +00002195 Visitor->AddStmt(C->getNumThreads());
2196}
2197
Alexey Bataev62c87d22014-03-21 04:51:18 +00002198void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2199 Visitor->AddStmt(C->getSafelen());
2200}
2201
Alexey Bataev66b15b52015-08-21 11:14:16 +00002202void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2203 Visitor->AddStmt(C->getSimdlen());
2204}
2205
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002206void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2207 Visitor->AddStmt(C->getAllocator());
2208}
2209
Alexander Musman8bd31e62014-05-27 15:12:19 +00002210void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2211 Visitor->AddStmt(C->getNumForLoops());
2212}
2213
Michael Kruse7520cf02020-03-25 09:26:14 -05002214void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
Alexey Bataev756c1962013-09-24 03:17:45 +00002215
Michael Kruse7520cf02020-03-25 09:26:14 -05002216void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002217
Alexey Bataev56dafe82014-06-20 07:16:17 +00002218void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002219 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002220 Visitor->AddStmt(C->getChunkSize());
2221}
2222
Alexey Bataev10e775f2015-07-30 11:36:16 +00002223void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2224 Visitor->AddStmt(C->getNumForLoops());
2225}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002226
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002227void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2228 Visitor->AddStmt(C->getEventHandler());
2229}
2230
Alexey Bataev236070f2014-06-20 11:19:47 +00002231void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2232
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002233void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2234
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002235void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2236
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002237void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2238
Alexey Bataevdea47612014-07-23 07:46:59 +00002239void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2240
Alexey Bataev67a4f222014-07-23 10:25:33 +00002241void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2242
Alexey Bataev459dec02014-07-24 06:46:57 +00002243void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2244
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002245void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2246
Alexey Bataevea9166b2020-02-06 16:30:23 -05002247void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2248
Alexey Bataev04a830f2020-02-10 14:30:39 -05002249void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2250
Alexey Bataev95598342020-02-10 15:49:05 -05002251void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2252
Alexey Bataev9a8defc2020-02-11 11:10:43 -05002253void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2254
Alexey Bataev346265e2015-09-25 10:37:12 +00002255void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2256
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002257void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2258
Alexey Bataevb825de12015-12-07 10:51:44 +00002259void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2260
Alexey Bataev375437a2020-03-02 14:21:20 -05002261void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {}
2262
Kelvin Li1408f912018-09-26 04:28:39 +00002263void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2264 const OMPUnifiedAddressClause *) {}
2265
Patrick Lyster4a370b92018-10-01 13:47:43 +00002266void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2267 const OMPUnifiedSharedMemoryClause *) {}
2268
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00002269void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2270 const OMPReverseOffloadClause *) {}
2271
Patrick Lyster3fe9e392018-10-11 14:41:10 +00002272void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2273 const OMPDynamicAllocatorsClause *) {}
2274
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002275void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2276 const OMPAtomicDefaultMemOrderClause *) {}
2277
Michael Wonge710d542015-08-07 16:16:36 +00002278void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2279 Visitor->AddStmt(C->getDevice());
2280}
2281
Kelvin Li099bb8c2015-11-24 20:50:12 +00002282void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00002283 VisitOMPClauseWithPreInit(C);
Kelvin Li099bb8c2015-11-24 20:50:12 +00002284 Visitor->AddStmt(C->getNumTeams());
2285}
2286
Michael Kruse7520cf02020-03-25 09:26:14 -05002287void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2288 const OMPThreadLimitClause *C) {
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00002289 VisitOMPClauseWithPreInit(C);
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002290 Visitor->AddStmt(C->getThreadLimit());
2291}
2292
Alexey Bataeva0569352015-12-01 10:17:31 +00002293void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2294 Visitor->AddStmt(C->getPriority());
2295}
2296
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002297void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2298 Visitor->AddStmt(C->getGrainsize());
2299}
2300
Alexey Bataev382967a2015-12-08 12:06:20 +00002301void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2302 Visitor->AddStmt(C->getNumTasks());
2303}
2304
Alexey Bataev28c75412015-12-15 08:19:24 +00002305void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2306 Visitor->AddStmt(C->getHint());
2307}
2308
Michael Kruse7520cf02020-03-25 09:26:14 -05002309template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002310 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002311 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002312 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002313}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002314
Alexey Bataev06dea732020-03-20 09:41:22 -04002315void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2316 VisitOMPClauseList(C);
2317}
Alexey Bataev63828a32020-03-23 10:41:08 -04002318void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2319 VisitOMPClauseList(C);
2320}
Alexey Bataeve04483e2019-03-27 14:14:31 +00002321void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2322 VisitOMPClauseList(C);
2323 Visitor->AddStmt(C->getAllocator());
2324}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002325void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002326 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002327 for (const auto *E : C->private_copies()) {
2328 Visitor->AddStmt(E);
2329 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002330}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002331void OMPClauseEnqueue::VisitOMPFirstprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002332 const OMPFirstprivateClause *C) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002333 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002334 VisitOMPClauseWithPreInit(C);
2335 for (const auto *E : C->private_copies()) {
2336 Visitor->AddStmt(E);
2337 }
2338 for (const auto *E : C->inits()) {
2339 Visitor->AddStmt(E);
2340 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002341}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002342void OMPClauseEnqueue::VisitOMPLastprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002343 const OMPLastprivateClause *C) {
Alexander Musman1bb328c2014-06-04 13:06:39 +00002344 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002345 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002346 for (auto *E : C->private_copies()) {
2347 Visitor->AddStmt(E);
2348 }
2349 for (auto *E : C->source_exprs()) {
2350 Visitor->AddStmt(E);
2351 }
2352 for (auto *E : C->destination_exprs()) {
2353 Visitor->AddStmt(E);
2354 }
2355 for (auto *E : C->assignment_ops()) {
2356 Visitor->AddStmt(E);
2357 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002358}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002359void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002360 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002361}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002362void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2363 VisitOMPClauseList(C);
Alexey Bataev61205072016-03-02 04:57:40 +00002364 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002365 for (auto *E : C->privates()) {
2366 Visitor->AddStmt(E);
2367 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002368 for (auto *E : C->lhs_exprs()) {
2369 Visitor->AddStmt(E);
2370 }
2371 for (auto *E : C->rhs_exprs()) {
2372 Visitor->AddStmt(E);
2373 }
2374 for (auto *E : C->reduction_ops()) {
2375 Visitor->AddStmt(E);
2376 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002377}
Alexey Bataev169d96a2017-07-18 20:17:46 +00002378void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2379 const OMPTaskReductionClause *C) {
2380 VisitOMPClauseList(C);
2381 VisitOMPClauseWithPostUpdate(C);
2382 for (auto *E : C->privates()) {
2383 Visitor->AddStmt(E);
2384 }
2385 for (auto *E : C->lhs_exprs()) {
2386 Visitor->AddStmt(E);
2387 }
2388 for (auto *E : C->rhs_exprs()) {
2389 Visitor->AddStmt(E);
2390 }
2391 for (auto *E : C->reduction_ops()) {
2392 Visitor->AddStmt(E);
2393 }
2394}
Alexey Bataevfa312f32017-07-21 18:48:21 +00002395void OMPClauseEnqueue::VisitOMPInReductionClause(
2396 const OMPInReductionClause *C) {
2397 VisitOMPClauseList(C);
2398 VisitOMPClauseWithPostUpdate(C);
2399 for (auto *E : C->privates()) {
2400 Visitor->AddStmt(E);
2401 }
2402 for (auto *E : C->lhs_exprs()) {
2403 Visitor->AddStmt(E);
2404 }
2405 for (auto *E : C->rhs_exprs()) {
2406 Visitor->AddStmt(E);
2407 }
2408 for (auto *E : C->reduction_ops()) {
2409 Visitor->AddStmt(E);
2410 }
Alexey Bataev88202be2017-07-27 13:20:36 +00002411 for (auto *E : C->taskgroup_descriptors())
2412 Visitor->AddStmt(E);
Alexey Bataevfa312f32017-07-21 18:48:21 +00002413}
Alexander Musman8dba6642014-04-22 13:09:42 +00002414void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2415 VisitOMPClauseList(C);
Alexey Bataev78849fb2016-03-09 09:49:00 +00002416 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002417 for (const auto *E : C->privates()) {
2418 Visitor->AddStmt(E);
2419 }
Alexander Musman3276a272015-03-21 10:12:56 +00002420 for (const auto *E : C->inits()) {
2421 Visitor->AddStmt(E);
2422 }
2423 for (const auto *E : C->updates()) {
2424 Visitor->AddStmt(E);
2425 }
2426 for (const auto *E : C->finals()) {
2427 Visitor->AddStmt(E);
2428 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002429 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002430 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002431}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002432void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2433 VisitOMPClauseList(C);
2434 Visitor->AddStmt(C->getAlignment());
2435}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002436void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2437 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002438 for (auto *E : C->source_exprs()) {
2439 Visitor->AddStmt(E);
2440 }
2441 for (auto *E : C->destination_exprs()) {
2442 Visitor->AddStmt(E);
2443 }
2444 for (auto *E : C->assignment_ops()) {
2445 Visitor->AddStmt(E);
2446 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002447}
Michael Kruse7520cf02020-03-25 09:26:14 -05002448void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2449 const OMPCopyprivateClause *C) {
Alexey Bataevbae9a792014-06-27 10:37:06 +00002450 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002451 for (auto *E : C->source_exprs()) {
2452 Visitor->AddStmt(E);
2453 }
2454 for (auto *E : C->destination_exprs()) {
2455 Visitor->AddStmt(E);
2456 }
2457 for (auto *E : C->assignment_ops()) {
2458 Visitor->AddStmt(E);
2459 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002460}
Alexey Bataev6125da92014-07-21 11:26:11 +00002461void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2462 VisitOMPClauseList(C);
2463}
Alexey Bataevc112e942020-02-28 09:52:15 -05002464void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2465 Visitor->AddStmt(C->getDepobj());
2466}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002467void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2468 VisitOMPClauseList(C);
2469}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002470void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2471 VisitOMPClauseList(C);
2472}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002473void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2474 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002475 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002476 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002477}
Alexey Bataev3392d762016-02-16 11:18:12 +00002478void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2479 const OMPDefaultmapClause * /*C*/) {}
Samuel Antao661c0902016-05-26 17:39:58 +00002480void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2481 VisitOMPClauseList(C);
2482}
Samuel Antaoec172c62016-05-26 17:49:04 +00002483void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2484 VisitOMPClauseList(C);
2485}
Michael Kruse7520cf02020-03-25 09:26:14 -05002486void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2487 const OMPUseDevicePtrClause *C) {
Carlo Bertolli2404b172016-07-13 15:37:16 +00002488 VisitOMPClauseList(C);
2489}
Michael Kruse7520cf02020-03-25 09:26:14 -05002490void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2491 const OMPIsDevicePtrClause *C) {
Carlo Bertolli70594e92016-07-13 17:16:49 +00002492 VisitOMPClauseList(C);
2493}
Alexey Bataevb6e70842019-12-16 15:54:17 -05002494void OMPClauseEnqueue::VisitOMPNontemporalClause(
2495 const OMPNontemporalClause *C) {
2496 VisitOMPClauseList(C);
Alexey Bataev0860db92019-12-19 10:01:10 -05002497 for (const auto *E : C->private_refs())
2498 Visitor->AddStmt(E);
Alexey Bataevb6e70842019-12-16 15:54:17 -05002499}
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002500void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
Alexey Bataevb5be1c52020-04-21 13:21:00 -04002501void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
2502 const OMPUsesAllocatorsClause *C) {
2503 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
2504 const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);
2505 Visitor->AddStmt(D.Allocator);
2506 Visitor->AddStmt(D.AllocatorTraits);
2507 }
2508}
Michael Kruse7520cf02020-03-25 09:26:14 -05002509} // namespace
Alexey Bataev756c1962013-09-24 03:17:45 +00002510
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002511void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2512 unsigned size = WL.size();
2513 OMPClauseEnqueue Visitor(this);
2514 Visitor.Visit(S);
2515 if (size == WL.size())
2516 return;
2517 // Now reverse the entries we just added. This will match the DFS
2518 // ordering performed by the worklist.
2519 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2520 std::reverse(I, E);
2521}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002522void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002523 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2524}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002525void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002526 AddDecl(B->getBlockDecl());
2527}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002528void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002529 EnqueueChildren(E);
2530 AddTypeLoc(E->getTypeSourceInfo());
2531}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002532void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002533 for (auto &I : llvm::reverse(S->body()))
2534 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002535}
Michael Kruse7520cf02020-03-25 09:26:14 -05002536void EnqueueVisitor::VisitMSDependentExistsStmt(
2537 const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002538 AddStmt(S->getSubStmt());
2539 AddDeclarationNameInfo(S);
2540 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2541 AddNestedNameSpecifierLoc(QualifierLoc);
2542}
2543
Michael Kruse7520cf02020-03-25 09:26:14 -05002544void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2545 const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002546 if (E->hasExplicitTemplateArgs())
2547 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002548 AddDeclarationNameInfo(E);
2549 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2550 AddNestedNameSpecifierLoc(QualifierLoc);
2551 if (!E->isImplicitAccess())
2552 AddStmt(E->getBase());
2553}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002554void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002555 // Enqueue the initializer , if any.
2556 AddStmt(E->getInitializer());
2557 // Enqueue the array size, if any.
Richard Smithb9fb1212019-05-06 03:47:15 +00002558 AddStmt(E->getArraySize().getValueOr(nullptr));
Guy Benyei11169dd2012-12-18 14:30:41 +00002559 // Enqueue the allocated type.
2560 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2561 // Enqueue the placement arguments.
2562 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002563 AddStmt(E->getPlacementArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002564}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002565void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002566 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002567 AddStmt(CE->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002568 AddStmt(CE->getCallee());
2569 AddStmt(CE->getArg(0));
2570}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002571void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002572 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002573 // Visit the name of the type being destroyed.
2574 AddTypeLoc(E->getDestroyedTypeInfo());
2575 // Visit the scope type that looks disturbingly like the nested-name-specifier
2576 // but isn't.
2577 AddTypeLoc(E->getScopeTypeInfo());
2578 // Visit the nested-name-specifier.
2579 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2580 AddNestedNameSpecifierLoc(QualifierLoc);
2581 // Visit base expression.
2582 AddStmt(E->getBase());
2583}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002584void EnqueueVisitor::VisitCXXScalarValueInitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002585 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002586 AddTypeLoc(E->getTypeSourceInfo());
2587}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002588void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002589 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002590 EnqueueChildren(E);
2591 AddTypeLoc(E->getTypeSourceInfo());
2592}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002593void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002594 EnqueueChildren(E);
2595 if (E->isTypeOperand())
2596 AddTypeLoc(E->getTypeOperandSourceInfo());
2597}
2598
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002599void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002600 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 EnqueueChildren(E);
2602 AddTypeLoc(E->getTypeSourceInfo());
2603}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002604void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002605 EnqueueChildren(E);
2606 if (E->isTypeOperand())
2607 AddTypeLoc(E->getTypeOperandSourceInfo());
2608}
2609
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002610void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002611 EnqueueChildren(S);
2612 AddDecl(S->getExceptionDecl());
2613}
2614
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002615void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002616 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002617 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002618 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002619}
2620
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002621void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002622 if (DR->hasExplicitTemplateArgs())
2623 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002624 WL.push_back(DeclRefExprParts(DR, Parent));
2625}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002626void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002627 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002628 if (E->hasExplicitTemplateArgs())
2629 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002630 AddDeclarationNameInfo(E);
2631 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2632}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002633void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 unsigned size = WL.size();
2635 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002636 for (const auto *D : S->decls()) {
2637 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002638 isFirst = false;
2639 }
2640 if (size == WL.size())
2641 return;
2642 // Now reverse the entries we just added. This will match the DFS
2643 // ordering performed by the worklist.
2644 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2645 std::reverse(I, E);
2646}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002647void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002648 AddStmt(E->getInit());
David Majnemerf7e36092016-06-23 00:15:04 +00002649 for (const DesignatedInitExpr::Designator &D :
2650 llvm::reverse(E->designators())) {
2651 if (D.isFieldDesignator()) {
2652 if (FieldDecl *Field = D.getField())
2653 AddMemberRef(Field, D.getFieldLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00002654 continue;
2655 }
David Majnemerf7e36092016-06-23 00:15:04 +00002656 if (D.isArrayDesignator()) {
2657 AddStmt(E->getArrayIndex(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002658 continue;
2659 }
David Majnemerf7e36092016-06-23 00:15:04 +00002660 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2661 AddStmt(E->getArrayRangeEnd(D));
2662 AddStmt(E->getArrayRangeStart(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002663 }
2664}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002665void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002666 EnqueueChildren(E);
2667 AddTypeLoc(E->getTypeInfoAsWritten());
2668}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002669void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002670 AddStmt(FS->getBody());
2671 AddStmt(FS->getInc());
2672 AddStmt(FS->getCond());
2673 AddDecl(FS->getConditionVariable());
2674 AddStmt(FS->getInit());
2675}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002676void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002677 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2678}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002679void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002680 AddStmt(If->getElse());
2681 AddStmt(If->getThen());
2682 AddStmt(If->getCond());
Milian Wolff08e18122020-05-02 22:18:09 +02002683 AddStmt(If->getInit());
Guy Benyei11169dd2012-12-18 14:30:41 +00002684 AddDecl(If->getConditionVariable());
2685}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002686void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002687 // We care about the syntactic form of the initializer list, only.
2688 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2689 IE = Syntactic;
2690 EnqueueChildren(IE);
2691}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002692void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002693 WL.push_back(MemberExprParts(M, Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002694
Guy Benyei11169dd2012-12-18 14:30:41 +00002695 // If the base of the member access expression is an implicit 'this', don't
2696 // visit it.
2697 // FIXME: If we ever want to show these implicit accesses, this will be
2698 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002699 if (M->isImplicitAccess())
2700 return;
2701
2702 // Ignore base anonymous struct/union fields, otherwise they will shadow the
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00002703 // real field that we are interested in.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002704 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2705 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2706 if (FD->isAnonymousStructOrUnion()) {
2707 AddStmt(SubME->getBase());
2708 return;
2709 }
2710 }
2711 }
2712
2713 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002714}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002715void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002716 AddTypeLoc(E->getEncodedTypeSourceInfo());
2717}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002718void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002719 EnqueueChildren(M);
2720 AddTypeLoc(M->getClassReceiverTypeInfo());
2721}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002722void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002723 // Visit the components of the offsetof expression.
2724 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Michael Kruse7520cf02020-03-25 09:26:14 -05002725 const OffsetOfNode &Node = E->getComponent(I - 1);
Guy Benyei11169dd2012-12-18 14:30:41 +00002726 switch (Node.getKind()) {
2727 case OffsetOfNode::Array:
2728 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2729 break;
2730 case OffsetOfNode::Field:
2731 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2732 break;
2733 case OffsetOfNode::Identifier:
2734 case OffsetOfNode::Base:
2735 continue;
2736 }
2737 }
2738 // Visit the type into which we're computing the offset.
2739 AddTypeLoc(E->getTypeSourceInfo());
2740}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002741void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002742 if (E->hasExplicitTemplateArgs())
2743 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 WL.push_back(OverloadExprParts(E, Parent));
2745}
2746void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002747 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 EnqueueChildren(E);
2749 if (E->isArgumentType())
2750 AddTypeLoc(E->getArgumentTypeInfo());
2751}
Michael Kruse7520cf02020-03-25 09:26:14 -05002752void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002753void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002754 AddStmt(S->getBody());
2755 AddStmt(S->getCond());
2756 AddDecl(S->getConditionVariable());
2757}
2758
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002759void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002760 AddStmt(W->getBody());
2761 AddStmt(W->getCond());
2762 AddDecl(W->getConditionVariable());
2763}
2764
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002765void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002766 for (unsigned I = E->getNumArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002767 AddTypeLoc(E->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002768}
2769
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002770void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002771 AddTypeLoc(E->getQueriedTypeSourceInfo());
2772}
2773
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002774void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002775 EnqueueChildren(E);
2776}
2777
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002778void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002779 VisitOverloadExpr(U);
2780 if (!U->isImplicitAccess())
2781 AddStmt(U->getBase());
2782}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002783void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002784 AddStmt(E->getSubExpr());
2785 AddTypeLoc(E->getWrittenTypeInfo());
2786}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002787void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 WL.push_back(SizeOfPackExprParts(E, Parent));
2789}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002790void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002791 // If the opaque value has a source expression, just transparently
2792 // visit that. This is useful for (e.g.) pseudo-object expressions.
2793 if (Expr *SourceExpr = E->getSourceExpr())
2794 return Visit(SourceExpr);
2795}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002796void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002797 AddStmt(E->getBody());
2798 WL.push_back(LambdaExprParts(E, Parent));
2799}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002800void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002801 // Treat the expression like its syntactic form.
2802 Visit(E->getSyntacticForm());
2803}
2804
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002805void EnqueueVisitor::VisitOMPExecutableDirective(
Michael Kruse7520cf02020-03-25 09:26:14 -05002806 const OMPExecutableDirective *D) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002807 EnqueueChildren(D);
2808 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2809 E = D->clauses().end();
2810 I != E; ++I)
2811 EnqueueChildren(*I);
2812}
2813
Alexander Musman3aaab662014-08-19 11:27:13 +00002814void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2815 VisitOMPExecutableDirective(D);
2816}
2817
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002818void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2819 VisitOMPExecutableDirective(D);
2820}
2821
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002822void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002823 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002824}
2825
Alexey Bataevf29276e2014-06-18 04:14:57 +00002826void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002827 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002828}
2829
Alexander Musmanf82886e2014-09-18 05:12:34 +00002830void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2831 VisitOMPLoopDirective(D);
2832}
2833
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002834void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2835 VisitOMPExecutableDirective(D);
2836}
2837
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002838void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2839 VisitOMPExecutableDirective(D);
2840}
2841
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002842void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2843 VisitOMPExecutableDirective(D);
2844}
2845
Alexander Musman80c22892014-07-17 08:54:58 +00002846void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2847 VisitOMPExecutableDirective(D);
2848}
2849
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002850void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2851 VisitOMPExecutableDirective(D);
2852 AddDeclarationNameInfo(D);
2853}
2854
Michael Kruse7520cf02020-03-25 09:26:14 -05002855void EnqueueVisitor::VisitOMPParallelForDirective(
2856 const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002857 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002858}
2859
Alexander Musmane4e893b2014-09-23 09:33:00 +00002860void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2861 const OMPParallelForSimdDirective *D) {
2862 VisitOMPLoopDirective(D);
2863}
2864
cchen47d60942019-12-05 13:43:48 -05002865void EnqueueVisitor::VisitOMPParallelMasterDirective(
2866 const OMPParallelMasterDirective *D) {
2867 VisitOMPExecutableDirective(D);
2868}
2869
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002870void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2871 const OMPParallelSectionsDirective *D) {
2872 VisitOMPExecutableDirective(D);
2873}
2874
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002875void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2876 VisitOMPExecutableDirective(D);
2877}
2878
Michael Kruse7520cf02020-03-25 09:26:14 -05002879void EnqueueVisitor::VisitOMPTaskyieldDirective(
2880 const OMPTaskyieldDirective *D) {
Alexey Bataev68446b72014-07-18 07:47:19 +00002881 VisitOMPExecutableDirective(D);
2882}
2883
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002884void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2885 VisitOMPExecutableDirective(D);
2886}
2887
Alexey Bataev2df347a2014-07-18 10:17:07 +00002888void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2889 VisitOMPExecutableDirective(D);
2890}
2891
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002892void EnqueueVisitor::VisitOMPTaskgroupDirective(
2893 const OMPTaskgroupDirective *D) {
2894 VisitOMPExecutableDirective(D);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00002895 if (const Expr *E = D->getReductionRef())
2896 VisitStmt(E);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002897}
2898
Alexey Bataev6125da92014-07-21 11:26:11 +00002899void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2900 VisitOMPExecutableDirective(D);
2901}
2902
Alexey Bataevc112e942020-02-28 09:52:15 -05002903void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
2904 VisitOMPExecutableDirective(D);
2905}
2906
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002907void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
2908 VisitOMPExecutableDirective(D);
2909}
2910
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002911void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2912 VisitOMPExecutableDirective(D);
2913}
2914
Alexey Bataev0162e452014-07-22 10:10:35 +00002915void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2916 VisitOMPExecutableDirective(D);
2917}
2918
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002919void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2920 VisitOMPExecutableDirective(D);
2921}
2922
Alexey Bataevc112e942020-02-28 09:52:15 -05002923void EnqueueVisitor::VisitOMPTargetDataDirective(
2924 const OMPTargetDataDirective *D) {
Michael Wong65f367f2015-07-21 13:44:28 +00002925 VisitOMPExecutableDirective(D);
2926}
2927
Samuel Antaodf67fc42016-01-19 19:15:56 +00002928void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2929 const OMPTargetEnterDataDirective *D) {
2930 VisitOMPExecutableDirective(D);
2931}
2932
Samuel Antao72590762016-01-19 20:04:50 +00002933void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2934 const OMPTargetExitDataDirective *D) {
2935 VisitOMPExecutableDirective(D);
2936}
2937
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002938void EnqueueVisitor::VisitOMPTargetParallelDirective(
2939 const OMPTargetParallelDirective *D) {
2940 VisitOMPExecutableDirective(D);
2941}
2942
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002943void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2944 const OMPTargetParallelForDirective *D) {
2945 VisitOMPLoopDirective(D);
2946}
2947
Alexey Bataev13314bf2014-10-09 04:18:56 +00002948void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2949 VisitOMPExecutableDirective(D);
2950}
2951
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002952void EnqueueVisitor::VisitOMPCancellationPointDirective(
2953 const OMPCancellationPointDirective *D) {
2954 VisitOMPExecutableDirective(D);
2955}
2956
Alexey Bataev80909872015-07-02 11:25:17 +00002957void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2958 VisitOMPExecutableDirective(D);
2959}
2960
Alexey Bataev49f6e782015-12-01 04:18:41 +00002961void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2962 VisitOMPLoopDirective(D);
2963}
2964
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002965void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2966 const OMPTaskLoopSimdDirective *D) {
2967 VisitOMPLoopDirective(D);
2968}
2969
Alexey Bataev60e51c42019-10-10 20:13:02 +00002970void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
2971 const OMPMasterTaskLoopDirective *D) {
2972 VisitOMPLoopDirective(D);
2973}
2974
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002975void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
2976 const OMPMasterTaskLoopSimdDirective *D) {
2977 VisitOMPLoopDirective(D);
2978}
2979
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002980void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
2981 const OMPParallelMasterTaskLoopDirective *D) {
2982 VisitOMPLoopDirective(D);
2983}
2984
Alexey Bataev14a388f2019-10-25 10:27:13 -04002985void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
2986 const OMPParallelMasterTaskLoopSimdDirective *D) {
2987 VisitOMPLoopDirective(D);
2988}
2989
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002990void EnqueueVisitor::VisitOMPDistributeDirective(
2991 const OMPDistributeDirective *D) {
2992 VisitOMPLoopDirective(D);
2993}
2994
Carlo Bertolli9925f152016-06-27 14:55:37 +00002995void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
2996 const OMPDistributeParallelForDirective *D) {
2997 VisitOMPLoopDirective(D);
2998}
2999
Kelvin Li4a39add2016-07-05 05:00:15 +00003000void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
3001 const OMPDistributeParallelForSimdDirective *D) {
3002 VisitOMPLoopDirective(D);
3003}
3004
Kelvin Li787f3fc2016-07-06 04:45:38 +00003005void EnqueueVisitor::VisitOMPDistributeSimdDirective(
3006 const OMPDistributeSimdDirective *D) {
3007 VisitOMPLoopDirective(D);
3008}
3009
Kelvin Lia579b912016-07-14 02:54:56 +00003010void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
3011 const OMPTargetParallelForSimdDirective *D) {
3012 VisitOMPLoopDirective(D);
3013}
3014
Kelvin Li986330c2016-07-20 22:57:10 +00003015void EnqueueVisitor::VisitOMPTargetSimdDirective(
3016 const OMPTargetSimdDirective *D) {
3017 VisitOMPLoopDirective(D);
3018}
3019
Kelvin Li02532872016-08-05 14:37:37 +00003020void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3021 const OMPTeamsDistributeDirective *D) {
3022 VisitOMPLoopDirective(D);
3023}
3024
Kelvin Li4e325f72016-10-25 12:50:55 +00003025void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3026 const OMPTeamsDistributeSimdDirective *D) {
3027 VisitOMPLoopDirective(D);
3028}
3029
Kelvin Li579e41c2016-11-30 23:51:03 +00003030void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3031 const OMPTeamsDistributeParallelForSimdDirective *D) {
3032 VisitOMPLoopDirective(D);
3033}
3034
Kelvin Li7ade93f2016-12-09 03:24:30 +00003035void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3036 const OMPTeamsDistributeParallelForDirective *D) {
3037 VisitOMPLoopDirective(D);
3038}
3039
Kelvin Libf594a52016-12-17 05:48:59 +00003040void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3041 const OMPTargetTeamsDirective *D) {
3042 VisitOMPExecutableDirective(D);
3043}
3044
Kelvin Li83c451e2016-12-25 04:52:54 +00003045void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3046 const OMPTargetTeamsDistributeDirective *D) {
3047 VisitOMPLoopDirective(D);
3048}
3049
Kelvin Li80e8f562016-12-29 22:16:30 +00003050void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3051 const OMPTargetTeamsDistributeParallelForDirective *D) {
3052 VisitOMPLoopDirective(D);
3053}
3054
Kelvin Li1851df52017-01-03 05:23:48 +00003055void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3056 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3057 VisitOMPLoopDirective(D);
3058}
3059
Kelvin Lida681182017-01-10 18:08:18 +00003060void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3061 const OMPTargetTeamsDistributeSimdDirective *D) {
3062 VisitOMPLoopDirective(D);
3063}
3064
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003065void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003066 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3067 .Visit(S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003068}
3069
3070bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3071 if (RegionOfInterest.isValid()) {
3072 SourceRange Range = getRawCursorExtent(C);
3073 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3074 return false;
3075 }
3076 return true;
3077}
3078
3079bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3080 while (!WL.empty()) {
3081 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00003082 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00003083
3084 // Set the Parent field, then back to its old value once we're done.
3085 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
Michael Kruse7520cf02020-03-25 09:26:14 -05003086
Guy Benyei11169dd2012-12-18 14:30:41 +00003087 switch (LI.getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003088 case VisitorJob::DeclVisitKind: {
3089 const Decl *D = cast<DeclVisit>(&LI)->get();
3090 if (!D)
3091 continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00003092
Michael Kruse7520cf02020-03-25 09:26:14 -05003093 // For now, perform default visitation for Decls.
3094 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3095 cast<DeclVisit>(&LI)->isFirst())))
3096 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003097
Michael Kruse7520cf02020-03-25 09:26:14 -05003098 continue;
3099 }
3100 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3101 for (const TemplateArgumentLoc &Arg :
3102 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3103 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00003104 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003105 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003106 continue;
3107 }
3108 case VisitorJob::TypeLocVisitKind: {
3109 // Perform default visitation for TypeLocs.
3110 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3111 return true;
3112 continue;
3113 }
3114 case VisitorJob::LabelRefVisitKind: {
3115 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3116 if (LabelStmt *stmt = LS->getStmt()) {
3117 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3118 TU))) {
3119 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003120 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003122 continue;
3123 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003124
Michael Kruse7520cf02020-03-25 09:26:14 -05003125 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3126 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3127 if (VisitNestedNameSpecifierLoc(V->get()))
3128 return true;
3129 continue;
3130 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003131
Michael Kruse7520cf02020-03-25 09:26:14 -05003132 case VisitorJob::DeclarationNameInfoVisitKind: {
3133 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3134 return true;
3135 continue;
3136 }
3137 case VisitorJob::MemberRefVisitKind: {
3138 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3139 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3140 return true;
3141 continue;
3142 }
3143 case VisitorJob::StmtVisitKind: {
3144 const Stmt *S = cast<StmtVisit>(&LI)->get();
3145 if (!S)
Guy Benyei11169dd2012-12-18 14:30:41 +00003146 continue;
Richard Smithba71c082013-05-16 06:20:58 +00003147
Michael Kruse7520cf02020-03-25 09:26:14 -05003148 // Update the current cursor.
3149 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3150 if (!IsInRegionOfInterest(Cursor))
3151 continue;
3152 switch (Visitor(Cursor, Parent, ClientData)) {
3153 case CXChildVisit_Break:
3154 return true;
3155 case CXChildVisit_Continue:
3156 break;
3157 case CXChildVisit_Recurse:
3158 if (PostChildrenVisitor)
3159 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3160 EnqueueWorkList(WL, S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 break;
3162 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003163 continue;
3164 }
3165 case VisitorJob::MemberExprPartsKind: {
3166 // Handle the other pieces in the MemberExpr besides the base.
3167 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00003168
Michael Kruse7520cf02020-03-25 09:26:14 -05003169 // Visit the nested-name-specifier
3170 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3171 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +00003172 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05003173
3174 // Visit the declaration name.
3175 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3176 return true;
3177
3178 // Visit the explicitly-specified template arguments, if any.
3179 if (M->hasExplicitTemplateArgs()) {
3180 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3181 *ArgEnd = Arg + M->getNumTemplateArgs();
3182 Arg != ArgEnd; ++Arg) {
3183 if (VisitTemplateArgumentLoc(*Arg))
3184 return true;
3185 }
3186 }
3187 continue;
3188 }
3189 case VisitorJob::DeclRefExprPartsKind: {
3190 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3191 // Visit nested-name-specifier, if present.
3192 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3193 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3194 return true;
3195 // Visit declaration name.
3196 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3197 return true;
3198 continue;
3199 }
3200 case VisitorJob::OverloadExprPartsKind: {
3201 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3202 // Visit the nested-name-specifier.
3203 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3204 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3205 return true;
3206 // Visit the declaration name.
3207 if (VisitDeclarationNameInfo(O->getNameInfo()))
3208 return true;
3209 // Visit the overloaded declaration reference.
3210 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3211 return true;
3212 continue;
3213 }
3214 case VisitorJob::SizeOfPackExprPartsKind: {
3215 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3216 NamedDecl *Pack = E->getPack();
3217 if (isa<TemplateTypeParmDecl>(Pack)) {
3218 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3219 E->getPackLoc(), TU)))
3220 return true;
3221
3222 continue;
3223 }
3224
3225 if (isa<TemplateTemplateParmDecl>(Pack)) {
3226 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3227 E->getPackLoc(), TU)))
3228 return true;
3229
3230 continue;
3231 }
3232
3233 // Non-type template parameter packs and function parameter packs are
3234 // treated like DeclRefExpr cursors.
3235 continue;
3236 }
3237
3238 case VisitorJob::LambdaExprPartsKind: {
3239 // Visit non-init captures.
3240 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3241 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3242 CEnd = E->explicit_capture_end();
3243 C != CEnd; ++C) {
3244 if (!C->capturesVariable())
3245 continue;
3246
3247 if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
3248 TU)))
3249 return true;
3250 }
3251 // Visit init captures
3252 for (auto InitExpr : E->capture_inits()) {
3253 if (Visit(InitExpr))
3254 return true;
3255 }
3256
3257 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3258 // Visit parameters and return type, if present.
3259 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3260 if (E->hasExplicitParameters()) {
3261 // Visit parameters.
3262 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3263 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3264 return true;
3265 }
3266 if (E->hasExplicitResultType()) {
3267 // Visit result type.
3268 if (Visit(Proto.getReturnLoc()))
3269 return true;
3270 }
3271 }
3272 break;
3273 }
3274
3275 case VisitorJob::PostChildrenVisitKind:
3276 if (PostChildrenVisitor(Parent, ClientData))
3277 return true;
3278 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00003279 }
3280 }
3281 return false;
3282}
3283
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003284bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00003285 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003286 if (!WorkListFreeList.empty()) {
3287 WL = WorkListFreeList.back();
3288 WL->clear();
3289 WorkListFreeList.pop_back();
Michael Kruse7520cf02020-03-25 09:26:14 -05003290 } else {
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 WL = new VisitorWorkList();
3292 WorkListCache.push_back(WL);
3293 }
3294 EnqueueWorkList(*WL, S);
3295 bool result = RunVisitorWorkList(*WL);
3296 WorkListFreeList.push_back(WL);
3297 return result;
3298}
3299
3300namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003301typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00003302RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3303 const DeclarationNameInfo &NI, SourceRange QLoc,
3304 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3306 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3307 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
Michael Kruse7520cf02020-03-25 09:26:14 -05003308
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
Michael Kruse7520cf02020-03-25 09:26:14 -05003310
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 RefNamePieces Pieces;
3312
3313 if (WantQualifier && QLoc.isValid())
3314 Pieces.push_back(QLoc);
Michael Kruse7520cf02020-03-25 09:26:14 -05003315
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3317 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00003318
3319 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3320 Pieces.push_back(*TemplateArgsLoc);
3321
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 if (Kind == DeclarationName::CXXOperatorName) {
3323 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003324 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003326 NI.getInfo().CXXOperatorName.EndOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003328
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 if (WantSinglePiece) {
3330 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3331 Pieces.clear();
3332 Pieces.push_back(R);
Michael Kruse7520cf02020-03-25 09:26:14 -05003333 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003334
Michael Kruse7520cf02020-03-25 09:26:14 -05003335 return Pieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00003336}
Michael Kruse7520cf02020-03-25 09:26:14 -05003337} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00003338
3339//===----------------------------------------------------------------------===//
3340// Misc. API hooks.
Michael Kruse7520cf02020-03-25 09:26:14 -05003341//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00003342
Chandler Carruth66660742014-06-27 16:37:27 +00003343namespace {
3344struct RegisterFatalErrorHandler {
3345 RegisterFatalErrorHandler() {
Jan Korousf7d23762019-09-12 22:55:55 +00003346 clang_install_aborting_llvm_fatal_error_handler();
Chandler Carruth66660742014-06-27 16:37:27 +00003347 }
3348};
Michael Kruse7520cf02020-03-25 09:26:14 -05003349} // namespace
Chandler Carruth66660742014-06-27 16:37:27 +00003350
Michael Kruse7520cf02020-03-25 09:26:14 -05003351static llvm::ManagedStatic<RegisterFatalErrorHandler>
3352 RegisterFatalErrorHandlerOnce;
Chandler Carruth66660742014-06-27 16:37:27 +00003353
Guy Benyei11169dd2012-12-18 14:30:41 +00003354CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3355 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003356 // We use crash recovery to make some of our APIs more reliable, implicitly
3357 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003358 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3359 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003360
Chandler Carruth66660742014-06-27 16:37:27 +00003361 // Look through the managed static to trigger construction of the managed
3362 // static which registers our fatal error handler. This ensures it is only
3363 // registered once.
3364 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003365
Adrian Prantlbc068582015-07-08 01:00:30 +00003366 // Initialize targets for clang module support.
3367 llvm::InitializeAllTargets();
3368 llvm::InitializeAllTargetMCs();
3369 llvm::InitializeAllAsmPrinters();
3370 llvm::InitializeAllAsmParsers();
3371
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003372 CIndexer *CIdxr = new CIndexer();
3373
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 if (excludeDeclarationsFromPCH)
3375 CIdxr->setOnlyLocalDecls();
3376 if (displayDiagnostics)
3377 CIdxr->setDisplayDiagnostics();
3378
3379 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3380 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3381 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3382 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3383 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3384 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3385
3386 return CIdxr;
3387}
3388
3389void clang_disposeIndex(CXIndex CIdx) {
3390 if (CIdx)
3391 delete static_cast<CIndexer *>(CIdx);
3392}
3393
3394void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3395 if (CIdx)
3396 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3397}
3398
3399unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3400 if (CIdx)
3401 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3402 return 0;
3403}
3404
Alex Lorenz08615792017-12-04 21:56:36 +00003405void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
3406 const char *Path) {
3407 if (CIdx)
3408 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
3409}
3410
Guy Benyei11169dd2012-12-18 14:30:41 +00003411void clang_toggleCrashRecovery(unsigned isEnabled) {
3412 if (isEnabled)
3413 llvm::CrashRecoveryContext::Enable();
3414 else
3415 llvm::CrashRecoveryContext::Disable();
3416}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003417
Guy Benyei11169dd2012-12-18 14:30:41 +00003418CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3419 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003420 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003421 enum CXErrorCode Result =
3422 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003423 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003424 assert((TU && Result == CXError_Success) ||
3425 (!TU && Result != CXError_Success));
3426 return TU;
3427}
3428
3429enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3430 const char *ast_filename,
3431 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003432 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003433 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003434
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003435 if (!CIdx || !ast_filename || !out_TU)
3436 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003437
Michael Kruse7520cf02020-03-25 09:26:14 -05003438 LOG_FUNC_SECTION { *Log << ast_filename; }
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003439
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3441 FileSystemOptions FileSystemOpts;
3442
Justin Bognerd512c1e2014-10-15 00:33:06 +00003443 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3444 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003445 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Richard Smithdbafb6c2017-06-29 23:23:46 +00003446 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
Michael Kruse7520cf02020-03-25 09:26:14 -05003447 ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3448 CXXIdx->getOnlyLocalDecls(), None, CaptureDiagsKind::All,
David Blaikie6f7382d2014-08-10 19:08:04 +00003449 /*AllowPCHWithCompilerErrors=*/true,
3450 /*UserFilesAreVolatile=*/true);
David Blaikieea4395e2017-01-06 19:49:01 +00003451 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003452 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003453}
3454
3455unsigned clang_defaultEditingTranslationUnitOptions() {
Michael Kruse7520cf02020-03-25 09:26:14 -05003456 return CXTranslationUnit_PrecompiledPreamble |
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 CXTranslationUnit_CacheCompletionResults;
3458}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003459
Michael Kruse7520cf02020-03-25 09:26:14 -05003460CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3461 CXIndex CIdx, const char *source_filename, int num_command_line_args,
3462 const char *const *command_line_args, unsigned num_unsaved_files,
3463 struct CXUnsavedFile *unsaved_files) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
Michael Kruse7520cf02020-03-25 09:26:14 -05003465 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3466 num_command_line_args, unsaved_files,
3467 num_unsaved_files, Options);
Guy Benyei11169dd2012-12-18 14:30:41 +00003468}
3469
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003470static CXErrorCode
3471clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3472 const char *const *command_line_args,
3473 int num_command_line_args,
3474 ArrayRef<CXUnsavedFile> unsaved_files,
3475 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003476 // Set up the initial return values.
3477 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003478 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003479
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003480 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003481 if (!CIdx || !out_TU)
3482 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003483
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3485
3486 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3487 setThreadBackgroundPriority();
3488
3489 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003490 bool CreatePreambleOnFirstParse =
3491 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 // FIXME: Add a flag for modules.
Michael Kruse7520cf02020-03-25 09:26:14 -05003493 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3494 CXTranslationUnit_SingleFileParse))
3495 ? TU_Prefix
3496 : TU_Complete;
3497 bool CacheCodeCompletionResults =
3498 options & CXTranslationUnit_CacheCompletionResults;
3499 bool IncludeBriefCommentsInCodeCompletion =
3500 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003501 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
3502 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
Michael Kruse7520cf02020-03-25 09:26:14 -05003503 bool RetainExcludedCB =
3504 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
Ivan Donchevskii6e895282018-05-17 09:24:37 +00003505 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
3506 if (options & CXTranslationUnit_SkipFunctionBodies) {
3507 SkipFunctionBodies =
3508 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
3509 ? SkipFunctionBodiesScope::Preamble
3510 : SkipFunctionBodiesScope::PreambleAndMainFile;
3511 }
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003512
3513 // Configure the diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05003514 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3515 CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003516
Manuel Klimek016c0242016-03-01 10:56:19 +00003517 if (options & CXTranslationUnit_KeepGoing)
Ivan Donchevskii878271b2019-03-07 10:13:50 +00003518 Diags->setFatalsAsError(true);
Manuel Klimek016c0242016-03-01 10:56:19 +00003519
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003520 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
3521 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
3522 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
3523
Guy Benyei11169dd2012-12-18 14:30:41 +00003524 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003525 llvm::CrashRecoveryContextCleanupRegistrar<
3526 DiagnosticsEngine,
3527 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
3528 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003529
Ahmed Charlesb8984322014-03-07 20:03:18 +00003530 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3531 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003532
3533 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003534 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3535 RemappedCleanup(RemappedFiles.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003536
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003537 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003538 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003539 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003540 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 }
3542
Ahmed Charlesb8984322014-03-07 20:03:18 +00003543 std::unique_ptr<std::vector<const char *>> Args(
3544 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003545
3546 // Recover resources if we crash before exiting this method.
Michael Kruse7520cf02020-03-25 09:26:14 -05003547 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
3548 ArgsCleanup(Args.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003549
3550 // Since the Clang C library is primarily used by batch tools dealing with
3551 // (often very broken) source code, where spell-checking can have a
Michael Kruse7520cf02020-03-25 09:26:14 -05003552 // significant negative impact on performance (particularly when
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 // precompiled headers are involved), we disable it by default.
3554 // Only do this if we haven't found a spell-checking-related argument.
3555 bool FoundSpellCheckingArgument = false;
3556 for (int I = 0; I != num_command_line_args; ++I) {
3557 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3558 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3559 FoundSpellCheckingArgument = true;
3560 break;
3561 }
3562 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 Args->insert(Args->end(), command_line_args,
3564 command_line_args + num_command_line_args);
3565
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003566 if (!FoundSpellCheckingArgument)
3567 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3568
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 // The 'source_filename' argument is optional. If the caller does not
3570 // specify it then it is assumed that the source file is specified
3571 // in the actual argument list.
3572 // Put the source file after command_line_args otherwise if '-x' flag is
3573 // present it will be unused.
3574 if (source_filename)
3575 Args->push_back(source_filename);
3576
3577 // Do we need the detailed preprocessing record?
3578 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3579 Args->push_back("-Xclang");
3580 Args->push_back("-detailed-preprocessing-record");
3581 }
Alex Lorenzcb006402017-04-27 13:47:03 +00003582
3583 // Suppress any editor placeholder diagnostics.
3584 Args->push_back("-fallow-editor-placeholders");
3585
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003587 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003588 // Unless the user specified that they want the preamble on the first parse
3589 // set it up to be created on the first reparse. This makes the first parse
3590 // faster, trading for a slower (first) reparse.
3591 unsigned PrecompilePreambleAfterNParses =
3592 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Alex Lorenz08615792017-12-04 21:56:36 +00003593
Alex Lorenz08615792017-12-04 21:56:36 +00003594 LibclangInvocationReporter InvocationReporter(
3595 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
Alex Lorenz690f0e22017-12-07 20:37:50 +00003596 options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
3597 unsaved_files);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003598 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003599 Args->data(), Args->data() + Args->size(),
3600 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003601 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003602 CaptureDiagnostics, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003603 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3604 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Argyrios Kyrtzidis735e92c2017-06-09 01:20:48 +00003605 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
Evgeny Mankov2ed2e622019-08-27 22:15:32 +00003606 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003607 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3608 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003609
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003610 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003611 if (!Unit && !ErrUnit)
3612 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003613
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 if (NumErrors != Diags->getClient()->getNumErrors()) {
3615 // Make sure to check that 'Unit' is non-NULL.
3616 if (CXXIdx->getDisplayDiagnostics())
3617 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3618 }
3619
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003620 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3621 return CXError_ASTReadError;
3622
David Blaikieea4395e2017-01-06 19:49:01 +00003623 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
Alex Lorenz690f0e22017-12-07 20:37:50 +00003624 if (CXTranslationUnitImpl *TU = *out_TU) {
3625 TU->ParsingOptions = options;
3626 TU->Arguments.reserve(Args->size());
3627 for (const char *Arg : *Args)
3628 TU->Arguments.push_back(Arg);
3629 return CXError_Success;
3630 }
3631 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003632}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003633
3634CXTranslationUnit
Michael Kruse7520cf02020-03-25 09:26:14 -05003635clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003636 const char *const *command_line_args,
3637 int num_command_line_args,
3638 struct CXUnsavedFile *unsaved_files,
Michael Kruse7520cf02020-03-25 09:26:14 -05003639 unsigned num_unsaved_files, unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003640 CXTranslationUnit TU;
3641 enum CXErrorCode Result = clang_parseTranslationUnit2(
3642 CIdx, source_filename, command_line_args, num_command_line_args,
3643 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003644 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003645 assert((TU && Result == CXError_Success) ||
3646 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003647 return TU;
3648}
3649
3650enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003651 CXIndex CIdx, const char *source_filename,
3652 const char *const *command_line_args, int num_command_line_args,
3653 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3654 unsigned options, CXTranslationUnit *out_TU) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003655 noteBottomOfStack();
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003656 SmallVector<const char *, 4> Args;
3657 Args.push_back("clang");
3658 Args.append(command_line_args, command_line_args + num_command_line_args);
3659 return clang_parseTranslationUnit2FullArgv(
3660 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3661 num_unsaved_files, options, out_TU);
3662}
3663
3664enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3665 CXIndex CIdx, const char *source_filename,
3666 const char *const *command_line_args, int num_command_line_args,
3667 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3668 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003669 LOG_FUNC_SECTION {
3670 *Log << source_filename << ": ";
3671 for (int i = 0; i != num_command_line_args; ++i)
3672 *Log << command_line_args[i] << " ";
3673 }
3674
Alp Toker9d85b182014-07-07 01:23:14 +00003675 if (num_unsaved_files && !unsaved_files)
3676 return CXError_InvalidArguments;
3677
Alp Toker5c532982014-07-07 22:42:03 +00003678 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003679 auto ParseTranslationUnitImpl = [=, &result] {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003680 noteBottomOfStack();
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003681 result = clang_parseTranslationUnit_Impl(
3682 CIdx, source_filename, command_line_args, num_command_line_args,
3683 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3684 };
Erik Verbruggen284848d2017-08-29 09:08:02 +00003685
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 llvm::CrashRecoveryContext CRC;
3687
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003688 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3690 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3691 fprintf(stderr, " 'command_line_args' : [");
3692 for (int i = 0; i != num_command_line_args; ++i) {
3693 if (i)
3694 fprintf(stderr, ", ");
3695 fprintf(stderr, "'%s'", command_line_args[i]);
3696 }
3697 fprintf(stderr, "],\n");
3698 fprintf(stderr, " 'unsaved_files' : [");
3699 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3700 if (i)
3701 fprintf(stderr, ", ");
3702 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3703 unsaved_files[i].Length);
3704 }
3705 fprintf(stderr, "],\n");
3706 fprintf(stderr, " 'options' : %d,\n", options);
3707 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003708
3709 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003711 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003712 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 }
Alp Toker5c532982014-07-07 22:42:03 +00003714
3715 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003716}
3717
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003718CXString clang_Type_getObjCEncoding(CXType CT) {
3719 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3720 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3721 std::string encoding;
Michael Kruse7520cf02020-03-25 09:26:14 -05003722 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003723
3724 return cxstring::createDup(encoding);
3725}
3726
3727static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3728 if (C.kind == CXCursor_MacroDefinition) {
3729 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3730 return MDR->getName();
3731 } else if (C.kind == CXCursor_MacroExpansion) {
3732 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3733 return ME.getName();
3734 }
3735 return nullptr;
3736}
3737
3738unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3739 const IdentifierInfo *II = getMacroIdentifier(C);
3740 if (!II) {
3741 return false;
3742 }
3743 ASTUnit *ASTU = getCursorASTUnit(C);
3744 Preprocessor &PP = ASTU->getPreprocessor();
3745 if (const MacroInfo *MI = PP.getMacroInfo(II))
3746 return MI->isFunctionLike();
3747 return false;
3748}
3749
3750unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3751 const IdentifierInfo *II = getMacroIdentifier(C);
3752 if (!II) {
3753 return false;
3754 }
3755 ASTUnit *ASTU = getCursorASTUnit(C);
3756 Preprocessor &PP = ASTU->getPreprocessor();
3757 if (const MacroInfo *MI = PP.getMacroInfo(II))
3758 return MI->isBuiltinMacro();
3759 return false;
3760}
3761
3762unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3763 const Decl *D = getCursorDecl(C);
3764 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3765 if (!FD) {
3766 return false;
3767 }
3768 return FD->isInlined();
3769}
3770
Michael Kruse7520cf02020-03-25 09:26:14 -05003771static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003772 if (callExpr->getNumArgs() != 1) {
3773 return nullptr;
3774 }
3775
3776 StringLiteral *S = nullptr;
3777 auto *arg = callExpr->getArg(0);
3778 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3779 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3780 auto *subExpr = I->getSubExprAsWritten();
3781
Michael Kruse7520cf02020-03-25 09:26:14 -05003782 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003783 return nullptr;
3784 }
3785
3786 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3787 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3788 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3789 } else {
3790 return nullptr;
3791 }
3792 return S;
3793}
3794
David Blaikie59272572016-04-13 18:23:33 +00003795struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003796 CXEvalResultKind EvalType;
3797 union {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003798 unsigned long long unsignedVal;
3799 long long intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003800 double floatVal;
3801 char *stringVal;
3802 } EvalData;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003803 bool IsUnsignedInt;
David Blaikie59272572016-04-13 18:23:33 +00003804 ~ExprEvalResult() {
3805 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3806 EvalType != CXEval_Int) {
Alex Lorenza19cb2e2019-01-08 23:28:37 +00003807 delete[] EvalData.stringVal;
David Blaikie59272572016-04-13 18:23:33 +00003808 }
3809 }
3810};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003811
3812void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003813 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003814}
3815
3816CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3817 if (!E) {
3818 return CXEval_UnExposed;
3819 }
3820 return ((ExprEvalResult *)E)->EvalType;
3821}
3822
3823int clang_EvalResult_getAsInt(CXEvalResult E) {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003824 return clang_EvalResult_getAsLongLong(E);
3825}
3826
3827long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003828 if (!E) {
3829 return 0;
3830 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003831 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003832 if (Result->IsUnsignedInt)
3833 return Result->EvalData.unsignedVal;
3834 return Result->EvalData.intVal;
3835}
3836
3837unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
3838 return ((ExprEvalResult *)E)->IsUnsignedInt;
3839}
3840
3841unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
3842 if (!E) {
3843 return 0;
3844 }
3845
Michael Kruse7520cf02020-03-25 09:26:14 -05003846 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003847 if (Result->IsUnsignedInt)
3848 return Result->EvalData.unsignedVal;
3849 return Result->EvalData.intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003850}
3851
3852double clang_EvalResult_getAsDouble(CXEvalResult E) {
3853 if (!E) {
3854 return 0;
3855 }
3856 return ((ExprEvalResult *)E)->EvalData.floatVal;
3857}
3858
Michael Kruse7520cf02020-03-25 09:26:14 -05003859const char *clang_EvalResult_getAsStr(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003860 if (!E) {
3861 return nullptr;
3862 }
3863 return ((ExprEvalResult *)E)->EvalData.stringVal;
3864}
3865
Michael Kruse7520cf02020-03-25 09:26:14 -05003866static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003867 Expr::EvalResult ER;
3868 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003869 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003870 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003871
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003872 expr = expr->IgnoreParens();
Emilio Cobos Alvarez74375452019-07-09 14:27:01 +00003873 if (expr->isValueDependent())
3874 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003875 if (!expr->EvaluateAsRValue(ER, ctx))
3876 return nullptr;
3877
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003878 QualType rettype;
3879 CallExpr *callExpr;
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00003880 auto result = std::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003881 result->EvalType = CXEval_UnExposed;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003882 result->IsUnsignedInt = false;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003883
David Blaikiebbc00882016-04-13 18:36:19 +00003884 if (ER.Val.isInt()) {
3885 result->EvalType = CXEval_Int;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003886
Michael Kruse7520cf02020-03-25 09:26:14 -05003887 auto &val = ER.Val.getInt();
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003888 if (val.isUnsigned()) {
3889 result->IsUnsignedInt = true;
3890 result->EvalData.unsignedVal = val.getZExtValue();
3891 } else {
3892 result->EvalData.intVal = val.getExtValue();
3893 }
3894
David Blaikiebbc00882016-04-13 18:36:19 +00003895 return result.release();
3896 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003897
David Blaikiebbc00882016-04-13 18:36:19 +00003898 if (ER.Val.isFloat()) {
3899 llvm::SmallVector<char, 100> Buffer;
3900 ER.Val.getFloat().toString(Buffer);
3901 std::string floatStr(Buffer.data(), Buffer.size());
3902 result->EvalType = CXEval_Float;
3903 bool ignored;
3904 llvm::APFloat apFloat = ER.Val.getFloat();
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003905 apFloat.convert(llvm::APFloat::IEEEdouble(),
David Blaikiebbc00882016-04-13 18:36:19 +00003906 llvm::APFloat::rmNearestTiesToEven, &ignored);
3907 result->EvalData.floatVal = apFloat.convertToDouble();
3908 return result.release();
3909 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003910
David Blaikiebbc00882016-04-13 18:36:19 +00003911 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3912 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3913 auto *subExpr = I->getSubExprAsWritten();
3914 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3915 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003916 const StringLiteral *StrE = nullptr;
3917 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003918 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003919
3920 if (ObjCExpr) {
3921 StrE = ObjCExpr->getString();
3922 result->EvalType = CXEval_ObjCStrLiteral;
3923 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003924 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003925 result->EvalType = CXEval_StrLiteral;
3926 }
3927
3928 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003929 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003930 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3931 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003932 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003933 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003934 }
3935 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3936 expr->getStmtClass() == Stmt::StringLiteralClass) {
3937 const StringLiteral *StrE = nullptr;
3938 const ObjCStringLiteral *ObjCExpr;
3939 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003940
David Blaikiebbc00882016-04-13 18:36:19 +00003941 if (ObjCExpr) {
3942 StrE = ObjCExpr->getString();
3943 result->EvalType = CXEval_ObjCStrLiteral;
3944 } else {
3945 StrE = cast<StringLiteral>(expr);
3946 result->EvalType = CXEval_StrLiteral;
3947 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003948
David Blaikiebbc00882016-04-13 18:36:19 +00003949 std::string strRef(StrE->getString().str());
3950 result->EvalData.stringVal = new char[strRef.size() + 1];
3951 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3952 result->EvalData.stringVal[strRef.size()] = '\0';
3953 return result.release();
3954 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003955
David Blaikiebbc00882016-04-13 18:36:19 +00003956 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3957 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003958
David Blaikiebbc00882016-04-13 18:36:19 +00003959 rettype = CC->getType();
3960 if (rettype.getAsString() == "CFStringRef" &&
3961 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003962
David Blaikiebbc00882016-04-13 18:36:19 +00003963 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3964 StringLiteral *S = getCFSTR_value(callExpr);
3965 if (S) {
3966 std::string strLiteral(S->getString().str());
3967 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003968
David Blaikiebbc00882016-04-13 18:36:19 +00003969 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3970 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3971 strLiteral.size());
3972 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003973 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003974 }
3975 }
3976
David Blaikiebbc00882016-04-13 18:36:19 +00003977 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3978 callExpr = static_cast<CallExpr *>(expr);
3979 rettype = callExpr->getCallReturnType(ctx);
3980
3981 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
3982 return nullptr;
3983
3984 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3985 if (callExpr->getNumArgs() == 1 &&
3986 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
3987 return nullptr;
3988 } else if (rettype.getAsString() == "CFStringRef") {
3989
3990 StringLiteral *S = getCFSTR_value(callExpr);
3991 if (S) {
3992 std::string strLiteral(S->getString().str());
3993 result->EvalType = CXEval_CFStr;
3994 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3995 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3996 strLiteral.size());
3997 result->EvalData.stringVal[strLiteral.size()] = '\0';
3998 return result.release();
3999 }
4000 }
4001 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
4002 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
4003 ValueDecl *V = D->getDecl();
4004 if (V->getKind() == Decl::Function) {
4005 std::string strName = V->getNameAsString();
4006 result->EvalType = CXEval_Other;
4007 result->EvalData.stringVal = new char[strName.size() + 1];
4008 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
4009 result->EvalData.stringVal[strName.size()] = '\0';
4010 return result.release();
4011 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004012 }
4013
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004014 return nullptr;
4015}
4016
Alex Lorenz65317e12019-01-08 22:32:51 +00004017static const Expr *evaluateDeclExpr(const Decl *D) {
4018 if (!D)
Evgeniy Stepanov9b871492018-07-10 19:48:53 +00004019 return nullptr;
Alex Lorenz65317e12019-01-08 22:32:51 +00004020 if (auto *Var = dyn_cast<VarDecl>(D))
4021 return Var->getInit();
4022 else if (auto *Field = dyn_cast<FieldDecl>(D))
4023 return Field->getInClassInitializer();
4024 return nullptr;
4025}
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004026
Alex Lorenz65317e12019-01-08 22:32:51 +00004027static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4028 assert(CS && "invalid compound statement");
4029 for (auto *bodyIterator : CS->body()) {
4030 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4031 return E;
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004032 }
Alex Lorenzc4cf96e2018-07-09 19:56:45 +00004033 return nullptr;
4034}
4035
Alex Lorenz65317e12019-01-08 22:32:51 +00004036CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
4037 if (const Expr *E =
4038 clang_getCursorKind(C) == CXCursor_CompoundStmt
4039 ? evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)))
4040 : evaluateDeclExpr(getCursorDecl(C)))
4041 return const_cast<CXEvalResult>(
4042 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4043 return nullptr;
4044}
4045
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004046unsigned clang_Cursor_hasAttrs(CXCursor C) {
4047 const Decl *D = getCursorDecl(C);
4048 if (!D) {
4049 return 0;
4050 }
4051
4052 if (D->hasAttrs()) {
4053 return 1;
4054 }
4055
4056 return 0;
4057}
Guy Benyei11169dd2012-12-18 14:30:41 +00004058unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4059 return CXSaveTranslationUnit_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05004060}
Guy Benyei11169dd2012-12-18 14:30:41 +00004061
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004062static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4063 const char *FileName,
4064 unsigned options) {
4065 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4067 setThreadBackgroundPriority();
4068
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004069 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4070 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00004071}
4072
4073int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4074 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004075 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004076
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004077 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004078 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004080 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004081
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004082 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4084 if (!CXXUnit->hasSema())
4085 return CXSaveError_InvalidTU;
4086
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004087 CXSaveError result;
4088 auto SaveTranslationUnitImpl = [=, &result]() {
4089 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4090 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004091
Erik Verbruggen3cc39112017-11-14 09:34:39 +00004092 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004093 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00004094
4095 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4096 PrintLibclangResourceUsage(TU);
4097
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004098 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 }
4100
4101 // We have an AST that has invalid nodes due to compiler errors.
4102 // Use a crash recovery thread for protection.
4103
4104 llvm::CrashRecoveryContext CRC;
4105
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004106 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4108 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4109 fprintf(stderr, " 'options' : %d,\n", options);
4110 fprintf(stderr, "}\n");
4111
4112 return CXSaveError_Unknown;
4113
4114 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4115 PrintLibclangResourceUsage(TU);
4116 }
4117
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004118 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004119}
4120
4121void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4122 if (CTUnit) {
4123 // If the translation unit has been marked as unsafe to free, just discard
4124 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004125 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4126 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 return;
4128
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004129 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00004130 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4132 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00004133 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 delete CTUnit;
4135 }
4136}
4137
Erik Verbruggen346066b2017-05-30 14:25:54 +00004138unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4139 if (CTUnit) {
4140 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4141
4142 if (Unit && Unit->isUnsafeToFree())
4143 return false;
4144
4145 Unit->ResetForParse();
4146 return true;
4147 }
4148
4149 return false;
4150}
4151
Guy Benyei11169dd2012-12-18 14:30:41 +00004152unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4153 return CXReparse_None;
4154}
4155
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004156static CXErrorCode
4157clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4158 ArrayRef<CXUnsavedFile> unsaved_files,
4159 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004160 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004161 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004162 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004163 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004164 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004165
4166 // Reset the associated diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05004167 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00004168 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004169
Dmitri Gribenko183436e2013-01-26 21:49:50 +00004170 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4172 setThreadBackgroundPriority();
4173
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004174 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00004176
4177 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4178 new std::vector<ASTUnit::RemappedFile>());
4179
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05004181 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4182 RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00004183
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004184 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004185 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00004186 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004187 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004189
Adrian Prantlbb165fb2015-06-20 18:53:08 +00004190 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4191 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004192 return CXError_Success;
4193 if (isASTReadError(CXXUnit))
4194 return CXError_ASTReadError;
4195 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00004196}
4197
4198int clang_reparseTranslationUnit(CXTranslationUnit TU,
4199 unsigned num_unsaved_files,
4200 struct CXUnsavedFile *unsaved_files,
4201 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004202 LOG_FUNC_SECTION { *Log << TU; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004203
Alp Toker9d85b182014-07-07 01:23:14 +00004204 if (num_unsaved_files && !unsaved_files)
4205 return CXError_InvalidArguments;
4206
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004207 CXErrorCode result;
4208 auto ReparseTranslationUnitImpl = [=, &result]() {
4209 result = clang_reparseTranslationUnit_Impl(
4210 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
4211 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004212
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 llvm::CrashRecoveryContext CRC;
4214
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004215 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004217 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004218 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4220 PrintLibclangResourceUsage(TU);
4221
Alp Toker5c532982014-07-07 22:42:03 +00004222 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004223}
4224
Guy Benyei11169dd2012-12-18 14:30:41 +00004225CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004226 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004227 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004228 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004229 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004230
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004231 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004232 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004233}
4234
4235CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004236 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004237 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004238 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004239 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004240
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004241 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4243}
4244
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004245CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4246 if (isNotUsableTU(CTUnit)) {
4247 LOG_BAD_TU(CTUnit);
4248 return nullptr;
4249 }
4250
Michael Kruse7520cf02020-03-25 09:26:14 -05004251 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004252 impl->TranslationUnit = CTUnit;
4253 return impl;
4254}
4255
4256CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4257 if (!TargetInfo)
4258 return cxstring::createEmpty();
4259
4260 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4261 assert(!isNotUsableTU(CTUnit) &&
4262 "Unexpected unusable translation unit in TargetInfo");
4263
4264 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4265 std::string Triple =
Michael Kruse7520cf02020-03-25 09:26:14 -05004266 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004267 return cxstring::createDup(Triple);
4268}
4269
4270int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4271 if (!TargetInfo)
4272 return -1;
4273
4274 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4275 assert(!isNotUsableTU(CTUnit) &&
4276 "Unexpected unusable translation unit in TargetInfo");
4277
4278 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4279 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4280}
4281
4282void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4283 if (!TargetInfo)
4284 return;
4285
4286 delete TargetInfo;
4287}
4288
Guy Benyei11169dd2012-12-18 14:30:41 +00004289//===----------------------------------------------------------------------===//
4290// CXFile Operations.
4291//===----------------------------------------------------------------------===//
4292
Guy Benyei11169dd2012-12-18 14:30:41 +00004293CXString clang_getFileName(CXFile SFile) {
4294 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00004295 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00004296
4297 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004298 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004299}
4300
4301time_t clang_getFileTime(CXFile SFile) {
4302 if (!SFile)
4303 return 0;
4304
4305 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4306 return FEnt->getModificationTime();
4307}
4308
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004309CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004310 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004311 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00004312 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004313 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004314
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004315 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004316
4317 FileManager &FMgr = CXXUnit->getFileManager();
Harlan Haskins8d323d12019-08-01 21:31:56 +00004318 auto File = FMgr.getFile(file_name);
4319 if (!File)
4320 return nullptr;
4321 return const_cast<FileEntry *>(*File);
Guy Benyei11169dd2012-12-18 14:30:41 +00004322}
4323
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004324const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4325 size_t *size) {
4326 if (isNotUsableTU(TU)) {
4327 LOG_BAD_TU(TU);
4328 return nullptr;
4329 }
4330
4331 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4332 FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
4333 bool Invalid = true;
Nico Weber04347d82019-04-04 21:06:41 +00004334 const llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid);
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004335 if (Invalid) {
4336 if (size)
4337 *size = 0;
4338 return nullptr;
4339 }
4340 if (size)
4341 *size = buf->getBufferSize();
4342 return buf->getBufferStart();
4343}
4344
Michael Kruse7520cf02020-03-25 09:26:14 -05004345unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004346 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004347 LOG_BAD_TU(TU);
4348 return 0;
4349 }
4350
4351 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00004352 return 0;
4353
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004354 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004355 FileEntry *FEnt = static_cast<FileEntry *>(file);
Michael Kruse7520cf02020-03-25 09:26:14 -05004356 return CXXUnit->getPreprocessor()
4357 .getHeaderSearchInfo()
4358 .isFileMultipleIncludeGuarded(FEnt);
Guy Benyei11169dd2012-12-18 14:30:41 +00004359}
4360
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004361int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
4362 if (!file || !outID)
4363 return 1;
4364
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004365 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00004366 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
4367 outID->data[0] = ID.getDevice();
4368 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004369 outID->data[2] = FEnt->getModificationTime();
4370 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004371}
4372
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00004373int clang_File_isEqual(CXFile file1, CXFile file2) {
4374 if (file1 == file2)
4375 return true;
4376
4377 if (!file1 || !file2)
4378 return false;
4379
4380 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
4381 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
4382 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
4383}
4384
Fangrui Songe46ac5f2018-04-07 20:50:35 +00004385CXString clang_File_tryGetRealPathName(CXFile SFile) {
4386 if (!SFile)
4387 return cxstring::createNull();
4388
4389 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4390 return cxstring::createRef(FEnt->tryGetRealPathName());
4391}
4392
Guy Benyei11169dd2012-12-18 14:30:41 +00004393//===----------------------------------------------------------------------===//
4394// CXCursor Operations.
4395//===----------------------------------------------------------------------===//
4396
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004397static const Decl *getDeclFromExpr(const Stmt *E) {
4398 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 return getDeclFromExpr(CE->getSubExpr());
4400
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004401 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004402 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004403 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004405 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004406 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004407 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 if (PRE->isExplicitProperty())
4409 return PRE->getExplicitProperty();
4410 // It could be messaging both getter and setter as in:
4411 // ++myobj.myprop;
4412 // in which case prefer to associate the setter since it is less obvious
4413 // from inspecting the source that the setter is going to get called.
4414 if (PRE->isMessagingSetter())
4415 return PRE->getImplicitPropertySetter();
4416 return PRE->getImplicitPropertyGetter();
4417 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004418 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004420 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 if (Expr *Src = OVE->getSourceExpr())
4422 return getDeclFromExpr(Src);
Michael Kruse7520cf02020-03-25 09:26:14 -05004423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004424 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004425 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004426 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004427 if (!CE->isElidable())
Michael Kruse7520cf02020-03-25 09:26:14 -05004428 return CE->getConstructor();
Richard Smith5179eb72016-06-28 19:03:57 +00004429 if (const CXXInheritedCtorInitExpr *CE =
4430 dyn_cast<CXXInheritedCtorInitExpr>(E))
4431 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004432 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 return OME->getMethodDecl();
4434
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004435 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 return PE->getProtocol();
Michael Kruse7520cf02020-03-25 09:26:14 -05004437 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4438 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004440 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004441 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 isa<ParmVarDecl>(SizeOfPack->getPack()))
4443 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00004444
4445 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004446}
4447
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004448static SourceLocation getLocationFromExpr(const Expr *E) {
4449 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004450 return getLocationFromExpr(CE->getSubExpr());
4451
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004452 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004453 return /*FIXME:*/ Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004454 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004456 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004458 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004460 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004461 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004462 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 return PropRef->getLocation();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004464
4465 return E->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00004466}
4467
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00004468extern "C" {
4469
Michael Kruse7520cf02020-03-25 09:26:14 -05004470unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 CXClientData client_data) {
4472 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4473 /*VisitPreprocessorLast=*/false);
4474 return CursorVis.VisitChildren(parent);
4475}
4476
4477#ifndef __has_feature
4478#define __has_feature(x) 0
4479#endif
4480#if __has_feature(blocks)
Michael Kruse7520cf02020-03-25 09:26:14 -05004481typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4482 CXCursor parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00004483
4484static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004485 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004486 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4487 return block(cursor, parent);
4488}
4489#else
4490// If we are compiled with a compiler that doesn't have native blocks support,
Michael Kruse7520cf02020-03-25 09:26:14 -05004491// define and call the block manually, so the
4492typedef struct _CXChildVisitResult {
4493 void *isa;
4494 int flags;
4495 int reserved;
4496 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
4497 CXCursor);
4498} * CXCursorVisitorBlock;
Guy Benyei11169dd2012-12-18 14:30:41 +00004499
4500static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004501 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4503 return block->invoke(block, cursor, parent);
4504}
4505#endif
4506
Guy Benyei11169dd2012-12-18 14:30:41 +00004507unsigned clang_visitChildrenWithBlock(CXCursor parent,
4508 CXCursorVisitorBlock block) {
4509 return clang_visitChildren(parent, visitWithBlock, block);
4510}
4511
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004514 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004515
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004516 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004518 if (const ObjCPropertyImplDecl *PropImpl =
4519 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004521 return cxstring::createDup(Property->getIdentifier()->getName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004522
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004523 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004525 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004526
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004527 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004529
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004530 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004531 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004532
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004533 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4535 // and returns different names. NamedDecl returns the class name and
4536 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004537 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004538
4539 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004540 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05004541
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 SmallString<1024> S;
4543 llvm::raw_svector_ostream os(S);
4544 ND->printName(os);
Michael Kruse7520cf02020-03-25 09:26:14 -05004545
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004546 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004547}
4548
4549CXString clang_getCursorSpelling(CXCursor C) {
4550 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004551 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004552
4553 if (clang_isReference(C.kind)) {
4554 switch (C.kind) {
4555 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004556 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004557 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 }
4559 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004560 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004561 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 }
4563 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004564 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004566 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 }
4568 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004569 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004570 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 }
4572 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004573 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004574 assert(Type && "Missing type decl");
4575
Michael Kruse7520cf02020-03-25 09:26:14 -05004576 return cxstring::createDup(
4577 getCursorContext(C).getTypeDeclType(Type).getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 }
4579 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004580 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 assert(Template && "Missing template decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004582
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004583 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004585
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004587 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 assert(NS && "Missing namespace decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004589
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004590 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 }
4592
4593 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004594 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 assert(Field && "Missing member decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004596
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004597 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 }
4599
4600 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004601 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004602 assert(Label && "Missing label");
Michael Kruse7520cf02020-03-25 09:26:14 -05004603
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004604 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 }
4606
4607 case CXCursor_OverloadedDeclRef: {
4608 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004609 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4610 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004611 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004612 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004614 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004615 return cxstring::createDup(E->getName().getAsString());
Michael Kruse7520cf02020-03-25 09:26:14 -05004616 OverloadedTemplateStorage *Ovl =
4617 Storage.get<OverloadedTemplateStorage *>();
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004619 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004620 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004622
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004624 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004625 assert(Var && "Missing variable decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004626
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004627 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004629
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004631 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 }
4633 }
4634
4635 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004636 const Expr *E = getCursorExpr(C);
4637
4638 if (C.kind == CXCursor_ObjCStringLiteral ||
4639 C.kind == CXCursor_StringLiteral) {
4640 const StringLiteral *SLit;
4641 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4642 SLit = OSL->getString();
4643 } else {
4644 SLit = cast<StringLiteral>(E);
4645 }
4646 SmallString<256> Buf;
4647 llvm::raw_svector_ostream OS(Buf);
4648 SLit->outputString(OS);
4649 return cxstring::createDup(OS.str());
4650 }
4651
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004652 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 if (D)
4654 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004655 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004656 }
4657
4658 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004659 const Stmt *S = getCursorStmt(C);
4660 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004661 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004662
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004663 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004665
Guy Benyei11169dd2012-12-18 14:30:41 +00004666 if (C.kind == CXCursor_MacroExpansion)
Michael Kruse7520cf02020-03-25 09:26:14 -05004667 return cxstring::createRef(
4668 getCursorMacroExpansion(C).getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004669
4670 if (C.kind == CXCursor_MacroDefinition)
Michael Kruse7520cf02020-03-25 09:26:14 -05004671 return cxstring::createRef(
4672 getCursorMacroDefinition(C)->getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004673
4674 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004675 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004676
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 if (clang_isDeclaration(C.kind))
4678 return getDeclSpelling(getCursorDecl(C));
4679
4680 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004681 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004682 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 }
4684
4685 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004686 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004687 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 }
4689
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004690 if (C.kind == CXCursor_PackedAttr) {
4691 return cxstring::createRef("packed");
4692 }
4693
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004694 if (C.kind == CXCursor_VisibilityAttr) {
4695 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4696 switch (AA->getVisibility()) {
4697 case VisibilityAttr::VisibilityType::Default:
4698 return cxstring::createRef("default");
4699 case VisibilityAttr::VisibilityType::Hidden:
4700 return cxstring::createRef("hidden");
4701 case VisibilityAttr::VisibilityType::Protected:
4702 return cxstring::createRef("protected");
4703 }
4704 llvm_unreachable("unknown visibility type");
4705 }
4706
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004707 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004708}
4709
Michael Kruse7520cf02020-03-25 09:26:14 -05004710CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 unsigned options) {
4712 if (clang_Cursor_isNull(C))
4713 return clang_getNullRange();
4714
4715 ASTContext &Ctx = getCursorContext(C);
4716
4717 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004718 const Stmt *S = getCursorStmt(C);
4719 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 if (pieceIndex > 0)
4721 return clang_getNullRange();
4722 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4723 }
4724
4725 return clang_getNullRange();
4726 }
4727
4728 if (C.kind == CXCursor_ObjCMessageExpr) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004729 if (const ObjCMessageExpr *ME =
4730 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 if (pieceIndex >= ME->getNumSelectorLocs())
4732 return clang_getNullRange();
4733 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4734 }
4735 }
4736
4737 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4738 C.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004739 if (const ObjCMethodDecl *MD =
4740 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 if (pieceIndex >= MD->getNumSelectorLocs())
4742 return clang_getNullRange();
4743 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4744 }
4745 }
4746
4747 if (C.kind == CXCursor_ObjCCategoryDecl ||
4748 C.kind == CXCursor_ObjCCategoryImplDecl) {
4749 if (pieceIndex > 0)
4750 return clang_getNullRange();
Michael Kruse7520cf02020-03-25 09:26:14 -05004751 if (const ObjCCategoryDecl *CD =
4752 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Michael Kruse7520cf02020-03-25 09:26:14 -05004754 if (const ObjCCategoryImplDecl *CID =
4755 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4757 }
4758
4759 if (C.kind == CXCursor_ModuleImportDecl) {
4760 if (pieceIndex > 0)
4761 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004762 if (const ImportDecl *ImportD =
4763 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4765 if (!Locs.empty())
Michael Kruse7520cf02020-03-25 09:26:14 -05004766 return cxloc::translateSourceRange(
4767 Ctx, SourceRange(Locs.front(), Locs.back()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 }
4769 return clang_getNullRange();
4770 }
4771
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004772 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
Kevin Funk4be5d672016-12-20 09:56:56 +00004773 C.kind == CXCursor_ConversionFunction ||
4774 C.kind == CXCursor_FunctionDecl) {
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004775 if (pieceIndex > 0)
4776 return clang_getNullRange();
4777 if (const FunctionDecl *FD =
4778 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4779 DeclarationNameInfo FunctionName = FD->getNameInfo();
4780 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4781 }
4782 return clang_getNullRange();
4783 }
4784
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 // FIXME: A CXCursor_InclusionDirective should give the location of the
4786 // filename, but we don't keep track of this.
4787
4788 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4789 // but we don't keep track of this.
4790
4791 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4792 // but we don't keep track of this.
4793
4794 // Default handling, give the location of the cursor.
4795
4796 if (pieceIndex > 0)
4797 return clang_getNullRange();
4798
4799 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4800 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4801 return cxloc::translateSourceRange(Ctx, Loc);
4802}
4803
Eli Bendersky44a206f2014-07-31 18:04:56 +00004804CXString clang_Cursor_getMangling(CXCursor C) {
4805 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4806 return cxstring::createEmpty();
4807
Eli Bendersky44a206f2014-07-31 18:04:56 +00004808 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004809 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004810 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4811 return cxstring::createEmpty();
4812
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004813 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004814 ASTNameGenerator ASTNameGen(Ctx);
4815 return cxstring::createDup(ASTNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004816}
4817
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004818CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4819 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4820 return nullptr;
4821
4822 const Decl *D = getCursorDecl(C);
4823 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4824 return nullptr;
4825
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004826 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004827 ASTNameGenerator ASTNameGen(Ctx);
4828 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004829 return cxstring::createSet(Manglings);
4830}
4831
Dave Lee1a532c92017-09-22 16:58:57 +00004832CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
4833 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4834 return nullptr;
4835
4836 const Decl *D = getCursorDecl(C);
4837 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
4838 return nullptr;
4839
4840 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004841 ASTNameGenerator ASTNameGen(Ctx);
4842 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Dave Lee1a532c92017-09-22 16:58:57 +00004843 return cxstring::createSet(Manglings);
4844}
4845
Jonathan Coe45ef5032018-01-16 10:19:56 +00004846CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
4847 if (clang_Cursor_isNull(C))
4848 return 0;
4849 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
4850}
4851
4852void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
4853 if (Policy)
4854 delete static_cast<PrintingPolicy *>(Policy);
4855}
4856
4857unsigned
4858clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
4859 enum CXPrintingPolicyProperty Property) {
4860 if (!Policy)
4861 return 0;
4862
4863 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4864 switch (Property) {
4865 case CXPrintingPolicy_Indentation:
4866 return P->Indentation;
4867 case CXPrintingPolicy_SuppressSpecifiers:
4868 return P->SuppressSpecifiers;
4869 case CXPrintingPolicy_SuppressTagKeyword:
4870 return P->SuppressTagKeyword;
4871 case CXPrintingPolicy_IncludeTagDefinition:
4872 return P->IncludeTagDefinition;
4873 case CXPrintingPolicy_SuppressScope:
4874 return P->SuppressScope;
4875 case CXPrintingPolicy_SuppressUnwrittenScope:
4876 return P->SuppressUnwrittenScope;
4877 case CXPrintingPolicy_SuppressInitializers:
4878 return P->SuppressInitializers;
4879 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4880 return P->ConstantArraySizeAsWritten;
4881 case CXPrintingPolicy_AnonymousTagLocations:
4882 return P->AnonymousTagLocations;
4883 case CXPrintingPolicy_SuppressStrongLifetime:
4884 return P->SuppressStrongLifetime;
4885 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4886 return P->SuppressLifetimeQualifiers;
4887 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4888 return P->SuppressTemplateArgsInCXXConstructors;
4889 case CXPrintingPolicy_Bool:
4890 return P->Bool;
4891 case CXPrintingPolicy_Restrict:
4892 return P->Restrict;
4893 case CXPrintingPolicy_Alignof:
4894 return P->Alignof;
4895 case CXPrintingPolicy_UnderscoreAlignof:
4896 return P->UnderscoreAlignof;
4897 case CXPrintingPolicy_UseVoidForZeroParams:
4898 return P->UseVoidForZeroParams;
4899 case CXPrintingPolicy_TerseOutput:
4900 return P->TerseOutput;
4901 case CXPrintingPolicy_PolishForDeclaration:
4902 return P->PolishForDeclaration;
4903 case CXPrintingPolicy_Half:
4904 return P->Half;
4905 case CXPrintingPolicy_MSWChar:
4906 return P->MSWChar;
4907 case CXPrintingPolicy_IncludeNewlines:
4908 return P->IncludeNewlines;
4909 case CXPrintingPolicy_MSVCFormatting:
4910 return P->MSVCFormatting;
4911 case CXPrintingPolicy_ConstantsAsWritten:
4912 return P->ConstantsAsWritten;
4913 case CXPrintingPolicy_SuppressImplicitBase:
4914 return P->SuppressImplicitBase;
4915 case CXPrintingPolicy_FullyQualifiedName:
4916 return P->FullyQualifiedName;
4917 }
4918
4919 assert(false && "Invalid CXPrintingPolicyProperty");
4920 return 0;
4921}
4922
4923void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
4924 enum CXPrintingPolicyProperty Property,
4925 unsigned Value) {
4926 if (!Policy)
4927 return;
4928
4929 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4930 switch (Property) {
4931 case CXPrintingPolicy_Indentation:
4932 P->Indentation = Value;
4933 return;
4934 case CXPrintingPolicy_SuppressSpecifiers:
4935 P->SuppressSpecifiers = Value;
4936 return;
4937 case CXPrintingPolicy_SuppressTagKeyword:
4938 P->SuppressTagKeyword = Value;
4939 return;
4940 case CXPrintingPolicy_IncludeTagDefinition:
4941 P->IncludeTagDefinition = Value;
4942 return;
4943 case CXPrintingPolicy_SuppressScope:
4944 P->SuppressScope = Value;
4945 return;
4946 case CXPrintingPolicy_SuppressUnwrittenScope:
4947 P->SuppressUnwrittenScope = Value;
4948 return;
4949 case CXPrintingPolicy_SuppressInitializers:
4950 P->SuppressInitializers = Value;
4951 return;
4952 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4953 P->ConstantArraySizeAsWritten = Value;
4954 return;
4955 case CXPrintingPolicy_AnonymousTagLocations:
4956 P->AnonymousTagLocations = Value;
4957 return;
4958 case CXPrintingPolicy_SuppressStrongLifetime:
4959 P->SuppressStrongLifetime = Value;
4960 return;
4961 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4962 P->SuppressLifetimeQualifiers = Value;
4963 return;
4964 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4965 P->SuppressTemplateArgsInCXXConstructors = Value;
4966 return;
4967 case CXPrintingPolicy_Bool:
4968 P->Bool = Value;
4969 return;
4970 case CXPrintingPolicy_Restrict:
4971 P->Restrict = Value;
4972 return;
4973 case CXPrintingPolicy_Alignof:
4974 P->Alignof = Value;
4975 return;
4976 case CXPrintingPolicy_UnderscoreAlignof:
4977 P->UnderscoreAlignof = Value;
4978 return;
4979 case CXPrintingPolicy_UseVoidForZeroParams:
4980 P->UseVoidForZeroParams = Value;
4981 return;
4982 case CXPrintingPolicy_TerseOutput:
4983 P->TerseOutput = Value;
4984 return;
4985 case CXPrintingPolicy_PolishForDeclaration:
4986 P->PolishForDeclaration = Value;
4987 return;
4988 case CXPrintingPolicy_Half:
4989 P->Half = Value;
4990 return;
4991 case CXPrintingPolicy_MSWChar:
4992 P->MSWChar = Value;
4993 return;
4994 case CXPrintingPolicy_IncludeNewlines:
4995 P->IncludeNewlines = Value;
4996 return;
4997 case CXPrintingPolicy_MSVCFormatting:
4998 P->MSVCFormatting = Value;
4999 return;
5000 case CXPrintingPolicy_ConstantsAsWritten:
5001 P->ConstantsAsWritten = Value;
5002 return;
5003 case CXPrintingPolicy_SuppressImplicitBase:
5004 P->SuppressImplicitBase = Value;
5005 return;
5006 case CXPrintingPolicy_FullyQualifiedName:
5007 P->FullyQualifiedName = Value;
5008 return;
5009 }
5010
5011 assert(false && "Invalid CXPrintingPolicyProperty");
5012}
5013
5014CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
5015 if (clang_Cursor_isNull(C))
5016 return cxstring::createEmpty();
5017
5018 if (clang_isDeclaration(C.kind)) {
5019 const Decl *D = getCursorDecl(C);
5020 if (!D)
5021 return cxstring::createEmpty();
5022
5023 SmallString<128> Str;
5024 llvm::raw_svector_ostream OS(Str);
5025 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5026 D->print(OS, UserPolicy ? *UserPolicy
5027 : getCursorContext(C).getPrintingPolicy());
5028
5029 return cxstring::createDup(OS.str());
5030 }
5031
5032 return cxstring::createEmpty();
5033}
5034
Guy Benyei11169dd2012-12-18 14:30:41 +00005035CXString clang_getCursorDisplayName(CXCursor C) {
5036 if (!clang_isDeclaration(C.kind))
5037 return clang_getCursorSpelling(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05005038
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005039 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005040 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005041 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005042
5043 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005044 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 D = FunTmpl->getTemplatedDecl();
Michael Kruse7520cf02020-03-25 09:26:14 -05005046
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005047 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005048 SmallString<64> Str;
5049 llvm::raw_svector_ostream OS(Str);
5050 OS << *Function;
5051 if (Function->getPrimaryTemplate())
5052 OS << "<>";
5053 OS << "(";
5054 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5055 if (I)
5056 OS << ", ";
5057 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5058 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005059
Guy Benyei11169dd2012-12-18 14:30:41 +00005060 if (Function->isVariadic()) {
5061 if (Function->getNumParams())
5062 OS << ", ";
5063 OS << "...";
5064 }
5065 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005066 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005068
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005069 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005070 SmallString<64> Str;
5071 llvm::raw_svector_ostream OS(Str);
5072 OS << *ClassTemplate;
5073 OS << "<";
5074 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5075 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5076 if (I)
5077 OS << ", ";
Michael Kruse7520cf02020-03-25 09:26:14 -05005078
Guy Benyei11169dd2012-12-18 14:30:41 +00005079 NamedDecl *Param = Params->getParam(I);
5080 if (Param->getIdentifier()) {
5081 OS << Param->getIdentifier()->getName();
5082 continue;
5083 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005084
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 // There is no parameter name, which makes this tricky. Try to come up
5086 // with something useful that isn't too long.
5087 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
Saar Razff1e0fc2020-01-15 02:48:42 +02005088 if (const auto *TC = TTP->getTypeConstraint()) {
5089 TC->getConceptNameInfo().printName(OS, Policy);
5090 if (TC->hasExplicitTemplateArgs())
5091 OS << "<...>";
5092 } else
Michael Kruse7520cf02020-03-25 09:26:14 -05005093 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5094 else if (NonTypeTemplateParmDecl *NTTP =
5095 dyn_cast<NonTypeTemplateParmDecl>(Param))
Guy Benyei11169dd2012-12-18 14:30:41 +00005096 OS << NTTP->getType().getAsString(Policy);
5097 else
5098 OS << "template<...> class";
5099 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005100
Guy Benyei11169dd2012-12-18 14:30:41 +00005101 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005102 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005104
5105 if (const ClassTemplateSpecializationDecl *ClassSpec =
5106 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005107 // If the type was explicitly written, use that.
5108 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005109 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Serge Pavlov03e672c2017-11-28 16:14:14 +00005110
Benjamin Kramer9170e912013-02-22 15:46:01 +00005111 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 llvm::raw_svector_ostream OS(Str);
5113 OS << *ClassSpec;
Serge Pavlov03e672c2017-11-28 16:14:14 +00005114 printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
5115 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005116 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005118
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 return clang_getCursorSpelling(C);
5120}
Michael Kruse7520cf02020-03-25 09:26:14 -05005121
Guy Benyei11169dd2012-12-18 14:30:41 +00005122CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5123 switch (Kind) {
5124 case CXCursor_FunctionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005125 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 case CXCursor_TypedefDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005127 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 case CXCursor_EnumDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005129 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 case CXCursor_EnumConstantDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005131 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 case CXCursor_StructDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005133 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 case CXCursor_UnionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005135 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 case CXCursor_ClassDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005137 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 case CXCursor_FieldDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005139 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 case CXCursor_VarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005141 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 case CXCursor_ParmDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005143 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 case CXCursor_ObjCInterfaceDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005145 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 case CXCursor_ObjCCategoryDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005147 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 case CXCursor_ObjCProtocolDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005149 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 case CXCursor_ObjCPropertyDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005151 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 case CXCursor_ObjCIvarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005153 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 case CXCursor_ObjCInstanceMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005155 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 case CXCursor_ObjCClassMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005157 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 case CXCursor_ObjCImplementationDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005159 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 case CXCursor_ObjCCategoryImplDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005161 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 case CXCursor_CXXMethod:
Michael Kruse7520cf02020-03-25 09:26:14 -05005163 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 case CXCursor_UnexposedDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005165 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005167 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 case CXCursor_ObjCProtocolRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005169 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 case CXCursor_ObjCClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005171 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 case CXCursor_TypeRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005173 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 case CXCursor_TemplateRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005175 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005177 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005179 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005181 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005183 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005185 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 case CXCursor_IntegerLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005187 return cxstring::createRef("IntegerLiteral");
Leonard Chandb01c3a2018-06-20 17:19:40 +00005188 case CXCursor_FixedPointLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005189 return cxstring::createRef("FixedPointLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 case CXCursor_FloatingLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005191 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 case CXCursor_ImaginaryLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005193 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 case CXCursor_StringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005195 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 case CXCursor_CharacterLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005197 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 case CXCursor_ParenExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005199 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 case CXCursor_UnaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005201 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 case CXCursor_ArraySubscriptExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005203 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00005204 case CXCursor_OMPArraySectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005205 return cxstring::createRef("OMPArraySectionExpr");
Alexey Bataev7ac9efb2020-02-05 09:33:05 -05005206 case CXCursor_OMPArrayShapingExpr:
5207 return cxstring::createRef("OMPArrayShapingExpr");
Alexey Bataev13a15042020-04-01 15:06:38 -04005208 case CXCursor_OMPIteratorExpr:
5209 return cxstring::createRef("OMPIteratorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 case CXCursor_BinaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005211 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 case CXCursor_CompoundAssignOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005213 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 case CXCursor_ConditionalOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005215 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 case CXCursor_CStyleCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005217 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 case CXCursor_CompoundLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005219 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 case CXCursor_InitListExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005221 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 case CXCursor_AddrLabelExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005223 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 case CXCursor_StmtExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005225 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 case CXCursor_GenericSelectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005227 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 case CXCursor_GNUNullExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005229 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 case CXCursor_CXXStaticCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005231 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 case CXCursor_CXXDynamicCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005233 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 case CXCursor_CXXReinterpretCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005235 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 case CXCursor_CXXConstCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005237 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 case CXCursor_CXXFunctionalCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005239 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 case CXCursor_CXXTypeidExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005241 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 case CXCursor_CXXBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005243 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 case CXCursor_CXXNullPtrLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005245 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 case CXCursor_CXXThisExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005247 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 case CXCursor_CXXThrowExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005249 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 case CXCursor_CXXNewExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005251 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 case CXCursor_CXXDeleteExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005253 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 case CXCursor_UnaryExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005255 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 case CXCursor_ObjCStringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005257 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 case CXCursor_ObjCBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005259 return cxstring::createRef("ObjCBoolLiteralExpr");
Erik Pilkington29099de2016-07-16 00:35:23 +00005260 case CXCursor_ObjCAvailabilityCheckExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005261 return cxstring::createRef("ObjCAvailabilityCheckExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00005262 case CXCursor_ObjCSelfExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005263 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 case CXCursor_ObjCEncodeExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005265 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 case CXCursor_ObjCSelectorExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005267 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 case CXCursor_ObjCProtocolExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005269 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 case CXCursor_ObjCBridgedCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005271 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 case CXCursor_BlockExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005273 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 case CXCursor_PackExpansionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005275 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 case CXCursor_SizeOfPackExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005277 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005279 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 case CXCursor_UnexposedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005281 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 case CXCursor_DeclRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005283 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 case CXCursor_MemberRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005285 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005287 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 case CXCursor_ObjCMessageExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005289 return cxstring::createRef("ObjCMessageExpr");
Erik Pilkingtoneee944e2019-07-02 18:28:13 +00005290 case CXCursor_BuiltinBitCastExpr:
5291 return cxstring::createRef("BuiltinBitCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 case CXCursor_UnexposedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005293 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 case CXCursor_DeclStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005295 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 case CXCursor_LabelStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005297 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 case CXCursor_CompoundStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005299 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 case CXCursor_CaseStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005301 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 case CXCursor_DefaultStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005303 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 case CXCursor_IfStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005305 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 case CXCursor_SwitchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005307 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 case CXCursor_WhileStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005309 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 case CXCursor_DoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005311 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 case CXCursor_ForStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005313 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 case CXCursor_GotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005315 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 case CXCursor_IndirectGotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005317 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 case CXCursor_ContinueStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005319 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 case CXCursor_BreakStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005321 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 case CXCursor_ReturnStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005323 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 case CXCursor_GCCAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005325 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 case CXCursor_MSAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005327 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 case CXCursor_ObjCAtTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005329 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 case CXCursor_ObjCAtCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005331 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 case CXCursor_ObjCAtFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005333 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 case CXCursor_ObjCAtThrowStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005335 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 case CXCursor_ObjCAtSynchronizedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005337 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 case CXCursor_ObjCAutoreleasePoolStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005339 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 case CXCursor_ObjCForCollectionStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005341 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 case CXCursor_CXXCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005343 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 case CXCursor_CXXTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005345 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 case CXCursor_CXXForRangeStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005347 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 case CXCursor_SEHTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005349 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 case CXCursor_SEHExceptStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005351 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 case CXCursor_SEHFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005353 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00005354 case CXCursor_SEHLeaveStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005355 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 case CXCursor_NullStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005357 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 case CXCursor_InvalidFile:
Michael Kruse7520cf02020-03-25 09:26:14 -05005359 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005361 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 case CXCursor_NoDeclFound:
Michael Kruse7520cf02020-03-25 09:26:14 -05005363 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 case CXCursor_NotImplemented:
Michael Kruse7520cf02020-03-25 09:26:14 -05005365 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 case CXCursor_TranslationUnit:
Michael Kruse7520cf02020-03-25 09:26:14 -05005367 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00005368 case CXCursor_UnexposedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005369 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 case CXCursor_IBActionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005371 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 case CXCursor_IBOutletAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005373 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 case CXCursor_IBOutletCollectionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005375 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 case CXCursor_CXXFinalAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005377 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 case CXCursor_CXXOverrideAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005379 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005381 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005382 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005383 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005384 case CXCursor_PackedAttr:
5385 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00005386 case CXCursor_PureAttr:
5387 return cxstring::createRef("attribute(pure)");
5388 case CXCursor_ConstAttr:
5389 return cxstring::createRef("attribute(const)");
5390 case CXCursor_NoDuplicateAttr:
5391 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00005392 case CXCursor_CUDAConstantAttr:
5393 return cxstring::createRef("attribute(constant)");
5394 case CXCursor_CUDADeviceAttr:
5395 return cxstring::createRef("attribute(device)");
5396 case CXCursor_CUDAGlobalAttr:
5397 return cxstring::createRef("attribute(global)");
5398 case CXCursor_CUDAHostAttr:
5399 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00005400 case CXCursor_CUDASharedAttr:
5401 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00005402 case CXCursor_VisibilityAttr:
5403 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00005404 case CXCursor_DLLExport:
5405 return cxstring::createRef("attribute(dllexport)");
5406 case CXCursor_DLLImport:
5407 return cxstring::createRef("attribute(dllimport)");
Michael Wud092d0b2018-08-03 05:03:22 +00005408 case CXCursor_NSReturnsRetained:
5409 return cxstring::createRef("attribute(ns_returns_retained)");
5410 case CXCursor_NSReturnsNotRetained:
5411 return cxstring::createRef("attribute(ns_returns_not_retained)");
5412 case CXCursor_NSReturnsAutoreleased:
5413 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5414 case CXCursor_NSConsumesSelf:
5415 return cxstring::createRef("attribute(ns_consumes_self)");
5416 case CXCursor_NSConsumed:
5417 return cxstring::createRef("attribute(ns_consumed)");
5418 case CXCursor_ObjCException:
5419 return cxstring::createRef("attribute(objc_exception)");
5420 case CXCursor_ObjCNSObject:
5421 return cxstring::createRef("attribute(NSObject)");
5422 case CXCursor_ObjCIndependentClass:
5423 return cxstring::createRef("attribute(objc_independent_class)");
5424 case CXCursor_ObjCPreciseLifetime:
5425 return cxstring::createRef("attribute(objc_precise_lifetime)");
5426 case CXCursor_ObjCReturnsInnerPointer:
5427 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5428 case CXCursor_ObjCRequiresSuper:
5429 return cxstring::createRef("attribute(objc_requires_super)");
5430 case CXCursor_ObjCRootClass:
5431 return cxstring::createRef("attribute(objc_root_class)");
5432 case CXCursor_ObjCSubclassingRestricted:
5433 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5434 case CXCursor_ObjCExplicitProtocolImpl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005435 return cxstring::createRef(
5436 "attribute(objc_protocol_requires_explicit_implementation)");
Michael Wud092d0b2018-08-03 05:03:22 +00005437 case CXCursor_ObjCDesignatedInitializer:
5438 return cxstring::createRef("attribute(objc_designated_initializer)");
5439 case CXCursor_ObjCRuntimeVisible:
5440 return cxstring::createRef("attribute(objc_runtime_visible)");
5441 case CXCursor_ObjCBoxable:
5442 return cxstring::createRef("attribute(objc_boxable)");
Michael Wu58d837d2018-08-03 05:55:40 +00005443 case CXCursor_FlagEnum:
5444 return cxstring::createRef("attribute(flag_enum)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005446 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005448 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005450 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005452 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005454 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005456 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005458 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005460 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005462 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005464 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005466 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005468 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005470 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005472 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005474 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005476 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005478 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005480 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005482 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005484 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005486 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005488 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005490 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005492 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005493 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00005494 return cxstring::createRef("OMPParallelDirective");
5495 case CXCursor_OMPSimdDirective:
5496 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00005497 case CXCursor_OMPForDirective:
5498 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00005499 case CXCursor_OMPForSimdDirective:
5500 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00005501 case CXCursor_OMPSectionsDirective:
5502 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00005503 case CXCursor_OMPSectionDirective:
5504 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00005505 case CXCursor_OMPSingleDirective:
5506 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00005507 case CXCursor_OMPMasterDirective:
5508 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00005509 case CXCursor_OMPCriticalDirective:
5510 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00005511 case CXCursor_OMPParallelForDirective:
5512 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00005513 case CXCursor_OMPParallelForSimdDirective:
5514 return cxstring::createRef("OMPParallelForSimdDirective");
cchen47d60942019-12-05 13:43:48 -05005515 case CXCursor_OMPParallelMasterDirective:
5516 return cxstring::createRef("OMPParallelMasterDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00005517 case CXCursor_OMPParallelSectionsDirective:
5518 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00005519 case CXCursor_OMPTaskDirective:
5520 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00005521 case CXCursor_OMPTaskyieldDirective:
5522 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00005523 case CXCursor_OMPBarrierDirective:
5524 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00005525 case CXCursor_OMPTaskwaitDirective:
5526 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00005527 case CXCursor_OMPTaskgroupDirective:
5528 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00005529 case CXCursor_OMPFlushDirective:
5530 return cxstring::createRef("OMPFlushDirective");
Alexey Bataevc112e942020-02-28 09:52:15 -05005531 case CXCursor_OMPDepobjDirective:
5532 return cxstring::createRef("OMPDepobjDirective");
Alexey Bataevfcba7c32020-03-20 07:03:01 -04005533 case CXCursor_OMPScanDirective:
5534 return cxstring::createRef("OMPScanDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00005535 case CXCursor_OMPOrderedDirective:
5536 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00005537 case CXCursor_OMPAtomicDirective:
5538 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00005539 case CXCursor_OMPTargetDirective:
5540 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00005541 case CXCursor_OMPTargetDataDirective:
5542 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00005543 case CXCursor_OMPTargetEnterDataDirective:
5544 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00005545 case CXCursor_OMPTargetExitDataDirective:
5546 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00005547 case CXCursor_OMPTargetParallelDirective:
5548 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00005549 case CXCursor_OMPTargetParallelForDirective:
5550 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00005551 case CXCursor_OMPTargetUpdateDirective:
5552 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00005553 case CXCursor_OMPTeamsDirective:
5554 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00005555 case CXCursor_OMPCancellationPointDirective:
5556 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00005557 case CXCursor_OMPCancelDirective:
5558 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00005559 case CXCursor_OMPTaskLoopDirective:
5560 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005561 case CXCursor_OMPTaskLoopSimdDirective:
5562 return cxstring::createRef("OMPTaskLoopSimdDirective");
Alexey Bataev60e51c42019-10-10 20:13:02 +00005563 case CXCursor_OMPMasterTaskLoopDirective:
5564 return cxstring::createRef("OMPMasterTaskLoopDirective");
Alexey Bataevb8552ab2019-10-18 16:47:35 +00005565 case CXCursor_OMPMasterTaskLoopSimdDirective:
5566 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
Alexey Bataev5bbcead2019-10-14 17:17:41 +00005567 case CXCursor_OMPParallelMasterTaskLoopDirective:
5568 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
Alexey Bataev14a388f2019-10-25 10:27:13 -04005569 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5570 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00005571 case CXCursor_OMPDistributeDirective:
5572 return cxstring::createRef("OMPDistributeDirective");
Carlo Bertolli9925f152016-06-27 14:55:37 +00005573 case CXCursor_OMPDistributeParallelForDirective:
5574 return cxstring::createRef("OMPDistributeParallelForDirective");
Kelvin Li4a39add2016-07-05 05:00:15 +00005575 case CXCursor_OMPDistributeParallelForSimdDirective:
5576 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
Kelvin Li787f3fc2016-07-06 04:45:38 +00005577 case CXCursor_OMPDistributeSimdDirective:
5578 return cxstring::createRef("OMPDistributeSimdDirective");
Kelvin Lia579b912016-07-14 02:54:56 +00005579 case CXCursor_OMPTargetParallelForSimdDirective:
5580 return cxstring::createRef("OMPTargetParallelForSimdDirective");
Kelvin Li986330c2016-07-20 22:57:10 +00005581 case CXCursor_OMPTargetSimdDirective:
5582 return cxstring::createRef("OMPTargetSimdDirective");
Kelvin Li02532872016-08-05 14:37:37 +00005583 case CXCursor_OMPTeamsDistributeDirective:
5584 return cxstring::createRef("OMPTeamsDistributeDirective");
Kelvin Li4e325f72016-10-25 12:50:55 +00005585 case CXCursor_OMPTeamsDistributeSimdDirective:
5586 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
Kelvin Li579e41c2016-11-30 23:51:03 +00005587 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5588 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
Kelvin Li7ade93f2016-12-09 03:24:30 +00005589 case CXCursor_OMPTeamsDistributeParallelForDirective:
5590 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
Kelvin Libf594a52016-12-17 05:48:59 +00005591 case CXCursor_OMPTargetTeamsDirective:
5592 return cxstring::createRef("OMPTargetTeamsDirective");
Kelvin Li83c451e2016-12-25 04:52:54 +00005593 case CXCursor_OMPTargetTeamsDistributeDirective:
5594 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
Kelvin Li80e8f562016-12-29 22:16:30 +00005595 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5596 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
Kelvin Li1851df52017-01-03 05:23:48 +00005597 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5598 return cxstring::createRef(
5599 "OMPTargetTeamsDistributeParallelForSimdDirective");
Kelvin Lida681182017-01-10 18:08:18 +00005600 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5601 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00005602 case CXCursor_OverloadCandidate:
Michael Kruse7520cf02020-03-25 09:26:14 -05005603 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00005604 case CXCursor_TypeAliasTemplateDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005605 return cxstring::createRef("TypeAliasTemplateDecl");
Olivier Goffart81978012016-06-09 16:15:55 +00005606 case CXCursor_StaticAssert:
Michael Kruse7520cf02020-03-25 09:26:14 -05005607 return cxstring::createRef("StaticAssert");
Olivier Goffartd211c642016-11-04 06:29:27 +00005608 case CXCursor_FriendDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005609 return cxstring::createRef("FriendDecl");
Sven van Haastregtdc2c9302019-02-11 11:00:56 +00005610 case CXCursor_ConvergentAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005611 return cxstring::createRef("attribute(convergent)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005612 case CXCursor_WarnUnusedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005613 return cxstring::createRef("attribute(warn_unused)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005614 case CXCursor_WarnUnusedResultAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005615 return cxstring::createRef("attribute(warn_unused_result)");
Emilio Cobos Alvarezcd741272019-03-13 16:16:54 +00005616 case CXCursor_AlignedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005617 return cxstring::createRef("attribute(aligned)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005618 }
5619
5620 llvm_unreachable("Unhandled CXCursorKind");
5621}
5622
5623struct GetCursorData {
5624 SourceLocation TokenBeginLoc;
5625 bool PointsAtMacroArgExpansion;
5626 bool VisitedObjCPropertyImplDecl;
5627 SourceLocation VisitedDeclaratorDeclStartLoc;
5628 CXCursor &BestCursor;
5629
Michael Kruse7520cf02020-03-25 09:26:14 -05005630 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5631 CXCursor &outputCursor)
5632 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5634 VisitedObjCPropertyImplDecl = false;
5635 }
5636};
5637
Michael Kruse7520cf02020-03-25 09:26:14 -05005638static enum CXChildVisitResult
5639GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5641 CXCursor *BestCursor = &Data->BestCursor;
5642
5643 // If we point inside a macro argument we should provide info of what the
5644 // token is so use the actual cursor, don't replace it with a macro expansion
5645 // cursor.
5646 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5647 return CXChildVisit_Recurse;
Michael Kruse7520cf02020-03-25 09:26:14 -05005648
Guy Benyei11169dd2012-12-18 14:30:41 +00005649 if (clang_isDeclaration(cursor.kind)) {
5650 // Avoid having the implicit methods override the property decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05005651 if (const ObjCMethodDecl *MD =
5652 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 if (MD->isImplicit())
5654 return CXChildVisit_Break;
5655
Michael Kruse7520cf02020-03-25 09:26:14 -05005656 } else if (const ObjCInterfaceDecl *ID =
5657 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005658 // Check that when we have multiple @class references in the same line,
5659 // that later ones do not override the previous ones.
5660 // If we have:
5661 // @class Foo, Bar;
5662 // source ranges for both start at '@', so 'Bar' will end up overriding
5663 // 'Foo' even though the cursor location was at 'Foo'.
5664 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5665 BestCursor->kind == CXCursor_ObjCClassRef)
Michael Kruse7520cf02020-03-25 09:26:14 -05005666 if (const ObjCInterfaceDecl *PrevID =
5667 dyn_cast_or_null<ObjCInterfaceDecl>(
5668 getCursorDecl(*BestCursor))) {
5669 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5670 !ID->isThisDeclarationADefinition())
5671 return CXChildVisit_Break;
Guy Benyei11169dd2012-12-18 14:30:41 +00005672 }
5673
Michael Kruse7520cf02020-03-25 09:26:14 -05005674 } else if (const DeclaratorDecl *DD =
5675 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5677 // Check that when we have multiple declarators in the same line,
5678 // that later ones do not override the previous ones.
5679 // If we have:
5680 // int Foo, Bar;
5681 // source ranges for both start at 'int', so 'Bar' will end up overriding
5682 // 'Foo' even though the cursor location was at 'Foo'.
5683 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5684 return CXChildVisit_Break;
5685 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5686
Michael Kruse7520cf02020-03-25 09:26:14 -05005687 } else if (const ObjCPropertyImplDecl *PropImp =
5688 dyn_cast_or_null<ObjCPropertyImplDecl>(
5689 getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 (void)PropImp;
5691 // Check that when we have multiple @synthesize in the same line,
5692 // that later ones do not override the previous ones.
5693 // If we have:
5694 // @synthesize Foo, Bar;
5695 // source ranges for both start at '@', so 'Bar' will end up overriding
5696 // 'Foo' even though the cursor location was at 'Foo'.
5697 if (Data->VisitedObjCPropertyImplDecl)
5698 return CXChildVisit_Break;
5699 Data->VisitedObjCPropertyImplDecl = true;
5700 }
5701 }
5702
5703 if (clang_isExpression(cursor.kind) &&
5704 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005705 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005706 // Avoid having the cursor of an expression replace the declaration cursor
5707 // when the expression source range overlaps the declaration range.
5708 // This can happen for C++ constructor expressions whose range generally
5709 // include the variable declaration, e.g.:
Michael Kruse7520cf02020-03-25 09:26:14 -05005710 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5711 // cursor.
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5713 D->getLocation() == Data->TokenBeginLoc)
5714 return CXChildVisit_Break;
5715 }
5716 }
5717
Michael Kruse7520cf02020-03-25 09:26:14 -05005718 // If our current best cursor is the construction of a temporary object,
5719 // don't replace that cursor with a type reference, because we want
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 // clang_getCursor() to point at the constructor.
5721 if (clang_isExpression(BestCursor->kind) &&
5722 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5723 cursor.kind == CXCursor_TypeRef) {
5724 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5725 // as having the actual point on the type reference.
5726 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5727 return CXChildVisit_Recurse;
5728 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005729
5730 // If we already have an Objective-C superclass reference, don't
5731 // update it further.
5732 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5733 return CXChildVisit_Break;
5734
Guy Benyei11169dd2012-12-18 14:30:41 +00005735 *BestCursor = cursor;
5736 return CXChildVisit_Recurse;
5737}
5738
5739CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005740 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005741 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005743 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005744
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005745 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5747
5748 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5749 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5750
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005751 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 CXFile SearchFile;
5753 unsigned SearchLine, SearchColumn;
5754 CXFile ResultFile;
5755 unsigned ResultLine, ResultColumn;
5756 CXString SearchFileName, ResultFileName, KindSpelling, USR;
Michael Kruse7520cf02020-03-25 09:26:14 -05005757 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005759
5760 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5761 nullptr);
Michael Kruse7520cf02020-03-25 09:26:14 -05005762 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5763 nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 SearchFileName = clang_getFileName(SearchFile);
5765 ResultFileName = clang_getFileName(ResultFile);
5766 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5767 USR = clang_getCursorUSR(Result);
Michael Kruse7520cf02020-03-25 09:26:14 -05005768 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5769 SearchLine, SearchColumn,
5770 clang_getCString(KindSpelling))
5771 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5772 ResultLine, ResultColumn, clang_getCString(USR),
5773 IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 clang_disposeString(SearchFileName);
5775 clang_disposeString(ResultFileName);
5776 clang_disposeString(KindSpelling);
5777 clang_disposeString(USR);
Michael Kruse7520cf02020-03-25 09:26:14 -05005778
Guy Benyei11169dd2012-12-18 14:30:41 +00005779 CXCursor Definition = clang_getCursorDefinition(Result);
5780 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5781 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
Michael Kruse7520cf02020-03-25 09:26:14 -05005782 CXString DefinitionKindSpelling =
5783 clang_getCursorKindSpelling(Definition.kind);
Guy Benyei11169dd2012-12-18 14:30:41 +00005784 CXFile DefinitionFile;
5785 unsigned DefinitionLine, DefinitionColumn;
Michael Kruse7520cf02020-03-25 09:26:14 -05005786 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5787 &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005788 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005789 *Log << llvm::format(" -> %s(%s:%d:%d)",
Michael Kruse7520cf02020-03-25 09:26:14 -05005790 clang_getCString(DefinitionKindSpelling),
5791 clang_getCString(DefinitionFileName), DefinitionLine,
5792 DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005793 clang_disposeString(DefinitionFileName);
5794 clang_disposeString(DefinitionKindSpelling);
5795 }
5796 }
5797
5798 return Result;
5799}
5800
5801CXCursor clang_getNullCursor(void) {
5802 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5803}
5804
5805unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005806 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5807 // can't set consistently. For example, when visiting a DeclStmt we will set
5808 // it but we don't set it on the result of clang_getCursorDefinition for
5809 // a reference of the same declaration.
5810 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5811 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5812 // to provide that kind of info.
5813 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005814 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005815 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005816 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005817
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 return X == Y;
5819}
5820
5821unsigned clang_hashCursor(CXCursor C) {
5822 unsigned Index = 0;
5823 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5824 Index = 1;
Michael Kruse7520cf02020-03-25 09:26:14 -05005825
5826 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5827 std::make_pair(C.kind, C.data[Index]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005828}
5829
5830unsigned clang_isInvalid(enum CXCursorKind K) {
5831 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5832}
5833
5834unsigned clang_isDeclaration(enum CXCursorKind K) {
5835 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005836 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5837}
5838
Ivan Donchevskii08ff9102018-01-04 10:59:50 +00005839unsigned clang_isInvalidDeclaration(CXCursor C) {
5840 if (clang_isDeclaration(C.kind)) {
5841 if (const Decl *D = getCursorDecl(C))
5842 return D->isInvalidDecl();
5843 }
5844
5845 return 0;
5846}
5847
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005848unsigned clang_isReference(enum CXCursorKind K) {
5849 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5850}
Guy Benyei11169dd2012-12-18 14:30:41 +00005851
5852unsigned clang_isExpression(enum CXCursorKind K) {
5853 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5854}
5855
5856unsigned clang_isStatement(enum CXCursorKind K) {
5857 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5858}
5859
5860unsigned clang_isAttribute(enum CXCursorKind K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005861 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005862}
5863
5864unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5865 return K == CXCursor_TranslationUnit;
5866}
5867
5868unsigned clang_isPreprocessing(enum CXCursorKind K) {
5869 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5870}
Michael Kruse7520cf02020-03-25 09:26:14 -05005871
Guy Benyei11169dd2012-12-18 14:30:41 +00005872unsigned clang_isUnexposed(enum CXCursorKind K) {
5873 switch (K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005874 case CXCursor_UnexposedDecl:
5875 case CXCursor_UnexposedExpr:
5876 case CXCursor_UnexposedStmt:
5877 case CXCursor_UnexposedAttr:
5878 return true;
5879 default:
5880 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005881 }
5882}
5883
Michael Kruse7520cf02020-03-25 09:26:14 -05005884CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005885
5886CXSourceLocation clang_getCursorLocation(CXCursor C) {
5887 if (clang_isReference(C.kind)) {
5888 switch (C.kind) {
5889 case CXCursor_ObjCSuperClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005890 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5891 getCursorObjCSuperClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005892 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5893 }
5894
5895 case CXCursor_ObjCProtocolRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005896 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5897 getCursorObjCProtocolRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5899 }
5900
5901 case CXCursor_ObjCClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005902 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5903 getCursorObjCClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005904 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5905 }
5906
5907 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005908 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005909 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5910 }
5911
5912 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005913 std::pair<const TemplateDecl *, SourceLocation> P =
5914 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5916 }
5917
5918 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005919 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005920 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5921 }
5922
5923 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005924 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005925 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5926 }
5927
5928 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005929 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005930 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5931 }
5932
5933 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005934 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005935 if (!BaseSpec)
5936 return clang_getNullLocation();
Michael Kruse7520cf02020-03-25 09:26:14 -05005937
Guy Benyei11169dd2012-12-18 14:30:41 +00005938 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
Michael Kruse7520cf02020-03-25 09:26:14 -05005939 return cxloc::translateSourceLocation(
5940 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005941
Guy Benyei11169dd2012-12-18 14:30:41 +00005942 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005943 BaseSpec->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005944 }
5945
5946 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005947 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005948 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5949 }
5950
5951 case CXCursor_OverloadedDeclRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005952 return cxloc::translateSourceLocation(
5953 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
Guy Benyei11169dd2012-12-18 14:30:41 +00005954
5955 default:
5956 // FIXME: Need a way to enumerate all non-reference cases.
5957 llvm_unreachable("Missed a reference kind");
5958 }
5959 }
5960
5961 if (clang_isExpression(C.kind))
Michael Kruse7520cf02020-03-25 09:26:14 -05005962 return cxloc::translateSourceLocation(
5963 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
Guy Benyei11169dd2012-12-18 14:30:41 +00005964
5965 if (clang_isStatement(C.kind))
5966 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005967 getCursorStmt(C)->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005968
5969 if (C.kind == CXCursor_PreprocessingDirective) {
5970 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5971 return cxloc::translateSourceLocation(getCursorContext(C), L);
5972 }
5973
5974 if (C.kind == CXCursor_MacroExpansion) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005975 SourceLocation L =
5976 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005977 return cxloc::translateSourceLocation(getCursorContext(C), L);
5978 }
5979
5980 if (C.kind == CXCursor_MacroDefinition) {
5981 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5982 return cxloc::translateSourceLocation(getCursorContext(C), L);
5983 }
5984
5985 if (C.kind == CXCursor_InclusionDirective) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005986 SourceLocation L =
5987 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005988 return cxloc::translateSourceLocation(getCursorContext(C), L);
5989 }
5990
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005991 if (clang_isAttribute(C.kind)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005992 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005993 return cxloc::translateSourceLocation(getCursorContext(C), L);
5994 }
5995
Guy Benyei11169dd2012-12-18 14:30:41 +00005996 if (!clang_isDeclaration(C.kind))
5997 return clang_getNullLocation();
5998
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005999 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006000 if (!D)
6001 return clang_getNullLocation();
6002
6003 SourceLocation Loc = D->getLocation();
6004 // FIXME: Multiple variables declared in a single declaration
6005 // currently lack the information needed to correctly determine their
6006 // ranges when accounting for the type-specifier. We use context
6007 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6008 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006009 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006010 if (!cxcursor::isFirstInDeclGroup(C))
6011 Loc = VD->getLocation();
6012 }
6013
6014 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006015 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 Loc = MD->getSelectorStartLoc();
6017
6018 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
6019}
6020
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00006021} // end extern "C"
6022
Guy Benyei11169dd2012-12-18 14:30:41 +00006023CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6024 assert(TU);
6025
6026 // Guard against an invalid SourceLocation, or we may assert in one
6027 // of the following calls.
6028 if (SLoc.isInvalid())
6029 return clang_getNullCursor();
6030
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006031 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006032
6033 // Translate the given source location to make it point at the beginning of
6034 // the token under the cursor.
6035 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6036 CXXUnit->getASTContext().getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05006037
Guy Benyei11169dd2012-12-18 14:30:41 +00006038 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6039 if (SLoc.isValid()) {
6040 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6041 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Michael Kruse7520cf02020-03-25 09:26:14 -05006042 /*VisitPreprocessorLast=*/true,
Guy Benyei11169dd2012-12-18 14:30:41 +00006043 /*VisitIncludedEntities=*/false,
6044 SourceLocation(SLoc));
6045 CursorVis.visitFileRegion();
6046 }
6047
6048 return Result;
6049}
6050
6051static SourceRange getRawCursorExtent(CXCursor C) {
6052 if (clang_isReference(C.kind)) {
6053 switch (C.kind) {
6054 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05006055 return getCursorObjCSuperClassRef(C).second;
Guy Benyei11169dd2012-12-18 14:30:41 +00006056
6057 case CXCursor_ObjCProtocolRef:
6058 return getCursorObjCProtocolRef(C).second;
6059
6060 case CXCursor_ObjCClassRef:
6061 return getCursorObjCClassRef(C).second;
6062
6063 case CXCursor_TypeRef:
6064 return getCursorTypeRef(C).second;
6065
6066 case CXCursor_TemplateRef:
6067 return getCursorTemplateRef(C).second;
6068
6069 case CXCursor_NamespaceRef:
6070 return getCursorNamespaceRef(C).second;
6071
6072 case CXCursor_MemberRef:
6073 return getCursorMemberRef(C).second;
6074
6075 case CXCursor_CXXBaseSpecifier:
6076 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6077
6078 case CXCursor_LabelRef:
6079 return getCursorLabelRef(C).second;
6080
6081 case CXCursor_OverloadedDeclRef:
6082 return getCursorOverloadedDeclRef(C).second;
6083
6084 case CXCursor_VariableRef:
6085 return getCursorVariableRef(C).second;
Michael Kruse7520cf02020-03-25 09:26:14 -05006086
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 default:
6088 // FIXME: Need a way to enumerate all non-reference cases.
6089 llvm_unreachable("Missed a reference kind");
6090 }
6091 }
6092
6093 if (clang_isExpression(C.kind))
6094 return getCursorExpr(C)->getSourceRange();
6095
6096 if (clang_isStatement(C.kind))
6097 return getCursorStmt(C)->getSourceRange();
6098
6099 if (clang_isAttribute(C.kind))
6100 return getCursorAttr(C)->getRange();
6101
6102 if (C.kind == CXCursor_PreprocessingDirective)
6103 return cxcursor::getCursorPreprocessingDirective(C);
6104
6105 if (C.kind == CXCursor_MacroExpansion) {
6106 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006107 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006108 return TU->mapRangeFromPreamble(Range);
6109 }
6110
6111 if (C.kind == CXCursor_MacroDefinition) {
6112 ASTUnit *TU = getCursorASTUnit(C);
6113 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6114 return TU->mapRangeFromPreamble(Range);
6115 }
6116
6117 if (C.kind == CXCursor_InclusionDirective) {
6118 ASTUnit *TU = getCursorASTUnit(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05006119 SourceRange Range =
6120 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 return TU->mapRangeFromPreamble(Range);
6122 }
6123
6124 if (C.kind == CXCursor_TranslationUnit) {
6125 ASTUnit *TU = getCursorASTUnit(C);
6126 FileID MainID = TU->getSourceManager().getMainFileID();
6127 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6128 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6129 return SourceRange(Start, End);
6130 }
6131
6132 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006133 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006134 if (!D)
6135 return SourceRange();
6136
6137 SourceRange R = D->getSourceRange();
6138 // FIXME: Multiple variables declared in a single declaration
6139 // currently lack the information needed to correctly determine their
6140 // ranges when accounting for the type-specifier. We use context
6141 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6142 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006143 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006144 if (!cxcursor::isFirstInDeclGroup(C))
6145 R.setBegin(VD->getLocation());
6146 }
6147 return R;
6148 }
6149 return SourceRange();
6150}
6151
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006152/// Retrieves the "raw" cursor extent, which is then extended to include
Guy Benyei11169dd2012-12-18 14:30:41 +00006153/// the decl-specifier-seq for declarations.
6154static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6155 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006156 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 if (!D)
6158 return SourceRange();
6159
6160 SourceRange R = D->getSourceRange();
6161
6162 // Adjust the start of the location for declarations preceded by
6163 // declaration specifiers.
6164 SourceLocation StartLoc;
6165 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6166 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006167 StartLoc = TI->getTypeLoc().getBeginLoc();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006168 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006169 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006170 StartLoc = TI->getTypeLoc().getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00006171 }
6172
6173 if (StartLoc.isValid() && R.getBegin().isValid() &&
6174 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6175 R.setBegin(StartLoc);
6176
6177 // FIXME: Multiple variables declared in a single declaration
6178 // currently lack the information needed to correctly determine their
6179 // ranges when accounting for the type-specifier. We use context
6180 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6181 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006182 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006183 if (!cxcursor::isFirstInDeclGroup(C))
6184 R.setBegin(VD->getLocation());
6185 }
6186
Michael Kruse7520cf02020-03-25 09:26:14 -05006187 return R;
Guy Benyei11169dd2012-12-18 14:30:41 +00006188 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006189
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 return getRawCursorExtent(C);
6191}
6192
Guy Benyei11169dd2012-12-18 14:30:41 +00006193CXSourceRange clang_getCursorExtent(CXCursor C) {
6194 SourceRange R = getRawCursorExtent(C);
6195 if (R.isInvalid())
6196 return clang_getNullRange();
6197
6198 return cxloc::translateSourceRange(getCursorContext(C), R);
6199}
6200
6201CXCursor clang_getCursorReferenced(CXCursor C) {
6202 if (clang_isInvalid(C.kind))
6203 return clang_getNullCursor();
6204
6205 CXTranslationUnit tu = getCursorTU(C);
6206 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006207 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006208 if (!D)
6209 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006210 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006211 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006212 if (const ObjCPropertyImplDecl *PropImpl =
6213 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006214 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6215 return MakeCXCursor(Property, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006216
Guy Benyei11169dd2012-12-18 14:30:41 +00006217 return C;
6218 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006219
Guy Benyei11169dd2012-12-18 14:30:41 +00006220 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006221 const Expr *E = getCursorExpr(C);
6222 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00006223 if (D) {
6224 CXCursor declCursor = MakeCXCursor(D, tu);
6225 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6226 declCursor);
6227 return declCursor;
6228 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006229
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006230 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 return MakeCursorOverloadedDeclRef(Ovl, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006232
Guy Benyei11169dd2012-12-18 14:30:41 +00006233 return clang_getNullCursor();
6234 }
6235
6236 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006237 const Stmt *S = getCursorStmt(C);
6238 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00006239 if (LabelDecl *label = Goto->getLabel())
6240 if (LabelStmt *labelS = label->getStmt())
Michael Kruse7520cf02020-03-25 09:26:14 -05006241 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006242
6243 return clang_getNullCursor();
6244 }
Richard Smith66a81862015-05-04 02:25:31 +00006245
Guy Benyei11169dd2012-12-18 14:30:41 +00006246 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00006247 if (const MacroDefinitionRecord *Def =
6248 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006249 return MakeMacroDefinitionCursor(Def, tu);
6250 }
6251
6252 if (!clang_isReference(C.kind))
6253 return clang_getNullCursor();
6254
6255 switch (C.kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006256 case CXCursor_ObjCSuperClassRef:
6257 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006258
Michael Kruse7520cf02020-03-25 09:26:14 -05006259 case CXCursor_ObjCProtocolRef: {
6260 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6261 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6262 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006263
Michael Kruse7520cf02020-03-25 09:26:14 -05006264 return MakeCXCursor(Prot, tu);
6265 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006266
Michael Kruse7520cf02020-03-25 09:26:14 -05006267 case CXCursor_ObjCClassRef: {
6268 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6269 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6270 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006271
Michael Kruse7520cf02020-03-25 09:26:14 -05006272 return MakeCXCursor(Class, tu);
6273 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006274
Michael Kruse7520cf02020-03-25 09:26:14 -05006275 case CXCursor_TypeRef:
6276 return MakeCXCursor(getCursorTypeRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006277
Michael Kruse7520cf02020-03-25 09:26:14 -05006278 case CXCursor_TemplateRef:
6279 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006280
Michael Kruse7520cf02020-03-25 09:26:14 -05006281 case CXCursor_NamespaceRef:
6282 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006283
Michael Kruse7520cf02020-03-25 09:26:14 -05006284 case CXCursor_MemberRef:
6285 return MakeCXCursor(getCursorMemberRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006286
Michael Kruse7520cf02020-03-25 09:26:14 -05006287 case CXCursor_CXXBaseSpecifier: {
6288 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6289 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6290 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006291
Michael Kruse7520cf02020-03-25 09:26:14 -05006292 case CXCursor_LabelRef:
6293 // FIXME: We end up faking the "parent" declaration here because we
6294 // don't want to make CXCursor larger.
6295 return MakeCXCursor(
6296 getCursorLabelRef(C).first,
6297 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006298
Michael Kruse7520cf02020-03-25 09:26:14 -05006299 case CXCursor_OverloadedDeclRef:
6300 return C;
Guy Benyei11169dd2012-12-18 14:30:41 +00006301
Michael Kruse7520cf02020-03-25 09:26:14 -05006302 case CXCursor_VariableRef:
6303 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6304
6305 default:
6306 // We would prefer to enumerate all non-reference cursor kinds here.
6307 llvm_unreachable("Unhandled reference cursor kind");
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 }
6309}
6310
6311CXCursor clang_getCursorDefinition(CXCursor C) {
6312 if (clang_isInvalid(C.kind))
6313 return clang_getNullCursor();
6314
6315 CXTranslationUnit TU = getCursorTU(C);
6316
6317 bool WasReference = false;
6318 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6319 C = clang_getCursorReferenced(C);
6320 WasReference = true;
6321 }
6322
6323 if (C.kind == CXCursor_MacroExpansion)
6324 return clang_getCursorReferenced(C);
6325
6326 if (!clang_isDeclaration(C.kind))
6327 return clang_getNullCursor();
6328
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006329 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006330 if (!D)
6331 return clang_getNullCursor();
6332
6333 switch (D->getKind()) {
6334 // Declaration kinds that don't really separate the notions of
6335 // declaration and definition.
6336 case Decl::Namespace:
6337 case Decl::Typedef:
6338 case Decl::TypeAlias:
6339 case Decl::TypeAliasTemplate:
6340 case Decl::TemplateTypeParm:
6341 case Decl::EnumConstant:
6342 case Decl::Field:
Richard Smithbdb84f32016-07-22 23:36:59 +00006343 case Decl::Binding:
John McCall5e77d762013-04-16 07:28:30 +00006344 case Decl::MSProperty:
Richard Smithbab6df82020-04-11 22:15:29 -07006345 case Decl::MSGuid:
Guy Benyei11169dd2012-12-18 14:30:41 +00006346 case Decl::IndirectField:
6347 case Decl::ObjCIvar:
6348 case Decl::ObjCAtDefsField:
6349 case Decl::ImplicitParam:
6350 case Decl::ParmVar:
6351 case Decl::NonTypeTemplateParm:
6352 case Decl::TemplateTemplateParm:
6353 case Decl::ObjCCategoryImpl:
6354 case Decl::ObjCImplementation:
6355 case Decl::AccessSpec:
6356 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006357 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006358 case Decl::ObjCPropertyImpl:
6359 case Decl::FileScopeAsm:
6360 case Decl::StaticAssert:
6361 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006362 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006363 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006364 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006366 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006367 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006368 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006369 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006370 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006371 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006372 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006373 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006374 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006375 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006376 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006377 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006378 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006379 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006380 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006381 return C;
6382
6383 // Declaration kinds that don't make any sense here, but are
6384 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006385 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006386 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006387 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006388 break;
6389
6390 // Declaration kinds for which the definition is not resolvable.
6391 case Decl::UnresolvedUsingTypename:
6392 case Decl::UnresolvedUsingValue:
6393 break;
6394
6395 case Decl::UsingDirective:
6396 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6397 TU);
6398
6399 case Decl::NamespaceAlias:
6400 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6401
6402 case Decl::Enum:
6403 case Decl::Record:
6404 case Decl::CXXRecord:
6405 case Decl::ClassTemplateSpecialization:
6406 case Decl::ClassTemplatePartialSpecialization:
6407 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6408 return MakeCXCursor(Def, TU);
6409 return clang_getNullCursor();
6410
6411 case Decl::Function:
6412 case Decl::CXXMethod:
6413 case Decl::CXXConstructor:
6414 case Decl::CXXDestructor:
6415 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006416 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006417 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006418 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006419 return clang_getNullCursor();
6420 }
6421
Larisse Voufo39a1e502013-08-06 01:03:05 +00006422 case Decl::Var:
6423 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006424 case Decl::VarTemplatePartialSpecialization:
6425 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006426 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006427 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006428 return MakeCXCursor(Def, TU);
6429 return clang_getNullCursor();
6430 }
6431
6432 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006433 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006434 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6435 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6436 return clang_getNullCursor();
6437 }
6438
6439 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006440 if (RecordDecl *Def =
6441 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006442 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6443 TU);
6444 return clang_getNullCursor();
6445 }
6446
Larisse Voufo39a1e502013-08-06 01:03:05 +00006447 case Decl::VarTemplate: {
6448 if (VarDecl *Def =
6449 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6450 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6451 return clang_getNullCursor();
6452 }
6453
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006455 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6456 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006457
6458 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006459 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006460 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006461 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006462
6463 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006464 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006465 if (Method->isThisDeclarationADefinition())
6466 return C;
6467
6468 // Dig out the method definition in the associated
6469 // @implementation, if we have it.
6470 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006471 if (const ObjCInterfaceDecl *Class =
6472 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006473 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006474 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6475 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006476 if (Def->isThisDeclarationADefinition())
6477 return MakeCXCursor(Def, TU);
6478
6479 return clang_getNullCursor();
6480 }
6481
6482 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006483 if (ObjCCategoryImplDecl *Impl =
6484 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006485 return MakeCXCursor(Impl, TU);
6486 return clang_getNullCursor();
6487
6488 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006489 if (const ObjCProtocolDecl *Def =
6490 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006491 return MakeCXCursor(Def, TU);
6492 return clang_getNullCursor();
6493
6494 case Decl::ObjCInterface: {
6495 // There are two notions of a "definition" for an Objective-C
6496 // class: the interface and its implementation. When we resolved a
6497 // reference to an Objective-C class, produce the @interface as
6498 // the definition; when we were provided with the interface,
6499 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006500 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006501 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006502 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006503 return MakeCXCursor(Def, TU);
6504 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6505 return MakeCXCursor(Impl, TU);
6506 return clang_getNullCursor();
6507 }
6508
6509 case Decl::ObjCProperty:
6510 // FIXME: We don't really know where to find the
6511 // ObjCPropertyImplDecls that implement this property.
6512 return clang_getNullCursor();
6513
6514 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006515 if (const ObjCInterfaceDecl *Class =
6516 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006517 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006518 return MakeCXCursor(Def, TU);
6519
6520 return clang_getNullCursor();
6521
6522 case Decl::Friend:
6523 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6524 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6525 return clang_getNullCursor();
6526
6527 case Decl::FriendTemplate:
6528 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6529 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6530 return clang_getNullCursor();
6531 }
6532
6533 return clang_getNullCursor();
6534}
6535
6536unsigned clang_isCursorDefinition(CXCursor C) {
6537 if (!clang_isDeclaration(C.kind))
6538 return 0;
6539
6540 return clang_getCursorDefinition(C) == C;
6541}
6542
6543CXCursor clang_getCanonicalCursor(CXCursor C) {
6544 if (!clang_isDeclaration(C.kind))
6545 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006546
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006547 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006548 if (const ObjCCategoryImplDecl *CatImplD =
6549 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006550 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6551 return MakeCXCursor(CatD, getCursorTU(C));
6552
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006553 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6554 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006555 return MakeCXCursor(IFD, getCursorTU(C));
6556
6557 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6558 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006559
Guy Benyei11169dd2012-12-18 14:30:41 +00006560 return C;
6561}
6562
6563int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6564 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6565}
Michael Kruse7520cf02020-03-25 09:26:14 -05006566
Guy Benyei11169dd2012-12-18 14:30:41 +00006567unsigned clang_getNumOverloadedDecls(CXCursor C) {
6568 if (C.kind != CXCursor_OverloadedDeclRef)
6569 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006570
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006572 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006573 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006574
6575 if (OverloadedTemplateStorage *S =
6576 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006577 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006578
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006579 const Decl *D = Storage.get<const Decl *>();
6580 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006581 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006582
Guy Benyei11169dd2012-12-18 14:30:41 +00006583 return 0;
6584}
6585
6586CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6587 if (cursor.kind != CXCursor_OverloadedDeclRef)
6588 return clang_getNullCursor();
6589
6590 if (index >= clang_getNumOverloadedDecls(cursor))
6591 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006592
Guy Benyei11169dd2012-12-18 14:30:41 +00006593 CXTranslationUnit TU = getCursorTU(cursor);
6594 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006595 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006596 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006597
6598 if (OverloadedTemplateStorage *S =
6599 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006600 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006601
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006602 const Decl *D = Storage.get<const Decl *>();
6603 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006604 // FIXME: This is, unfortunately, linear time.
6605 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6606 std::advance(Pos, index);
6607 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6608 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006609
Guy Benyei11169dd2012-12-18 14:30:41 +00006610 return clang_getNullCursor();
6611}
Michael Kruse7520cf02020-03-25 09:26:14 -05006612
6613void clang_getDefinitionSpellingAndExtent(
6614 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6615 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006616 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006617 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006618 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6619
6620 SourceManager &SM = FD->getASTContext().getSourceManager();
6621 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6622 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6623 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6624 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6625 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6626 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6627}
6628
Guy Benyei11169dd2012-12-18 14:30:41 +00006629CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6630 unsigned PieceIndex) {
6631 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006632
Guy Benyei11169dd2012-12-18 14:30:41 +00006633 switch (C.kind) {
6634 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006635 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006636 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6637 E->getQualifierLoc().getSourceRange());
6638 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006639
Guy Benyei11169dd2012-12-18 14:30:41 +00006640 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006641 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6642 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6643 Pieces =
6644 buildPieces(NameFlags, false, E->getNameInfo(),
6645 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6646 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006647 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006648
Guy Benyei11169dd2012-12-18 14:30:41 +00006649 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006650 if (const CXXOperatorCallExpr *OCE =
6651 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006652 const Expr *Callee = OCE->getCallee();
6653 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006654 Callee = ICE->getSubExpr();
6655
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006656 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006657 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6658 DRE->getQualifierLoc().getSourceRange());
6659 }
6660 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006661
Guy Benyei11169dd2012-12-18 14:30:41 +00006662 default:
6663 break;
6664 }
6665
6666 if (Pieces.empty()) {
6667 if (PieceIndex == 0)
6668 return clang_getCursorExtent(C);
6669 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006670 SourceRange R = Pieces[PieceIndex];
6671 if (R.isValid())
6672 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006673 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006674
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 return clang_getNullRange();
6676}
6677
6678void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006679 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6680 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006681}
6682
Michael Kruse7520cf02020-03-25 09:26:14 -05006683void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006684 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006685 llvm::llvm_execute_on_thread(fn, user_data,
6686 stack_size == 0
6687 ? clang::DesiredStackSize
6688 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006689}
6690
Guy Benyei11169dd2012-12-18 14:30:41 +00006691//===----------------------------------------------------------------------===//
6692// Token-based Operations.
6693//===----------------------------------------------------------------------===//
6694
6695/* CXToken layout:
6696 * int_data[0]: a CXTokenKind
6697 * int_data[1]: starting token location
6698 * int_data[2]: token length
6699 * int_data[3]: reserved
6700 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6701 * otherwise unused.
6702 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006703CXTokenKind clang_getTokenKind(CXToken CXTok) {
6704 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6705}
6706
6707CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6708 switch (clang_getTokenKind(CXTok)) {
6709 case CXToken_Identifier:
6710 case CXToken_Keyword:
6711 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006712 return cxstring::createRef(
6713 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006714
6715 case CXToken_Literal: {
6716 // We have stashed the starting pointer in the ptr_data field. Use it.
6717 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006718 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006719 }
6720
6721 case CXToken_Punctuation:
6722 case CXToken_Comment:
6723 break;
6724 }
6725
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006726 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006727 LOG_BAD_TU(TU);
6728 return cxstring::createEmpty();
6729 }
6730
Guy Benyei11169dd2012-12-18 14:30:41 +00006731 // We have to find the starting buffer pointer the hard way, by
6732 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006733 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006734 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006735 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006736
6737 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006738 std::pair<FileID, unsigned> LocInfo =
6739 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006740 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006741 StringRef Buffer =
6742 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006743 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006744 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006745
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006746 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006747}
6748
6749CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006750 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006751 LOG_BAD_TU(TU);
6752 return clang_getNullLocation();
6753 }
6754
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006755 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006756 if (!CXXUnit)
6757 return clang_getNullLocation();
6758
Michael Kruse7520cf02020-03-25 09:26:14 -05006759 return cxloc::translateSourceLocation(
6760 CXXUnit->getASTContext(),
6761 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006762}
6763
6764CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006765 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006766 LOG_BAD_TU(TU);
6767 return clang_getNullRange();
6768 }
6769
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006770 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006771 if (!CXXUnit)
6772 return clang_getNullRange();
6773
Michael Kruse7520cf02020-03-25 09:26:14 -05006774 return cxloc::translateSourceRange(
6775 CXXUnit->getASTContext(),
6776 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006777}
6778
6779static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6780 SmallVectorImpl<CXToken> &CXTokens) {
6781 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006782 std::pair<FileID, unsigned> BeginLocInfo =
6783 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6784 std::pair<FileID, unsigned> EndLocInfo =
6785 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006786
6787 // Cannot tokenize across files.
6788 if (BeginLocInfo.first != EndLocInfo.first)
6789 return;
6790
6791 // Create a lexer
6792 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006793 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006794 if (Invalid)
6795 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006796
Guy Benyei11169dd2012-12-18 14:30:41 +00006797 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006798 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6799 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006800 Lex.SetCommentRetentionState(true);
6801
6802 // Lex tokens until we hit the end of the range.
6803 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6804 Token Tok;
6805 bool previousWasAt = false;
6806 do {
6807 // Lex the next token
6808 Lex.LexFromRawLexer(Tok);
6809 if (Tok.is(tok::eof))
6810 break;
6811
6812 // Initialize the CXToken.
6813 CXToken CXTok;
6814
6815 // - Common fields
6816 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6817 CXTok.int_data[2] = Tok.getLength();
6818 CXTok.int_data[3] = 0;
6819
6820 // - Kind-specific fields
6821 if (Tok.isLiteral()) {
6822 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006823 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006824 } else if (Tok.is(tok::raw_identifier)) {
6825 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006826 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006827
6828 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6829 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006830 } else {
6831 CXTok.int_data[0] =
6832 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006833 }
6834 CXTok.ptr_data = II;
6835 } else if (Tok.is(tok::comment)) {
6836 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006837 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006838 } else {
6839 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006840 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006841 }
6842 CXTokens.push_back(CXTok);
6843 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006844 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006845}
6846
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006847CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006848 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006849
6850 if (isNotUsableTU(TU)) {
6851 LOG_BAD_TU(TU);
6852 return NULL;
6853 }
6854
6855 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6856 if (!CXXUnit)
6857 return NULL;
6858
6859 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6860 if (Begin.isInvalid())
6861 return NULL;
6862 SourceManager &SM = CXXUnit->getSourceManager();
6863 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006864 DecomposedEnd.second +=
6865 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006866
Michael Kruse7520cf02020-03-25 09:26:14 -05006867 SourceLocation End =
6868 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006869
6870 SmallVector<CXToken, 32> CXTokens;
6871 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6872
6873 if (CXTokens.empty())
6874 return NULL;
6875
6876 CXTokens.resize(1);
6877 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6878
6879 memmove(Token, CXTokens.data(), sizeof(CXToken));
6880 return Token;
6881}
6882
Michael Kruse7520cf02020-03-25 09:26:14 -05006883void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6884 unsigned *NumTokens) {
6885 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006886
Guy Benyei11169dd2012-12-18 14:30:41 +00006887 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006888 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006889 if (NumTokens)
6890 *NumTokens = 0;
6891
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006892 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006893 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006894 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006895 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006896
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006897 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006898 if (!CXXUnit || !Tokens || !NumTokens)
6899 return;
6900
6901 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006902
Guy Benyei11169dd2012-12-18 14:30:41 +00006903 SourceRange R = cxloc::translateCXSourceRange(Range);
6904 if (R.isInvalid())
6905 return;
6906
6907 SmallVector<CXToken, 32> CXTokens;
6908 getTokens(CXXUnit, R, CXTokens);
6909
6910 if (CXTokens.empty())
6911 return;
6912
Serge Pavlov52525732018-02-21 02:02:39 +00006913 *Tokens = static_cast<CXToken *>(
6914 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006915 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6916 *NumTokens = CXTokens.size();
6917}
6918
Michael Kruse7520cf02020-03-25 09:26:14 -05006919void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6920 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006921 free(Tokens);
6922}
6923
Guy Benyei11169dd2012-12-18 14:30:41 +00006924//===----------------------------------------------------------------------===//
6925// Token annotation APIs.
6926//===----------------------------------------------------------------------===//
6927
Guy Benyei11169dd2012-12-18 14:30:41 +00006928static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6929 CXCursor parent,
6930 CXClientData client_data);
6931static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6932 CXClientData client_data);
6933
6934namespace {
6935class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006936 CXToken *Tokens;
6937 CXCursor *Cursors;
6938 unsigned NumTokens;
6939 unsigned TokIdx;
6940 unsigned PreprocessingTokIdx;
6941 CursorVisitor AnnotateVis;
6942 SourceManager &SrcMgr;
6943 bool HasContextSensitiveKeywords;
6944
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006945 struct PostChildrenAction {
6946 CXCursor cursor;
6947 enum Action { Invalid, Ignore, Postpone } action;
6948 };
6949 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6950
Guy Benyei11169dd2012-12-18 14:30:41 +00006951 struct PostChildrenInfo {
6952 CXCursor Cursor;
6953 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006954 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006955 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006956 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006957 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006958 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006959
6960 CXToken &getTok(unsigned Idx) {
6961 assert(Idx < NumTokens);
6962 return Tokens[Idx];
6963 }
6964 const CXToken &getTok(unsigned Idx) const {
6965 assert(Idx < NumTokens);
6966 return Tokens[Idx];
6967 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006968 bool MoreTokens() const { return TokIdx < NumTokens; }
6969 unsigned NextToken() const { return TokIdx; }
6970 void AdvanceToken() { ++TokIdx; }
6971 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006972 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006973 }
6974 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006975 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006976 }
6977 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006978 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006979 }
6980
6981 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006982 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006983 SourceRange);
6984
6985public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006986 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006987 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05006988 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
6989 PreprocessingTokIdx(0),
6990 AnnotateVis(TU, AnnotateTokensVisitor, this,
6991 /*VisitPreprocessorLast=*/true,
6992 /*VisitIncludedEntities=*/false, RegionOfInterest,
6993 /*VisitDeclsOnly=*/false,
6994 AnnotateTokensPostChildrenVisitor),
6995 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
6996 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00006997
6998 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6999 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007000 bool IsIgnoredChildCursor(CXCursor cursor) const;
7001 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
7002
Guy Benyei11169dd2012-12-18 14:30:41 +00007003 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007004 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
7005 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
7006
Guy Benyei11169dd2012-12-18 14:30:41 +00007007 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05007008
7009 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00007010 /// context-sensitive keywords.
7011 bool hasContextSensitiveKeywords() const {
7012 return HasContextSensitiveKeywords;
7013 }
7014
Michael Kruse7520cf02020-03-25 09:26:14 -05007015 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00007016};
Michael Kruse7520cf02020-03-25 09:26:14 -05007017} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00007018
7019void AnnotateTokensWorker::AnnotateTokens() {
7020 // Walk the AST within the region of interest, annotating tokens
7021 // along the way.
7022 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007023}
Guy Benyei11169dd2012-12-18 14:30:41 +00007024
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007025bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7026 if (PostChildrenInfos.empty())
7027 return false;
7028
7029 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7030 if (ChildAction.cursor == cursor &&
7031 ChildAction.action == PostChildrenAction::Ignore) {
7032 return true;
7033 }
7034 }
7035
7036 return false;
7037}
7038
7039const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7040 if (!clang_isExpression(Cursor.kind))
7041 return nullptr;
7042
7043 const Expr *E = getCursorExpr(Cursor);
7044 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7045 const OverloadedOperatorKind Kind = OCE->getOperator();
7046 if (Kind == OO_Call || Kind == OO_Subscript)
7047 return OCE;
7048 }
7049
7050 return nullptr;
7051}
7052
7053AnnotateTokensWorker::PostChildrenActions
7054AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7055 PostChildrenActions actions;
7056
7057 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7058 // visited before the arguments to the operator call. For the Call and
7059 // Subscript operator the range of this DeclRefExpr includes the whole call
7060 // expression, so that all tokens in that range would be mapped to the
7061 // operator function, including the tokens of the arguments. To avoid that,
7062 // ensure to visit this DeclRefExpr as last node.
7063 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7064 const Expr *Callee = OCE->getCallee();
7065 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7066 const Expr *SubExpr = ICE->getSubExpr();
7067 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007068 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007069 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7070
7071 // Visit the DeclRefExpr as last.
7072 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7073 actions.push_back({cxChild, PostChildrenAction::Postpone});
7074
7075 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7076 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7077 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7078 actions.push_back({cxChild, PostChildrenAction::Ignore});
7079 }
7080 }
7081 }
7082
7083 return actions;
7084}
7085
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007086static inline void updateCursorAnnotation(CXCursor &Cursor,
7087 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007088 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007089 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007090 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007091}
7092
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007093/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007094//// between the cursor location and the source range is the same as
7095/// \arg compResult.
7096///
7097/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7098/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007099void AnnotateTokensWorker::annotateAndAdvanceTokens(
7100 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007101 while (MoreTokens()) {
7102 const unsigned I = NextToken();
7103 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007104 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7105 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007106
7107 SourceLocation TokLoc = GetTokenLoc(I);
7108 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007109 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007110 AdvanceToken();
7111 continue;
7112 }
7113 break;
7114 }
7115}
7116
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007117/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007118/// \returns true if it advanced beyond all macro tokens, false otherwise.
7119bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007120 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007121 assert(MoreTokens());
7122 assert(isFunctionMacroToken(NextToken()) &&
7123 "Should be called only for macro arg tokens");
7124
7125 // This works differently than annotateAndAdvanceTokens; because expanded
7126 // macro arguments can have arbitrary translation-unit source order, we do not
7127 // advance the token index one by one until a token fails the range test.
7128 // We only advance once past all of the macro arg tokens if all of them
7129 // pass the range test. If one of them fails we keep the token index pointing
7130 // at the start of the macro arg tokens so that the failing token will be
7131 // annotated by a subsequent annotation try.
7132
7133 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007134
Guy Benyei11169dd2012-12-18 14:30:41 +00007135 unsigned I = NextToken();
7136 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7137 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7138 if (TokLoc.isFileID())
7139 continue; // not macro arg token, it's parens or comma.
7140 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7141 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7142 Cursors[I] = updateC;
7143 } else
7144 atLeastOneCompFail = true;
7145 }
7146
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007147 if (atLeastOneCompFail)
7148 return false;
7149
7150 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7151 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007152}
7153
Michael Kruse7520cf02020-03-25 09:26:14 -05007154enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7155 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007156 SourceRange cursorRange = getRawCursorExtent(cursor);
7157 if (cursorRange.isInvalid())
7158 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007159
7160 if (IsIgnoredChildCursor(cursor))
7161 return CXChildVisit_Continue;
7162
Guy Benyei11169dd2012-12-18 14:30:41 +00007163 if (!HasContextSensitiveKeywords) {
7164 // Objective-C properties can have context-sensitive keywords.
7165 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007166 if (const ObjCPropertyDecl *Property =
7167 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7168 HasContextSensitiveKeywords =
7169 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007170 }
7171 // Objective-C methods can have context-sensitive keywords.
7172 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7173 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007174 if (const ObjCMethodDecl *Method =
7175 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007176 if (Method->getObjCDeclQualifier())
7177 HasContextSensitiveKeywords = true;
7178 else {
David Majnemer59f77922016-06-24 04:05:48 +00007179 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007180 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007181 HasContextSensitiveKeywords = true;
7182 break;
7183 }
7184 }
7185 }
7186 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007187 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007188 // C++ methods can have context-sensitive keywords.
7189 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007190 if (const CXXMethodDecl *Method =
7191 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007192 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7193 HasContextSensitiveKeywords = true;
7194 }
7195 }
7196 // C++ classes can have context-sensitive keywords.
7197 else if (cursor.kind == CXCursor_StructDecl ||
7198 cursor.kind == CXCursor_ClassDecl ||
7199 cursor.kind == CXCursor_ClassTemplate ||
7200 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007201 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007202 if (D->hasAttr<FinalAttr>())
7203 HasContextSensitiveKeywords = true;
7204 }
7205 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007206
7207 // Don't override a property annotation with its getter/setter method.
7208 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7209 parent.kind == CXCursor_ObjCPropertyDecl)
7210 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007211
7212 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007213 // Items in the preprocessing record are kept separate from items in
7214 // declarations, so we keep a separate token index.
7215 unsigned SavedTokIdx = TokIdx;
7216 TokIdx = PreprocessingTokIdx;
7217
7218 // Skip tokens up until we catch up to the beginning of the preprocessing
7219 // entry.
7220 while (MoreTokens()) {
7221 const unsigned I = NextToken();
7222 SourceLocation TokLoc = GetTokenLoc(I);
7223 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7224 case RangeBefore:
7225 AdvanceToken();
7226 continue;
7227 case RangeAfter:
7228 case RangeOverlap:
7229 break;
7230 }
7231 break;
7232 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007233
Guy Benyei11169dd2012-12-18 14:30:41 +00007234 // Look at all of the tokens within this range.
7235 while (MoreTokens()) {
7236 const unsigned I = NextToken();
7237 SourceLocation TokLoc = GetTokenLoc(I);
7238 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7239 case RangeBefore:
7240 llvm_unreachable("Infeasible");
7241 case RangeAfter:
7242 break;
7243 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007244 // For macro expansions, just note where the beginning of the macro
7245 // expansion occurs.
7246 if (cursor.kind == CXCursor_MacroExpansion) {
7247 if (TokLoc == cursorRange.getBegin())
7248 Cursors[I] = cursor;
7249 AdvanceToken();
7250 break;
7251 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007252 // We may have already annotated macro names inside macro definitions.
7253 if (Cursors[I].kind != CXCursor_MacroExpansion)
7254 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007255 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007256 continue;
7257 }
7258 break;
7259 }
7260
7261 // Save the preprocessing token index; restore the non-preprocessing
7262 // token index.
7263 PreprocessingTokIdx = TokIdx;
7264 TokIdx = SavedTokIdx;
7265 return CXChildVisit_Recurse;
7266 }
7267
7268 if (cursorRange.isInvalid())
7269 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007270
7271 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007272 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007273 const enum CXCursorKind K = clang_getCursorKind(parent);
7274 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007275 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7276 // Attributes are annotated out-of-order, skip tokens until we reach it.
7277 clang_isAttribute(cursor.kind))
7278 ? clang_getNullCursor()
7279 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007280
7281 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7282
7283 // Avoid having the cursor of an expression "overwrite" the annotation of the
7284 // variable declaration that it belongs to.
7285 // This can happen for C++ constructor expressions whose range generally
7286 // include the variable declaration, e.g.:
7287 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007288 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007289 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007290 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007291 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007292 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7293 E->getBeginLoc() == D->getLocation() &&
7294 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007295 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007296 AdvanceToken();
7297 }
7298 }
7299 }
7300
7301 // Before recursing into the children keep some state that we are going
7302 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7303 // extra work after the child nodes are visited.
7304 // Note that we don't call VisitChildren here to avoid traversing statements
7305 // code-recursively which can blow the stack.
7306
7307 PostChildrenInfo Info;
7308 Info.Cursor = cursor;
7309 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007310 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007311 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007312 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007313 PostChildrenInfos.push_back(Info);
7314
7315 return CXChildVisit_Recurse;
7316}
7317
7318bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7319 if (PostChildrenInfos.empty())
7320 return false;
7321 const PostChildrenInfo &Info = PostChildrenInfos.back();
7322 if (!clang_equalCursors(Info.Cursor, cursor))
7323 return false;
7324
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007325 HandlePostPonedChildCursors(Info);
7326
Guy Benyei11169dd2012-12-18 14:30:41 +00007327 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7328 const unsigned AfterChildren = NextToken();
7329 SourceRange cursorRange = Info.CursorRange;
7330
7331 // Scan the tokens that are at the end of the cursor, but are not captured
7332 // but the child cursors.
7333 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7334
7335 // Scan the tokens that are at the beginning of the cursor, but are not
7336 // capture by the child cursors.
7337 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7338 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7339 break;
7340
7341 Cursors[I] = cursor;
7342 }
7343
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007344 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7345 // encountered the attribute cursor.
7346 if (clang_isAttribute(cursor.kind))
7347 TokIdx = Info.BeforeReachingCursorIdx;
7348
Guy Benyei11169dd2012-12-18 14:30:41 +00007349 PostChildrenInfos.pop_back();
7350 return false;
7351}
7352
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007353void AnnotateTokensWorker::HandlePostPonedChildCursors(
7354 const PostChildrenInfo &Info) {
7355 for (const auto &ChildAction : Info.ChildActions) {
7356 if (ChildAction.action == PostChildrenAction::Postpone) {
7357 HandlePostPonedChildCursor(ChildAction.cursor,
7358 Info.BeforeChildrenTokenIdx);
7359 }
7360 }
7361}
7362
7363void AnnotateTokensWorker::HandlePostPonedChildCursor(
7364 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007365 unsigned I = StartTokenIndex;
7366
7367 // The bracket tokens of a Call or Subscript operator are mapped to
7368 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7369 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7370 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007371 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7372 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007373 if (clang_Range_isNull(CXRefNameRange))
7374 break; // All ranges handled.
7375
7376 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7377 while (I < NumTokens) {
7378 const SourceLocation TokenLocation = GetTokenLoc(I);
7379 if (!TokenLocation.isValid())
7380 break;
7381
7382 // Adapt the end range, because LocationCompare() reports
7383 // RangeOverlap even for the not-inclusive end location.
7384 const SourceLocation fixedEnd =
7385 RefNameRange.getEnd().getLocWithOffset(-1);
7386 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7387
7388 const RangeComparisonResult ComparisonResult =
7389 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7390
7391 if (ComparisonResult == RangeOverlap) {
7392 Cursors[I++] = Cursor;
7393 } else if (ComparisonResult == RangeBefore) {
7394 ++I; // Not relevant token, check next one.
7395 } else if (ComparisonResult == RangeAfter) {
7396 break; // All tokens updated for current range, check next.
7397 }
7398 }
7399 }
7400}
7401
Guy Benyei11169dd2012-12-18 14:30:41 +00007402static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7403 CXCursor parent,
7404 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007405 return static_cast<AnnotateTokensWorker *>(client_data)
7406 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007407}
7408
7409static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7410 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007411 return static_cast<AnnotateTokensWorker *>(client_data)
7412 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007413}
7414
7415namespace {
7416
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007417/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007418/// and mark tokens that are macro arguments. This info is used by the
7419/// AnnotateTokensWorker.
7420class MarkMacroArgTokensVisitor {
7421 SourceManager &SM;
7422 CXToken *Tokens;
7423 unsigned NumTokens;
7424 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007425
Guy Benyei11169dd2012-12-18 14:30:41 +00007426public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007427 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7428 unsigned numTokens)
7429 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007430
7431 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7432 if (cursor.kind != CXCursor_MacroExpansion)
7433 return CXChildVisit_Continue;
7434
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007435 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007436 if (macroRange.getBegin() == macroRange.getEnd())
7437 return CXChildVisit_Continue; // it's not a function macro.
7438
7439 for (; CurIdx < NumTokens; ++CurIdx) {
7440 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7441 macroRange.getBegin()))
7442 break;
7443 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007444
Guy Benyei11169dd2012-12-18 14:30:41 +00007445 if (CurIdx == NumTokens)
7446 return CXChildVisit_Break;
7447
7448 for (; CurIdx < NumTokens; ++CurIdx) {
7449 SourceLocation tokLoc = getTokenLoc(CurIdx);
7450 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7451 break;
7452
7453 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7454 }
7455
7456 if (CurIdx == NumTokens)
7457 return CXChildVisit_Break;
7458
7459 return CXChildVisit_Continue;
7460 }
7461
7462private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007463 CXToken &getTok(unsigned Idx) {
7464 assert(Idx < NumTokens);
7465 return Tokens[Idx];
7466 }
7467 const CXToken &getTok(unsigned Idx) const {
7468 assert(Idx < NumTokens);
7469 return Tokens[Idx];
7470 }
7471
Guy Benyei11169dd2012-12-18 14:30:41 +00007472 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007473 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007474 }
7475
7476 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7477 // The third field is reserved and currently not used. Use it here
7478 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007479 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007480 }
7481};
7482
7483} // end anonymous namespace
7484
7485static CXChildVisitResult
7486MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7487 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007488 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7489 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007490}
7491
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007492/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007493/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007494static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7495 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007496 if (NextIdx >= NumTokens)
7497 return true;
7498
7499 ++NextIdx;
7500 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007501 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007502}
7503
Guy Benyei11169dd2012-12-18 14:30:41 +00007504static void annotatePreprocessorTokens(CXTranslationUnit TU,
7505 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007506 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007507 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007508 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007509
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007510 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007511 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007512 std::pair<FileID, unsigned> BeginLocInfo =
7513 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7514 std::pair<FileID, unsigned> EndLocInfo =
7515 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007516
7517 if (BeginLocInfo.first != EndLocInfo.first)
7518 return;
7519
7520 StringRef Buffer;
7521 bool Invalid = false;
7522 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7523 if (Buffer.empty() || Invalid)
7524 return;
7525
7526 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007527 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7528 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007529 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007530
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007531 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007532 // Lex tokens in raw mode until we hit the end of the range, to avoid
7533 // entering #includes or expanding macros.
7534 while (true) {
7535 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007536 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7537 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007538 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007539 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007540 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7541
Guy Benyei11169dd2012-12-18 14:30:41 +00007542 reprocess:
7543 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007544 // We have found a preprocessing directive. Annotate the tokens
7545 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007546 //
7547 // FIXME: Some simple tests here could identify macro definitions and
7548 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007549
7550 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007551 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7552 break;
7553
Craig Topper69186e72014-06-08 08:38:04 +00007554 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007555 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007556 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7557 break;
7558
7559 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007560 IdentifierInfo &II =
7561 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007562 SourceLocation MappedTokLoc =
7563 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7564 MI = getMacroInfo(II, MappedTokLoc, TU);
7565 }
7566 }
7567
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007568 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007569 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007570 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7571 finished = true;
7572 break;
7573 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007574 // If we are in a macro definition, check if the token was ever a
7575 // macro name and annotate it if that's the case.
7576 if (MI) {
7577 SourceLocation SaveLoc = Tok.getLocation();
7578 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007579 MacroDefinitionRecord *MacroDef =
7580 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007581 Tok.setLocation(SaveLoc);
7582 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007583 Cursors[NextIdx - 1] =
7584 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007585 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007586 } while (!Tok.isAtStartOfLine());
7587
Michael Kruse7520cf02020-03-25 09:26:14 -05007588 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007589 assert(TokIdx <= LastIdx);
7590 SourceLocation EndLoc =
7591 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7592 CXCursor Cursor =
7593 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7594
7595 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007596 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007597
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007598 if (finished)
7599 break;
7600 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007601 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007602 }
7603}
7604
7605// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007606static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7607 CXToken *Tokens, unsigned NumTokens,
7608 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007609 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007610 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7611 setThreadBackgroundPriority();
7612
7613 // Determine the region of interest, which contains all of the tokens.
7614 SourceRange RegionOfInterest;
7615 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007616 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7617 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7618 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007619
Guy Benyei11169dd2012-12-18 14:30:41 +00007620 // Relex the tokens within the source range to look for preprocessing
7621 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007622 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007623
7624 // If begin location points inside a macro argument, set it to the expansion
7625 // location so we can have the full context when annotating semantically.
7626 {
7627 SourceManager &SM = CXXUnit->getSourceManager();
7628 SourceLocation Loc =
7629 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7630 if (Loc.isMacroID())
7631 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7632 }
7633
Guy Benyei11169dd2012-12-18 14:30:41 +00007634 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7635 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007636 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7637 NumTokens);
7638 CursorVisitor MacroArgMarker(
7639 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7640 /*VisitPreprocessorLast=*/true,
7641 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007642 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7643 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007644
Guy Benyei11169dd2012-12-18 14:30:41 +00007645 // Annotate all of the source locations in the region of interest that map to
7646 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007647 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007648
Guy Benyei11169dd2012-12-18 14:30:41 +00007649 // FIXME: We use a ridiculous stack size here because the data-recursion
7650 // algorithm uses a large stack frame than the non-data recursive version,
7651 // and AnnotationTokensWorker currently transforms the data-recursion
7652 // algorithm back into a traditional recursion by explicitly calling
7653 // VisitChildren(). We will need to remove this explicit recursive call.
7654 W.AnnotateTokens();
7655
7656 // If we ran into any entities that involve context-sensitive keywords,
7657 // take another pass through the tokens to mark them as such.
7658 if (W.hasContextSensitiveKeywords()) {
7659 for (unsigned I = 0; I != NumTokens; ++I) {
7660 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7661 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007662
Guy Benyei11169dd2012-12-18 14:30:41 +00007663 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7664 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007665 if (const ObjCPropertyDecl *Property =
7666 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007667 if (Property->getPropertyAttributesAsWritten() != 0 &&
7668 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007669 .Case("readonly", true)
7670 .Case("assign", true)
7671 .Case("unsafe_unretained", true)
7672 .Case("readwrite", true)
7673 .Case("retain", true)
7674 .Case("copy", true)
7675 .Case("nonatomic", true)
7676 .Case("atomic", true)
7677 .Case("getter", true)
7678 .Case("setter", true)
7679 .Case("strong", true)
7680 .Case("weak", true)
7681 .Case("class", true)
7682 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007683 Tokens[I].int_data[0] = CXToken_Keyword;
7684 }
7685 continue;
7686 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007687
Guy Benyei11169dd2012-12-18 14:30:41 +00007688 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7689 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7690 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7691 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007692 .Case("in", true)
7693 .Case("out", true)
7694 .Case("inout", true)
7695 .Case("oneway", true)
7696 .Case("bycopy", true)
7697 .Case("byref", true)
7698 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007699 Tokens[I].int_data[0] = CXToken_Keyword;
7700 continue;
7701 }
7702
7703 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7704 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7705 Tokens[I].int_data[0] = CXToken_Keyword;
7706 continue;
7707 }
7708 }
7709 }
7710}
7711
Michael Kruse7520cf02020-03-25 09:26:14 -05007712void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7713 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007714 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007715 LOG_BAD_TU(TU);
7716 return;
7717 }
7718 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007719 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007720 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007721 }
7722
7723 LOG_FUNC_SECTION {
7724 *Log << TU << ' ';
7725 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007726 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007727 *Log << clang_getRange(bloc, eloc);
7728 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007729
7730 // Any token we don't specifically annotate will have a NULL cursor.
7731 CXCursor C = clang_getNullCursor();
7732 for (unsigned I = 0; I != NumTokens; ++I)
7733 Cursors[I] = C;
7734
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007735 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007736 if (!CXXUnit)
7737 return;
7738
7739 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007740
7741 auto AnnotateTokensImpl = [=]() {
7742 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7743 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007744 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007745 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007746 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7747 }
7748}
7749
Guy Benyei11169dd2012-12-18 14:30:41 +00007750//===----------------------------------------------------------------------===//
7751// Operations for querying linkage of a cursor.
7752//===----------------------------------------------------------------------===//
7753
Guy Benyei11169dd2012-12-18 14:30:41 +00007754CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7755 if (!clang_isDeclaration(cursor.kind))
7756 return CXLinkage_Invalid;
7757
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007758 const Decl *D = cxcursor::getCursorDecl(cursor);
7759 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007760 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007761 case NoLinkage:
7762 case VisibleNoLinkage:
7763 return CXLinkage_NoLinkage;
7764 case ModuleInternalLinkage:
7765 case InternalLinkage:
7766 return CXLinkage_Internal;
7767 case UniqueExternalLinkage:
7768 return CXLinkage_UniqueExternal;
7769 case ModuleLinkage:
7770 case ExternalLinkage:
7771 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007772 };
7773
7774 return CXLinkage_Invalid;
7775}
Guy Benyei11169dd2012-12-18 14:30:41 +00007776
7777//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007778// Operations for querying visibility of a cursor.
7779//===----------------------------------------------------------------------===//
7780
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007781CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7782 if (!clang_isDeclaration(cursor.kind))
7783 return CXVisibility_Invalid;
7784
7785 const Decl *D = cxcursor::getCursorDecl(cursor);
7786 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7787 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007788 case HiddenVisibility:
7789 return CXVisibility_Hidden;
7790 case ProtectedVisibility:
7791 return CXVisibility_Protected;
7792 case DefaultVisibility:
7793 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007794 };
7795
7796 return CXVisibility_Invalid;
7797}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007798
7799//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007800// Operations for querying language of a cursor.
7801//===----------------------------------------------------------------------===//
7802
7803static CXLanguageKind getDeclLanguage(const Decl *D) {
7804 if (!D)
7805 return CXLanguage_C;
7806
7807 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007808 default:
7809 break;
7810 case Decl::ImplicitParam:
7811 case Decl::ObjCAtDefsField:
7812 case Decl::ObjCCategory:
7813 case Decl::ObjCCategoryImpl:
7814 case Decl::ObjCCompatibleAlias:
7815 case Decl::ObjCImplementation:
7816 case Decl::ObjCInterface:
7817 case Decl::ObjCIvar:
7818 case Decl::ObjCMethod:
7819 case Decl::ObjCProperty:
7820 case Decl::ObjCPropertyImpl:
7821 case Decl::ObjCProtocol:
7822 case Decl::ObjCTypeParam:
7823 return CXLanguage_ObjC;
7824 case Decl::CXXConstructor:
7825 case Decl::CXXConversion:
7826 case Decl::CXXDestructor:
7827 case Decl::CXXMethod:
7828 case Decl::CXXRecord:
7829 case Decl::ClassTemplate:
7830 case Decl::ClassTemplatePartialSpecialization:
7831 case Decl::ClassTemplateSpecialization:
7832 case Decl::Friend:
7833 case Decl::FriendTemplate:
7834 case Decl::FunctionTemplate:
7835 case Decl::LinkageSpec:
7836 case Decl::Namespace:
7837 case Decl::NamespaceAlias:
7838 case Decl::NonTypeTemplateParm:
7839 case Decl::StaticAssert:
7840 case Decl::TemplateTemplateParm:
7841 case Decl::TemplateTypeParm:
7842 case Decl::UnresolvedUsingTypename:
7843 case Decl::UnresolvedUsingValue:
7844 case Decl::Using:
7845 case Decl::UsingDirective:
7846 case Decl::UsingShadow:
7847 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007848 }
7849
7850 return CXLanguage_C;
7851}
7852
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007853static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7854 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007855 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007856
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007857 switch (D->getAvailability()) {
7858 case AR_Available:
7859 case AR_NotYetIntroduced:
7860 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007861 return getCursorAvailabilityForDecl(
7862 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007863 return CXAvailability_Available;
7864
7865 case AR_Deprecated:
7866 return CXAvailability_Deprecated;
7867
7868 case AR_Unavailable:
7869 return CXAvailability_NotAvailable;
7870 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007871
7872 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007873}
7874
Guy Benyei11169dd2012-12-18 14:30:41 +00007875enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7876 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007877 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7878 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007879
7880 return CXAvailability_Available;
7881}
7882
7883static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007884 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007885 if (In.empty())
7886 return Out;
7887
7888 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007889
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007890 Optional<unsigned> Minor = In.getMinor();
7891 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007892 Out.Minor = *Minor;
7893 else
7894 return Out;
7895
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007896 Optional<unsigned> Subminor = In.getSubminor();
7897 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007898 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007899
Guy Benyei11169dd2012-12-18 14:30:41 +00007900 return Out;
7901}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007902
Alex Lorenz1345ea22017-06-12 19:06:30 +00007903static void getCursorPlatformAvailabilityForDecl(
7904 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7905 int *always_unavailable, CXString *unavailable_message,
7906 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007907 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007908 for (auto A : D->attrs()) {
7909 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007910 HadAvailAttr = true;
7911 if (always_deprecated)
7912 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007913 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007914 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007915 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007916 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007917 continue;
7918 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007919
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007920 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007921 HadAvailAttr = true;
7922 if (always_unavailable)
7923 *always_unavailable = 1;
7924 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007925 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007926 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7927 }
7928 continue;
7929 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007930
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007931 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007932 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007933 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007934 }
7935 }
7936
7937 if (!HadAvailAttr)
7938 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7939 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007940 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7941 deprecated_message, always_unavailable, unavailable_message,
7942 AvailabilityAttrs);
7943
7944 if (AvailabilityAttrs.empty())
7945 return;
7946
Michael Kruse7520cf02020-03-25 09:26:14 -05007947 llvm::sort(
7948 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7949 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7950 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007951 ASTContext &Ctx = D->getASTContext();
7952 auto It = std::unique(
7953 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7954 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7955 if (LHS->getPlatform() != RHS->getPlatform())
7956 return false;
7957
7958 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7959 LHS->getDeprecated() == RHS->getDeprecated() &&
7960 LHS->getObsoleted() == RHS->getObsoleted() &&
7961 LHS->getMessage() == RHS->getMessage() &&
7962 LHS->getReplacement() == RHS->getReplacement())
7963 return true;
7964
7965 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
7966 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
7967 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
7968 return false;
7969
7970 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
7971 LHS->setIntroduced(Ctx, RHS->getIntroduced());
7972
7973 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
7974 LHS->setDeprecated(Ctx, RHS->getDeprecated());
7975 if (LHS->getMessage().empty())
7976 LHS->setMessage(Ctx, RHS->getMessage());
7977 if (LHS->getReplacement().empty())
7978 LHS->setReplacement(Ctx, RHS->getReplacement());
7979 }
7980
7981 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
7982 LHS->setObsoleted(Ctx, RHS->getObsoleted());
7983 if (LHS->getMessage().empty())
7984 LHS->setMessage(Ctx, RHS->getMessage());
7985 if (LHS->getReplacement().empty())
7986 LHS->setReplacement(Ctx, RHS->getReplacement());
7987 }
7988
7989 return true;
7990 });
7991 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007992}
7993
Alex Lorenz1345ea22017-06-12 19:06:30 +00007994int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00007995 CXString *deprecated_message,
7996 int *always_unavailable,
7997 CXString *unavailable_message,
7998 CXPlatformAvailability *availability,
7999 int availability_size) {
8000 if (always_deprecated)
8001 *always_deprecated = 0;
8002 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008003 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00008004 if (always_unavailable)
8005 *always_unavailable = 0;
8006 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008007 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008008
Guy Benyei11169dd2012-12-18 14:30:41 +00008009 if (!clang_isDeclaration(cursor.kind))
8010 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008011
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008012 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00008013 if (!D)
8014 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008015
Alex Lorenz1345ea22017-06-12 19:06:30 +00008016 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
8017 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8018 always_unavailable, unavailable_message,
8019 AvailabilityAttrs);
8020 for (const auto &Avail :
8021 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8022 .take_front(availability_size))) {
8023 availability[Avail.index()].Platform =
8024 cxstring::createDup(Avail.value()->getPlatform()->getName());
8025 availability[Avail.index()].Introduced =
8026 convertVersion(Avail.value()->getIntroduced());
8027 availability[Avail.index()].Deprecated =
8028 convertVersion(Avail.value()->getDeprecated());
8029 availability[Avail.index()].Obsoleted =
8030 convertVersion(Avail.value()->getObsoleted());
8031 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8032 availability[Avail.index()].Message =
8033 cxstring::createDup(Avail.value()->getMessage());
8034 }
8035
8036 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008037}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008038
Guy Benyei11169dd2012-12-18 14:30:41 +00008039void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8040 clang_disposeString(availability->Platform);
8041 clang_disposeString(availability->Message);
8042}
8043
8044CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8045 if (clang_isDeclaration(cursor.kind))
8046 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8047
8048 return CXLanguage_Invalid;
8049}
8050
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008051CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8052 const Decl *D = cxcursor::getCursorDecl(cursor);
8053 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8054 switch (VD->getTLSKind()) {
8055 case VarDecl::TLS_None:
8056 return CXTLS_None;
8057 case VarDecl::TLS_Dynamic:
8058 return CXTLS_Dynamic;
8059 case VarDecl::TLS_Static:
8060 return CXTLS_Static;
8061 }
8062 }
8063
8064 return CXTLS_None;
8065}
8066
Michael Kruse7520cf02020-03-25 09:26:14 -05008067/// If the given cursor is the "templated" declaration
8068/// describing a class or function template, return the class or
8069/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008070static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008071 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008072 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008073
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008074 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008075 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8076 return FunTmpl;
8077
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008078 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008079 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8080 return ClassTmpl;
8081
8082 return D;
8083}
8084
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008085enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8086 StorageClass sc = SC_None;
8087 const Decl *D = getCursorDecl(C);
8088 if (D) {
8089 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8090 sc = FD->getStorageClass();
8091 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8092 sc = VD->getStorageClass();
8093 } else {
8094 return CX_SC_Invalid;
8095 }
8096 } else {
8097 return CX_SC_Invalid;
8098 }
8099 switch (sc) {
8100 case SC_None:
8101 return CX_SC_None;
8102 case SC_Extern:
8103 return CX_SC_Extern;
8104 case SC_Static:
8105 return CX_SC_Static;
8106 case SC_PrivateExtern:
8107 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008108 case SC_Auto:
8109 return CX_SC_Auto;
8110 case SC_Register:
8111 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008112 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008113 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008114}
8115
Guy Benyei11169dd2012-12-18 14:30:41 +00008116CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8117 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008118 if (const Decl *D = getCursorDecl(cursor)) {
8119 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008120 if (!DC)
8121 return clang_getNullCursor();
8122
Michael Kruse7520cf02020-03-25 09:26:14 -05008123 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008124 getCursorTU(cursor));
8125 }
8126 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008127
Guy Benyei11169dd2012-12-18 14:30:41 +00008128 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008129 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008130 return MakeCXCursor(D, getCursorTU(cursor));
8131 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008132
Guy Benyei11169dd2012-12-18 14:30:41 +00008133 return clang_getNullCursor();
8134}
8135
8136CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8137 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008138 if (const Decl *D = getCursorDecl(cursor)) {
8139 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008140 if (!DC)
8141 return clang_getNullCursor();
8142
Michael Kruse7520cf02020-03-25 09:26:14 -05008143 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008144 getCursorTU(cursor));
8145 }
8146 }
8147
Michael Kruse7520cf02020-03-25 09:26:14 -05008148 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008149 // statement or expression, so we return nothing.
8150 return clang_getNullCursor();
8151}
8152
8153CXFile clang_getIncludedFile(CXCursor cursor) {
8154 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008155 return nullptr;
8156
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008157 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008158 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008159}
8160
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008161unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8162 if (C.kind != CXCursor_ObjCPropertyDecl)
8163 return CXObjCPropertyAttr_noattr;
8164
8165 unsigned Result = CXObjCPropertyAttr_noattr;
8166 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008167 ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008168
Michael Kruse7520cf02020-03-25 09:26:14 -05008169#define SET_CXOBJCPROP_ATTR(A) \
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008170 if (Attr & ObjCPropertyAttribute::kind_##A) \
Michael Kruse7520cf02020-03-25 09:26:14 -05008171 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008172 SET_CXOBJCPROP_ATTR(readonly);
8173 SET_CXOBJCPROP_ATTR(getter);
8174 SET_CXOBJCPROP_ATTR(assign);
8175 SET_CXOBJCPROP_ATTR(readwrite);
8176 SET_CXOBJCPROP_ATTR(retain);
8177 SET_CXOBJCPROP_ATTR(copy);
8178 SET_CXOBJCPROP_ATTR(nonatomic);
8179 SET_CXOBJCPROP_ATTR(setter);
8180 SET_CXOBJCPROP_ATTR(atomic);
8181 SET_CXOBJCPROP_ATTR(weak);
8182 SET_CXOBJCPROP_ATTR(strong);
8183 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008184 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008185#undef SET_CXOBJCPROP_ATTR
8186
8187 return Result;
8188}
8189
Michael Wu6e88f532018-08-03 05:38:29 +00008190CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8191 if (C.kind != CXCursor_ObjCPropertyDecl)
8192 return cxstring::createNull();
8193
8194 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8195 Selector sel = PD->getGetterName();
8196 if (sel.isNull())
8197 return cxstring::createNull();
8198
8199 return cxstring::createDup(sel.getAsString());
8200}
8201
8202CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8203 if (C.kind != CXCursor_ObjCPropertyDecl)
8204 return cxstring::createNull();
8205
8206 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8207 Selector sel = PD->getSetterName();
8208 if (sel.isNull())
8209 return cxstring::createNull();
8210
8211 return cxstring::createDup(sel.getAsString());
8212}
8213
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008214unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8215 if (!clang_isDeclaration(C.kind))
8216 return CXObjCDeclQualifier_None;
8217
8218 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8219 const Decl *D = getCursorDecl(C);
8220 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8221 QT = MD->getObjCDeclQualifier();
8222 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8223 QT = PD->getObjCDeclQualifier();
8224 if (QT == Decl::OBJC_TQ_None)
8225 return CXObjCDeclQualifier_None;
8226
8227 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008228 if (QT & Decl::OBJC_TQ_In)
8229 Result |= CXObjCDeclQualifier_In;
8230 if (QT & Decl::OBJC_TQ_Inout)
8231 Result |= CXObjCDeclQualifier_Inout;
8232 if (QT & Decl::OBJC_TQ_Out)
8233 Result |= CXObjCDeclQualifier_Out;
8234 if (QT & Decl::OBJC_TQ_Bycopy)
8235 Result |= CXObjCDeclQualifier_Bycopy;
8236 if (QT & Decl::OBJC_TQ_Byref)
8237 Result |= CXObjCDeclQualifier_Byref;
8238 if (QT & Decl::OBJC_TQ_Oneway)
8239 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008240
8241 return Result;
8242}
8243
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008244unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8245 if (!clang_isDeclaration(C.kind))
8246 return 0;
8247
8248 const Decl *D = getCursorDecl(C);
8249 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8250 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8251 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8252 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8253
8254 return 0;
8255}
8256
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008257unsigned clang_Cursor_isVariadic(CXCursor C) {
8258 if (!clang_isDeclaration(C.kind))
8259 return 0;
8260
8261 const Decl *D = getCursorDecl(C);
8262 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8263 return FD->isVariadic();
8264 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8265 return MD->isVariadic();
8266
8267 return 0;
8268}
8269
Michael Kruse7520cf02020-03-25 09:26:14 -05008270unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8271 CXString *definedIn,
8272 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008273 if (!clang_isDeclaration(C.kind))
8274 return 0;
8275
8276 const Decl *D = getCursorDecl(C);
8277
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008278 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008279 if (language)
8280 *language = cxstring::createDup(attr->getLanguage());
8281 if (definedIn)
8282 *definedIn = cxstring::createDup(attr->getDefinedIn());
8283 if (isGenerated)
8284 *isGenerated = attr->getGeneratedDeclaration();
8285 return 1;
8286 }
8287 return 0;
8288}
8289
Guy Benyei11169dd2012-12-18 14:30:41 +00008290CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8291 if (!clang_isDeclaration(C.kind))
8292 return clang_getNullRange();
8293
8294 const Decl *D = getCursorDecl(C);
8295 ASTContext &Context = getCursorContext(C);
8296 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8297 if (!RC)
8298 return clang_getNullRange();
8299
8300 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8301}
8302
8303CXString clang_Cursor_getRawCommentText(CXCursor C) {
8304 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008305 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008306
8307 const Decl *D = getCursorDecl(C);
8308 ASTContext &Context = getCursorContext(C);
8309 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008310 StringRef RawText =
8311 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008312
8313 // Don't duplicate the string because RawText points directly into source
8314 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008315 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008316}
8317
8318CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8319 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008320 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008321
8322 const Decl *D = getCursorDecl(C);
8323 const ASTContext &Context = getCursorContext(C);
8324 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8325
8326 if (RC) {
8327 StringRef BriefText = RC->getBriefText(Context);
8328
8329 // Don't duplicate the string because RawComment ensures that this memory
8330 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008331 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008332 }
8333
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008334 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008335}
8336
Guy Benyei11169dd2012-12-18 14:30:41 +00008337CXModule clang_Cursor_getModule(CXCursor C) {
8338 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008339 if (const ImportDecl *ImportD =
8340 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008341 return ImportD->getImportedModule();
8342 }
8343
Craig Topper69186e72014-06-08 08:38:04 +00008344 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008345}
8346
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008347CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8348 if (isNotUsableTU(TU)) {
8349 LOG_BAD_TU(TU);
8350 return nullptr;
8351 }
8352 if (!File)
8353 return nullptr;
8354 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008355
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008356 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8357 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8358 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008359
Richard Smithfeb54b62014-10-23 02:01:19 +00008360 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008361}
8362
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008363CXFile clang_Module_getASTFile(CXModule CXMod) {
8364 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008365 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008366 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008367 return const_cast<FileEntry *>(Mod->getASTFile());
8368}
8369
Guy Benyei11169dd2012-12-18 14:30:41 +00008370CXModule clang_Module_getParent(CXModule CXMod) {
8371 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008372 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008373 Module *Mod = static_cast<Module *>(CXMod);
Guy Benyei11169dd2012-12-18 14:30:41 +00008374 return Mod->Parent;
8375}
8376
8377CXString clang_Module_getName(CXModule CXMod) {
8378 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008379 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008380 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008381 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008382}
8383
8384CXString clang_Module_getFullName(CXModule CXMod) {
8385 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008386 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008387 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008388 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008389}
8390
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008391int clang_Module_isSystem(CXModule CXMod) {
8392 if (!CXMod)
8393 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008394 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008395 return Mod->IsSystem;
8396}
8397
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008398unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8399 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008400 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008401 LOG_BAD_TU(TU);
8402 return 0;
8403 }
8404 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008405 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008406 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008407 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8408 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8409 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008410}
8411
Michael Kruse7520cf02020-03-25 09:26:14 -05008412CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8413 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008414 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008415 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008416 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008417 }
8418 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008419 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008420 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008421 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008422
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008423 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8424 if (Index < TopHeaders.size())
8425 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008426
Craig Topper69186e72014-06-08 08:38:04 +00008427 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008428}
8429
Guy Benyei11169dd2012-12-18 14:30:41 +00008430//===----------------------------------------------------------------------===//
8431// C++ AST instrospection.
8432//===----------------------------------------------------------------------===//
8433
Jonathan Coe29565352016-04-27 12:48:25 +00008434unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8435 if (!clang_isDeclaration(C.kind))
8436 return 0;
8437
8438 const Decl *D = cxcursor::getCursorDecl(C);
8439 const CXXConstructorDecl *Constructor =
8440 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8441 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8442}
8443
8444unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8445 if (!clang_isDeclaration(C.kind))
8446 return 0;
8447
8448 const Decl *D = cxcursor::getCursorDecl(C);
8449 const CXXConstructorDecl *Constructor =
8450 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8451 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8452}
8453
8454unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8455 if (!clang_isDeclaration(C.kind))
8456 return 0;
8457
8458 const Decl *D = cxcursor::getCursorDecl(C);
8459 const CXXConstructorDecl *Constructor =
8460 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8461 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8462}
8463
8464unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8465 if (!clang_isDeclaration(C.kind))
8466 return 0;
8467
8468 const Decl *D = cxcursor::getCursorDecl(C);
8469 const CXXConstructorDecl *Constructor =
8470 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8471 // Passing 'false' excludes constructors marked 'explicit'.
8472 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8473}
8474
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008475unsigned clang_CXXField_isMutable(CXCursor C) {
8476 if (!clang_isDeclaration(C.kind))
8477 return 0;
8478
8479 if (const auto D = cxcursor::getCursorDecl(C))
8480 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8481 return FD->isMutable() ? 1 : 0;
8482 return 0;
8483}
8484
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008485unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8486 if (!clang_isDeclaration(C.kind))
8487 return 0;
8488
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008489 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008490 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008491 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008492 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8493}
8494
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008495unsigned clang_CXXMethod_isConst(CXCursor C) {
8496 if (!clang_isDeclaration(C.kind))
8497 return 0;
8498
8499 const Decl *D = cxcursor::getCursorDecl(C);
8500 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008501 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008502 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008503}
8504
Jonathan Coe29565352016-04-27 12:48:25 +00008505unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8506 if (!clang_isDeclaration(C.kind))
8507 return 0;
8508
8509 const Decl *D = cxcursor::getCursorDecl(C);
8510 const CXXMethodDecl *Method =
8511 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8512 return (Method && Method->isDefaulted()) ? 1 : 0;
8513}
8514
Guy Benyei11169dd2012-12-18 14:30:41 +00008515unsigned clang_CXXMethod_isStatic(CXCursor C) {
8516 if (!clang_isDeclaration(C.kind))
8517 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008518
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008519 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008520 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008521 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008522 return (Method && Method->isStatic()) ? 1 : 0;
8523}
8524
8525unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8526 if (!clang_isDeclaration(C.kind))
8527 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008528
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008529 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008530 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008531 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008532 return (Method && Method->isVirtual()) ? 1 : 0;
8533}
Guy Benyei11169dd2012-12-18 14:30:41 +00008534
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008535unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8536 if (!clang_isDeclaration(C.kind))
8537 return 0;
8538
8539 const auto *D = cxcursor::getCursorDecl(C);
8540 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8541 if (RD)
8542 RD = RD->getDefinition();
8543 return (RD && RD->isAbstract()) ? 1 : 0;
8544}
8545
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008546unsigned clang_EnumDecl_isScoped(CXCursor C) {
8547 if (!clang_isDeclaration(C.kind))
8548 return 0;
8549
8550 const Decl *D = cxcursor::getCursorDecl(C);
8551 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8552 return (Enum && Enum->isScoped()) ? 1 : 0;
8553}
8554
Guy Benyei11169dd2012-12-18 14:30:41 +00008555//===----------------------------------------------------------------------===//
8556// Attribute introspection.
8557//===----------------------------------------------------------------------===//
8558
Guy Benyei11169dd2012-12-18 14:30:41 +00008559CXType clang_getIBOutletCollectionType(CXCursor C) {
8560 if (C.kind != CXCursor_IBOutletCollectionAttr)
8561 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008562
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008563 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008564 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8565
8566 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008567}
Guy Benyei11169dd2012-12-18 14:30:41 +00008568
8569//===----------------------------------------------------------------------===//
8570// Inspecting memory usage.
8571//===----------------------------------------------------------------------===//
8572
8573typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8574
8575static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008576 enum CXTUResourceUsageKind k,
8577 unsigned long amount) {
8578 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008579 entries.push_back(entry);
8580}
8581
Guy Benyei11169dd2012-12-18 14:30:41 +00008582const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8583 const char *str = "";
8584 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008585 case CXTUResourceUsage_AST:
8586 str = "ASTContext: expressions, declarations, and types";
8587 break;
8588 case CXTUResourceUsage_Identifiers:
8589 str = "ASTContext: identifiers";
8590 break;
8591 case CXTUResourceUsage_Selectors:
8592 str = "ASTContext: selectors";
8593 break;
8594 case CXTUResourceUsage_GlobalCompletionResults:
8595 str = "Code completion: cached global results";
8596 break;
8597 case CXTUResourceUsage_SourceManagerContentCache:
8598 str = "SourceManager: content cache allocator";
8599 break;
8600 case CXTUResourceUsage_AST_SideTables:
8601 str = "ASTContext: side tables";
8602 break;
8603 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8604 str = "SourceManager: malloc'ed memory buffers";
8605 break;
8606 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8607 str = "SourceManager: mmap'ed memory buffers";
8608 break;
8609 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8610 str = "ExternalASTSource: malloc'ed memory buffers";
8611 break;
8612 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8613 str = "ExternalASTSource: mmap'ed memory buffers";
8614 break;
8615 case CXTUResourceUsage_Preprocessor:
8616 str = "Preprocessor: malloc'ed memory";
8617 break;
8618 case CXTUResourceUsage_PreprocessingRecord:
8619 str = "Preprocessor: PreprocessingRecord";
8620 break;
8621 case CXTUResourceUsage_SourceManager_DataStructures:
8622 str = "SourceManager: data structures and tables";
8623 break;
8624 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8625 str = "Preprocessor: header search tables";
8626 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008627 }
8628 return str;
8629}
8630
8631CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008632 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008633 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008634 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008635 return usage;
8636 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008637
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008638 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008639 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008640 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008641
Guy Benyei11169dd2012-12-18 14:30:41 +00008642 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008643 createCXTUResourceUsageEntry(
8644 *entries, CXTUResourceUsage_AST,
8645 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008646
8647 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008648 createCXTUResourceUsageEntry(
8649 *entries, CXTUResourceUsage_Identifiers,
8650 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008651
8652 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008653 createCXTUResourceUsageEntry(
8654 *entries, CXTUResourceUsage_Selectors,
8655 (unsigned long)astContext.Selectors.getTotalMemory());
8656
Guy Benyei11169dd2012-12-18 14:30:41 +00008657 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008658 createCXTUResourceUsageEntry(
8659 *entries, CXTUResourceUsage_AST_SideTables,
8660 (unsigned long)astContext.getSideTableAllocatedMemory());
8661
Guy Benyei11169dd2012-12-18 14:30:41 +00008662 // How much memory is used for caching global code completion results?
8663 unsigned long completionBytes = 0;
8664 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008665 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008666 completionBytes = completionAllocator->getTotalMemory();
8667 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008668 createCXTUResourceUsageEntry(
8669 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8670
Guy Benyei11169dd2012-12-18 14:30:41 +00008671 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008672 createCXTUResourceUsageEntry(
8673 *entries, CXTUResourceUsage_SourceManagerContentCache,
8674 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8675
Guy Benyei11169dd2012-12-18 14:30:41 +00008676 // How much memory is being used by the MemoryBuffer's in SourceManager?
8677 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008678 astUnit->getSourceManager().getMemoryBufferSizes();
8679
Guy Benyei11169dd2012-12-18 14:30:41 +00008680 createCXTUResourceUsageEntry(*entries,
8681 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008682 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008683 createCXTUResourceUsageEntry(*entries,
8684 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008685 (unsigned long)srcBufs.mmap_bytes);
8686 createCXTUResourceUsageEntry(
8687 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8688 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8689
Guy Benyei11169dd2012-12-18 14:30:41 +00008690 // How much memory is being used by the ExternalASTSource?
8691 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8692 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008693 esrc->getMemoryBufferSizes();
8694
8695 createCXTUResourceUsageEntry(
8696 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8697 (unsigned long)sizes.malloc_bytes);
8698 createCXTUResourceUsageEntry(
8699 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8700 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008701 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008702
Guy Benyei11169dd2012-12-18 14:30:41 +00008703 // How much memory is being used by the Preprocessor?
8704 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008705 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008706 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008707
Guy Benyei11169dd2012-12-18 14:30:41 +00008708 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8709 createCXTUResourceUsageEntry(*entries,
8710 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008711 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008712 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008713
Guy Benyei11169dd2012-12-18 14:30:41 +00008714 createCXTUResourceUsageEntry(*entries,
8715 CXTUResourceUsage_Preprocessor_HeaderSearch,
8716 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008717
Michael Kruse7520cf02020-03-25 09:26:14 -05008718 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8719 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008720 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008721 return usage;
8722}
8723
8724void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8725 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008726 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008727}
8728
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008729CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8730 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008731 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008732 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008733
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008734 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008735 LOG_BAD_TU(TU);
8736 return skipped;
8737 }
8738
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008739 if (!file)
8740 return skipped;
8741
8742 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008743 PreprocessingRecord *ppRec =
8744 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008745 if (!ppRec)
8746 return skipped;
8747
8748 ASTContext &Ctx = astUnit->getASTContext();
8749 SourceManager &sm = Ctx.getSourceManager();
8750 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8751 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008752 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008753
8754 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8755 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008756 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8757 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008758 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008759 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8760 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008761 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008762 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8763 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008764 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008765 }
8766
8767 skipped->count = wantedRanges.size();
8768 skipped->ranges = new CXSourceRange[skipped->count];
8769 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8770 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8771
8772 return skipped;
8773}
8774
Cameron Desrochersd8091282016-08-18 15:43:55 +00008775CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8776 CXSourceRangeList *skipped = new CXSourceRangeList;
8777 skipped->count = 0;
8778 skipped->ranges = nullptr;
8779
8780 if (isNotUsableTU(TU)) {
8781 LOG_BAD_TU(TU);
8782 return skipped;
8783 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008784
Cameron Desrochersd8091282016-08-18 15:43:55 +00008785 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008786 PreprocessingRecord *ppRec =
8787 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008788 if (!ppRec)
8789 return skipped;
8790
8791 ASTContext &Ctx = astUnit->getASTContext();
8792
8793 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8794
8795 skipped->count = SkippedRanges.size();
8796 skipped->ranges = new CXSourceRange[skipped->count];
8797 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8798 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8799
8800 return skipped;
8801}
8802
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008803void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8804 if (ranges) {
8805 delete[] ranges->ranges;
8806 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008807 }
8808}
8809
Guy Benyei11169dd2012-12-18 14:30:41 +00008810void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8811 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8812 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008813 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008814 clang_getTUResourceUsageName(Usage.entries[I].kind),
8815 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008816
Guy Benyei11169dd2012-12-18 14:30:41 +00008817 clang_disposeCXTUResourceUsage(Usage);
8818}
8819
8820//===----------------------------------------------------------------------===//
8821// Misc. utility functions.
8822//===----------------------------------------------------------------------===//
8823
Richard Smith0a7b2972018-07-03 21:34:13 +00008824/// Default to using our desired 8 MB stack size on "safety" threads.
8825static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008826
8827namespace clang {
8828
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008829bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008830 unsigned Size) {
8831 if (!Size)
8832 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008833 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008834 return CRC.RunSafelyOnThread(Fn, Size);
8835 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008836}
8837
Michael Kruse7520cf02020-03-25 09:26:14 -05008838unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008839
Michael Kruse7520cf02020-03-25 09:26:14 -05008840void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008841
Michael Kruse7520cf02020-03-25 09:26:14 -05008842} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008843
8844void clang::setThreadBackgroundPriority() {
8845 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8846 return;
8847
Nico Weber18cfd9f2019-04-21 19:18:41 +00008848#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008849 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008850#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008851}
8852
8853void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8854 if (!Unit)
8855 return;
8856
Michael Kruse7520cf02020-03-25 09:26:14 -05008857 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8858 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008859 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008860 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008861 CXString Msg =
8862 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008863 fprintf(stderr, "%s\n", clang_getCString(Msg));
8864 clang_disposeString(Msg);
8865 }
Nico Weber1865df42018-04-27 19:11:14 +00008866#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008867 // On Windows, force a flush, since there may be multiple copies of
8868 // stderr and stdout in the file system, all with different buffers
8869 // but writing to the same device.
8870 fflush(stderr);
8871#endif
8872}
8873
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008874MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8875 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008876 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008877 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008878 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008879 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008880 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008881
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008882 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008883 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008884 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008885 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008886 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8887 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008888 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8889 return Def.getMacroInfo();
8890 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008891 }
8892
Craig Topper69186e72014-06-08 08:38:04 +00008893 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008894}
8895
Richard Smith66a81862015-05-04 02:25:31 +00008896const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008897 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008898 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008899 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008900 const IdentifierInfo *II = MacroDef->getName();
8901 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008902 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008903
8904 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8905}
8906
Richard Smith66a81862015-05-04 02:25:31 +00008907MacroDefinitionRecord *
8908cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8909 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008910 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008911 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008912 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008913 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008914
8915 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008916 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008917 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8918 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008919 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008920
8921 // Check that the token is inside the definition and not its argument list.
8922 SourceManager &SM = Unit->getSourceManager();
8923 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008924 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008925 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00008926 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008927
8928 Preprocessor &PP = Unit->getPreprocessor();
8929 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
8930 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00008931 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008932
Alp Toker2d57cea2014-05-17 04:53:25 +00008933 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008934 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008935 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008936
8937 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00008938 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00008939 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008940
Richard Smith20e883e2015-04-29 23:20:19 +00008941 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00008942 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00008943 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008944
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008945 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008946}
8947
Richard Smith66a81862015-05-04 02:25:31 +00008948MacroDefinitionRecord *
8949cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
8950 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008951 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008952 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008953
8954 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008955 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008956 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008957 Preprocessor &PP = Unit->getPreprocessor();
8958 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00008959 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008960 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
8961 Token Tok;
8962 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00008963 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008964
8965 return checkForMacroInMacroDefinition(MI, Tok, TU);
8966}
8967
Guy Benyei11169dd2012-12-18 14:30:41 +00008968CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008969 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00008970}
8971
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008972Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
8973 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008974 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008975 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00008976 if (Unit->isMainFileAST())
8977 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008978 return *this;
8979 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00008980 } else {
8981 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008982 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008983 return *this;
8984}
8985
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00008986Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
8987 *this << FE->getName();
8988 return *this;
8989}
8990
8991Logger &cxindex::Logger::operator<<(CXCursor cursor) {
8992 CXString cursorName = clang_getCursorDisplayName(cursor);
8993 *this << cursorName << "@" << clang_getCursorLocation(cursor);
8994 clang_disposeString(cursorName);
8995 return *this;
8996}
8997
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008998Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
8999 CXFile File;
9000 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00009001 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009002 CXString FileName = clang_getFileName(File);
9003 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
9004 clang_disposeString(FileName);
9005 return *this;
9006}
9007
9008Logger &cxindex::Logger::operator<<(CXSourceRange range) {
9009 CXSourceLocation BLoc = clang_getRangeStart(range);
9010 CXSourceLocation ELoc = clang_getRangeEnd(range);
9011
9012 CXFile BFile;
9013 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009014 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009015
9016 CXFile EFile;
9017 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009018 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009019
9020 CXString BFileName = clang_getFileName(BFile);
9021 if (BFile == EFile) {
9022 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05009023 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009024 } else {
9025 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009026 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9027 BColumn)
9028 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9029 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009030 clang_disposeString(EFileName);
9031 }
9032 clang_disposeString(BFileName);
9033 return *this;
9034}
9035
9036Logger &cxindex::Logger::operator<<(CXString Str) {
9037 *this << clang_getCString(Str);
9038 return *this;
9039}
9040
9041Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9042 LogOS << Fmt;
9043 return *this;
9044}
9045
Benjamin Kramer762bc332019-08-07 14:44:40 +00009046static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009047
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009048cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009049 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009050
9051 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9052
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009053 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009054 OS << "[libclang:" << Name << ':';
9055
Alp Toker1a86ad22014-07-06 06:24:00 +00009056#ifdef USE_DARWIN_THREADS
9057 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009058 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9059 OS << tid << ':';
9060#endif
9061
9062 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9063 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009064 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009065
9066 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009067 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009068 OS << "--------------------------------------------------\n";
9069 }
9070}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009071
9072#ifdef CLANG_TOOL_EXTRA_BUILD
9073// This anchor is used to force the linker to link the clang-tidy plugin.
9074extern volatile int ClangTidyPluginAnchorSource;
9075static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9076 ClangTidyPluginAnchorSource;
9077
9078// This anchor is used to force the linker to link the clang-include-fixer
9079// plugin.
9080extern volatile int ClangIncludeFixerPluginAnchorSource;
9081static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9082 ClangIncludeFixerPluginAnchorSource;
9083#endif