blob: fc9d8db62b2d762644b3d089e6390d1d20295b09 [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"
Jan Korous7e36ecd2019-09-05 20:33:52 +000025#include "clang/AST/Mangle.h"
Alexey Bataev95598342020-02-10 15:49:05 -050026#include "clang/AST/OpenMPClause.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000027#include "clang/AST/StmtVisitor.h"
28#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000029#include "clang/Basic/DiagnosticCategories.h"
30#include "clang/Basic/DiagnosticIDs.h"
Richard Smith0a7b2972018-07-03 21:34:13 +000031#include "clang/Basic/Stack.h"
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +000032#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000033#include "clang/Basic/Version.h"
34#include "clang/Frontend/ASTUnit.h"
35#include "clang/Frontend/CompilerInstance.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000036#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000037#include "clang/Lex/HeaderSearch.h"
38#include "clang/Lex/Lexer.h"
39#include "clang/Lex/PreprocessingRecord.h"
40#include "clang/Lex/Preprocessor.h"
41#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000045#include "llvm/Support/Compiler.h"
46#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000047#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000048#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/MemoryBuffer.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000050#include "llvm/Support/Program.h"
51#include "llvm/Support/SaveAndRestore.h"
52#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000053#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000054#include "llvm/Support/Threading.h"
55#include "llvm/Support/Timer.h"
56#include "llvm/Support/raw_ostream.h"
Benjamin Kramer762bc332019-08-07 14:44:40 +000057#include <mutex>
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000058
Alp Toker1a86ad22014-07-06 06:24:00 +000059#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
60#define USE_DARWIN_THREADS
61#endif
62
63#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000064#include <pthread.h>
65#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000066
67using namespace clang;
68using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000069using namespace clang::cxtu;
70using namespace clang::cxindex;
71
David Blaikieea4395e2017-01-06 19:49:01 +000072CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,
73 std::unique_ptr<ASTUnit> AU) {
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
David Blaikieea4395e2017-01-06 19:49:01 +000079 D->TheASTUnit = AU.release();
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Alex Lorenz690f0e22017-12-07 20:37:50 +000084 D->ParsingOptions = 0;
85 D->Arguments = {};
Guy Benyei11169dd2012-12-18 14:30:41 +000086 return D;
87}
88
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000089bool cxtu::isASTReadError(ASTUnit *AU) {
90 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
91 DEnd = AU->stored_diag_end();
92 D != DEnd; ++D) {
93 if (D->getLevel() >= DiagnosticsEngine::Error &&
94 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
95 diag::DiagCat_AST_Deserialization_Issue)
96 return true;
97 }
98 return false;
99}
100
Guy Benyei11169dd2012-12-18 14:30:41 +0000101cxtu::CXTUOwner::~CXTUOwner() {
102 if (TU)
103 clang_disposeTranslationUnit(TU);
104}
105
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000106/// Compare two source ranges to determine their relative position in
Guy Benyei11169dd2012-12-18 14:30:41 +0000107/// the translation unit.
Michael Kruse7520cf02020-03-25 09:26:14 -0500108static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1,
Guy Benyei11169dd2012-12-18 14:30:41 +0000109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000121/// Determine if a source location falls within, before, or after a
Guy Benyei11169dd2012-12-18 14:30:41 +0000122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000136/// Translate a Clang source range into a CIndex source range.
Guy Benyei11169dd2012-12-18 14:30:41 +0000137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
Richard Smithb5f81712018-04-30 05:25:48 +0000148 bool IsTokenRange = R.isTokenRange();
Michael Kruse7520cf02020-03-25 09:26:14 -0500149 if (EndLoc.isValid() && EndLoc.isMacroID() &&
150 !SM.isMacroArgExpansion(EndLoc)) {
Richard Smithb5f81712018-04-30 05:25:48 +0000151 CharSourceRange Expansion = SM.getExpansionRange(EndLoc);
152 EndLoc = Expansion.getEnd();
153 IsTokenRange = Expansion.isTokenRange();
154 }
155 if (IsTokenRange && EndLoc.isValid()) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500156 unsigned Length =
157 Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);
Guy Benyei11169dd2012-12-18 14:30:41 +0000158 EndLoc = EndLoc.getLocWithOffset(Length);
159 }
160
Bill Wendlingeade3622013-01-23 08:25:41 +0000161 CXSourceRange Result = {
Michael Kruse7520cf02020-03-25 09:26:14 -0500162 {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};
Guy Benyei11169dd2012-12-18 14:30:41 +0000163 return Result;
164}
165
166//===----------------------------------------------------------------------===//
167// Cursor visitor.
168//===----------------------------------------------------------------------===//
169
170static SourceRange getRawCursorExtent(CXCursor C);
171static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
172
Guy Benyei11169dd2012-12-18 14:30:41 +0000173RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
174 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
175}
176
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000177/// Visit the given cursor and, if requested by the visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +0000178/// its children.
179///
180/// \param Cursor the cursor to visit.
181///
182/// \param CheckedRegionOfInterest if true, then the caller already checked
183/// that this cursor is within the region of interest.
184///
185/// \returns true if the visitation should be aborted, false if it
186/// should continue.
187bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
188 if (clang_isInvalid(Cursor.kind))
189 return false;
190
191 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000192 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000193 if (!D) {
194 assert(0 && "Invalid declaration cursor");
195 return true; // abort.
196 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500197
Guy Benyei11169dd2012-12-18 14:30:41 +0000198 // Ignore implicit declarations, unless it's an objc method because
199 // currently we should report implicit methods for properties when indexing.
200 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
201 return false;
202 }
203
204 // If we have a range of interest, and this cursor doesn't intersect with it,
205 // we're done.
206 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
207 SourceRange Range = getRawCursorExtent(Cursor);
208 if (Range.isInvalid() || CompareRegionOfInterest(Range))
209 return false;
210 }
211
212 switch (Visitor(Cursor, Parent, ClientData)) {
213 case CXChildVisit_Break:
214 return true;
215
216 case CXChildVisit_Continue:
217 return false;
218
219 case CXChildVisit_Recurse: {
220 bool ret = VisitChildren(Cursor);
221 if (PostChildrenVisitor)
222 if (PostChildrenVisitor(Cursor, ClientData))
223 return true;
224 return ret;
225 }
226 }
227
228 llvm_unreachable("Invalid CXChildVisitResult!");
229}
230
231static bool visitPreprocessedEntitiesInRange(SourceRange R,
232 PreprocessingRecord &PPRec,
233 CursorVisitor &Visitor) {
234 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
235 FileID FID;
Michael Kruse7520cf02020-03-25 09:26:14 -0500236
Guy Benyei11169dd2012-12-18 14:30:41 +0000237 if (!Visitor.shouldVisitIncludedEntities()) {
238 // If the begin/end of the range lie in the same FileID, do the optimization
Michael Kruse7520cf02020-03-25 09:26:14 -0500239 // where we skip preprocessed entities that do not come from the same
240 // FileID.
Guy Benyei11169dd2012-12-18 14:30:41 +0000241 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
242 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
243 FID = FileID();
244 }
245
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000246 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
247 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000248 PPRec, FID);
249}
250
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000252 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000253 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000254
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000255 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000256 SourceManager &SM = Unit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -0500257
258 std::pair<FileID, unsigned> Begin = SM.getDecomposedLoc(
259 SM.getFileLoc(RegionOfInterest.getBegin())),
260 End = SM.getDecomposedLoc(
261 SM.getFileLoc(RegionOfInterest.getEnd()));
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 if (End.first != Begin.first) {
264 // If the end does not reside in the same file, try to recover by
265 // picking the end of the file of begin location.
266 End.first = Begin.first;
267 End.second = SM.getFileIDSize(Begin.first);
268 }
269
270 assert(Begin.first == End.first);
271 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000272 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -0500273
Guy Benyei11169dd2012-12-18 14:30:41 +0000274 FileID File = Begin.first;
275 unsigned Offset = Begin.second;
276 unsigned Length = End.second - Begin.second;
277
278 if (!VisitDeclsOnly && !VisitPreprocessorLast)
279 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000282 if (visitDeclsFromFileRegion(File, Offset, Length))
283 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000284
285 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000286 return visitPreprocessedEntitiesInRegion();
287
288 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000289}
290
291static bool isInLexicalContext(Decl *D, DeclContext *DC) {
292 if (!DC)
293 return false;
294
Michael Kruse7520cf02020-03-25 09:26:14 -0500295 for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;
296 DeclDC = DeclDC->getLexicalParent()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000297 if (DeclDC == DC)
298 return true;
299 }
300 return false;
301}
302
Michael Kruse7520cf02020-03-25 09:26:14 -0500303bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,
304 unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000305 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000306 SourceManager &SM = Unit->getSourceManager();
307 SourceRange Range = RegionOfInterest;
308
309 SmallVector<Decl *, 16> Decls;
310 Unit->findFileRegionDecls(File, Offset, Length, Decls);
311
312 // If we didn't find any file level decls for the file, try looking at the
313 // file that it was included from.
314 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
315 bool Invalid = false;
316 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
317 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000318 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000319
320 SourceLocation Outer;
321 if (SLEntry.isFile())
322 Outer = SLEntry.getFile().getIncludeLoc();
323 else
324 Outer = SLEntry.getExpansion().getExpansionLocStart();
325 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000326 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000327
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000328 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000329 Length = 0;
330 Unit->findFileRegionDecls(File, Offset, Length, Decls);
331 }
332
333 assert(!Decls.empty());
334
335 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000336 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000337 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
338 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000339 Decl *D = *DIt;
340 if (D->getSourceRange().isInvalid())
341 continue;
342
343 if (isInLexicalContext(D, CurDC))
344 continue;
345
346 CurDC = dyn_cast<DeclContext>(D);
347
348 if (TagDecl *TD = dyn_cast<TagDecl>(D))
349 if (!TD->isFreeStanding())
350 continue;
351
Michael Kruse7520cf02020-03-25 09:26:14 -0500352 RangeComparisonResult CompRes =
353 RangeCompare(SM, D->getSourceRange(), Range);
Guy Benyei11169dd2012-12-18 14:30:41 +0000354 if (CompRes == RangeBefore)
355 continue;
356 if (CompRes == RangeAfter)
357 break;
358
359 assert(CompRes == RangeOverlap);
360 VisitedAtLeastOnce = true;
361
362 if (isa<ObjCContainerDecl>(D)) {
363 FileDI_current = &DIt;
364 FileDE_current = DE;
365 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000366 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000371 }
372
373 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000374 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000375
376 // No Decls overlapped with the range. Move up the lexical context until there
377 // is a context that contains the range or we reach the translation unit
378 // level.
Michael Kruse7520cf02020-03-25 09:26:14 -0500379 DeclContext *DC = DIt == Decls.begin()
380 ? (*DIt)->getLexicalDeclContext()
381 : (*(DIt - 1))->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +0000382
383 while (DC && !DC->isTranslationUnit()) {
384 Decl *D = cast<Decl>(DC);
385 SourceRange CurDeclRange = D->getSourceRange();
386 if (CurDeclRange.isInvalid())
387 break;
388
389 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000390 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
391 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000392 }
393
394 DC = D->getLexicalDeclContext();
395 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000396
397 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000398}
399
400bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
401 if (!AU->getPreprocessor().getPreprocessingRecord())
402 return false;
403
Michael Kruse7520cf02020-03-25 09:26:14 -0500404 PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();
Guy Benyei11169dd2012-12-18 14:30:41 +0000405 SourceManager &SM = AU->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -0500406
Guy Benyei11169dd2012-12-18 14:30:41 +0000407 if (RegionOfInterest.isValid()) {
408 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
409 SourceLocation B = MappedRange.getBegin();
410 SourceLocation E = MappedRange.getEnd();
411
412 if (AU->isInPreambleFileID(B)) {
413 if (SM.isLoadedSourceLocation(E))
Michael Kruse7520cf02020-03-25 09:26:14 -0500414 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,
415 *this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000416
417 // Beginning of range lies in the preamble but it also extends beyond
418 // it into the main file. Split the range into 2 parts, one covering
419 // the preamble and another covering the main file. This allows subsequent
420 // calls to visitPreprocessedEntitiesInRange to accept a source range that
421 // lies in the same FileID, allowing it to skip preprocessed entities that
422 // do not come from the same FileID.
Michael Kruse7520cf02020-03-25 09:26:14 -0500423 bool breaked = visitPreprocessedEntitiesInRange(
424 SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);
425 if (breaked)
426 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000427 return visitPreprocessedEntitiesInRange(
Michael Kruse7520cf02020-03-25 09:26:14 -0500428 SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000429 }
430
431 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
432 }
433
Michael Kruse7520cf02020-03-25 09:26:14 -0500434 bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
435
Guy Benyei11169dd2012-12-18 14:30:41 +0000436 if (OnlyLocalDecls)
437 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
438 PPRec);
439
440 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
441}
442
Michael Kruse7520cf02020-03-25 09:26:14 -0500443template <typename InputIterator>
Guy Benyei11169dd2012-12-18 14:30:41 +0000444bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
445 InputIterator Last,
446 PreprocessingRecord &PPRec,
447 FileID FID) {
448 for (; First != Last; ++First) {
449 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
450 continue;
451
452 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000453 if (!PPE)
454 continue;
455
Guy Benyei11169dd2012-12-18 14:30:41 +0000456 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
457 if (Visit(MakeMacroExpansionCursor(ME, TU)))
458 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000459
Guy Benyei11169dd2012-12-18 14:30:41 +0000460 continue;
461 }
Richard Smith66a81862015-05-04 02:25:31 +0000462
463 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000464 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
465 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000466
Guy Benyei11169dd2012-12-18 14:30:41 +0000467 continue;
468 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500469
Guy Benyei11169dd2012-12-18 14:30:41 +0000470 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
471 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
472 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500473
Guy Benyei11169dd2012-12-18 14:30:41 +0000474 continue;
475 }
476 }
477
478 return false;
479}
480
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000481/// Visit the children of the given cursor.
Michael Kruse7520cf02020-03-25 09:26:14 -0500482///
Guy Benyei11169dd2012-12-18 14:30:41 +0000483/// \returns true if the visitation should be aborted, false if it
484/// should continue.
485bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500486 if (clang_isReference(Cursor.kind) &&
Guy Benyei11169dd2012-12-18 14:30:41 +0000487 Cursor.kind != CXCursor_CXXBaseSpecifier) {
488 // By definition, references have no children.
489 return false;
490 }
491
492 // Set the Parent field to Cursor, then back to its old value once we're
493 // done.
494 SetParentRAII SetParent(Parent, StmtParent, Cursor);
495
496 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000497 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000498 if (!D)
499 return false;
500
501 return VisitAttributes(D) || Visit(D);
502 }
503
504 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000505 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000506 return Visit(S);
507
508 return false;
509 }
510
511 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000512 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000513 return Visit(E);
514
515 return false;
516 }
517
518 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000519 CXTranslationUnit TU = getCursorTU(Cursor);
520 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -0500521
522 int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
Guy Benyei11169dd2012-12-18 14:30:41 +0000523 for (unsigned I = 0; I != 2; ++I) {
524 if (VisitOrder[I]) {
525 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
526 RegionOfInterest.isInvalid()) {
527 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -0500528 TLEnd = CXXUnit->top_level_end();
Guy Benyei11169dd2012-12-18 14:30:41 +0000529 TL != TLEnd; ++TL) {
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000530 const Optional<bool> V = handleDeclForVisitation(*TL);
531 if (!V.hasValue())
532 continue;
533 return V.getValue();
Guy Benyei11169dd2012-12-18 14:30:41 +0000534 }
535 } else if (VisitDeclContext(
Michael Kruse7520cf02020-03-25 09:26:14 -0500536 CXXUnit->getASTContext().getTranslationUnitDecl()))
Guy Benyei11169dd2012-12-18 14:30:41 +0000537 return true;
538 continue;
539 }
540
541 // Walk the preprocessing record.
542 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
543 visitPreprocessedEntitiesInRegion();
544 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500545
Guy Benyei11169dd2012-12-18 14:30:41 +0000546 return false;
547 }
548
549 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000550 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000551 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
552 return Visit(BaseTSInfo->getTypeLoc());
553 }
554 }
555 }
556
557 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000558 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -0500559 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000560 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000561 return Visit(cxcursor::MakeCursorObjCClassRef(
562 ObjT->getInterface(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000563 A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000564 }
565
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000566 // If pointing inside a macro definition, check if the token is an identifier
567 // that was ever defined as a macro. In such a case, create a "pseudo" macro
568 // expansion cursor for that token.
569 SourceLocation BeginLoc = RegionOfInterest.getBegin();
570 if (Cursor.kind == CXCursor_MacroDefinition &&
571 BeginLoc == RegionOfInterest.getEnd()) {
572 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000573 const MacroInfo *MI =
574 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000575 if (MacroDefinitionRecord *MacroDef =
576 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000577 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
578 }
579
Guy Benyei11169dd2012-12-18 14:30:41 +0000580 // Nothing to visit at the moment.
581 return false;
582}
583
584bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
585 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
586 if (Visit(TSInfo->getTypeLoc()))
Michael Kruse7520cf02020-03-25 09:26:14 -0500587 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000588
589 if (Stmt *Body = B->getBody())
590 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
591
592 return false;
593}
594
Ted Kremenek03325582013-02-21 01:29:01 +0000595Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000596 if (RegionOfInterest.isValid()) {
597 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
598 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000599 return None;
Michael Kruse7520cf02020-03-25 09:26:14 -0500600
Guy Benyei11169dd2012-12-18 14:30:41 +0000601 switch (CompareRegionOfInterest(Range)) {
602 case RangeBefore:
603 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000604 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000605
606 case RangeAfter:
607 // This declaration comes after the region of interest; we're done.
608 return false;
609
610 case RangeOverlap:
611 // This declaration overlaps the region of interest; visit it.
612 break;
613 }
614 }
615 return true;
616}
617
618bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
619 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
620
621 // FIXME: Eventually remove. This part of a hack to support proper
622 // iteration over all Decls contained lexically within an ObjC container.
Michael Kruse7520cf02020-03-25 09:26:14 -0500623 SaveAndRestore<DeclContext::decl_iterator *> DI_saved(DI_current, &I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000624 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
625
Michael Kruse7520cf02020-03-25 09:26:14 -0500626 for (; I != E; ++I) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000627 Decl *D = *I;
628 if (D->getLexicalDeclContext() != DC)
629 continue;
Adrian Prantl2073dd22019-11-04 14:28:14 -0800630 // Filter out synthesized property accessor redeclarations.
631 if (isa<ObjCImplDecl>(DC))
632 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
633 if (OMD->isSynthesizedAccessorStub())
634 continue;
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000635 const Optional<bool> V = handleDeclForVisitation(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000636 if (!V.hasValue())
637 continue;
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000638 return V.getValue();
Guy Benyei11169dd2012-12-18 14:30:41 +0000639 }
640 return false;
641}
642
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000643Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
644 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
645
646 // Ignore synthesized ivars here, otherwise if we have something like:
647 // @synthesize prop = _prop;
648 // and '_prop' is not declared, we will encounter a '_prop' ivar before
649 // encountering the 'prop' synthesize declaration and we will think that
650 // we passed the region-of-interest.
651 if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
652 if (ivarD->getSynthesize())
653 return None;
654 }
655
656 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
657 // declarations is a mismatch with the compiler semantics.
658 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
659 auto *ID = cast<ObjCInterfaceDecl>(D);
660 if (!ID->isThisDeclarationADefinition())
661 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
662
663 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
664 auto *PD = cast<ObjCProtocolDecl>(D);
665 if (!PD->isThisDeclarationADefinition())
666 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
667 }
668
669 const Optional<bool> V = shouldVisitCursor(Cursor);
670 if (!V.hasValue())
671 return None;
672 if (!V.getValue())
673 return false;
674 if (Visit(Cursor, true))
675 return true;
676 return None;
677}
678
Guy Benyei11169dd2012-12-18 14:30:41 +0000679bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
680 llvm_unreachable("Translation units are visited directly by Visit()");
681}
682
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000683bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500684 if (VisitTemplateParameters(D->getTemplateParameters()))
685 return true;
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000686
Michael Kruse7520cf02020-03-25 09:26:14 -0500687 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000688}
689
Guy Benyei11169dd2012-12-18 14:30:41 +0000690bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
691 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
692 return Visit(TSInfo->getTypeLoc());
693
694 return false;
695}
696
697bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
698 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
699 return Visit(TSInfo->getTypeLoc());
700
701 return false;
702}
703
Michael Kruse7520cf02020-03-25 09:26:14 -0500704bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }
Guy Benyei11169dd2012-12-18 14:30:41 +0000705
706bool CursorVisitor::VisitClassTemplateSpecializationDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -0500707 ClassTemplateSpecializationDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000708 bool ShouldVisitBody = false;
709 switch (D->getSpecializationKind()) {
710 case TSK_Undeclared:
711 case TSK_ImplicitInstantiation:
712 // Nothing to visit
713 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -0500714
Guy Benyei11169dd2012-12-18 14:30:41 +0000715 case TSK_ExplicitInstantiationDeclaration:
716 case TSK_ExplicitInstantiationDefinition:
717 break;
Michael Kruse7520cf02020-03-25 09:26:14 -0500718
Guy Benyei11169dd2012-12-18 14:30:41 +0000719 case TSK_ExplicitSpecialization:
720 ShouldVisitBody = true;
721 break;
722 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500723
Guy Benyei11169dd2012-12-18 14:30:41 +0000724 // Visit the template arguments used in the specialization.
725 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
726 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000727 if (TemplateSpecializationTypeLoc TSTLoc =
728 TL.getAs<TemplateSpecializationTypeLoc>()) {
729 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
730 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 return true;
732 }
733 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000734
735 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000736}
737
738bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -0500739 ClassTemplatePartialSpecializationDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000740 // FIXME: Visit the "outer" template parameter lists on the TagDecl
741 // before visiting these template parameters.
742 if (VisitTemplateParameters(D->getTemplateParameters()))
743 return true;
744
745 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000746 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
747 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
748 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000749 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
750 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500751
Guy Benyei11169dd2012-12-18 14:30:41 +0000752 return VisitCXXRecordDecl(D);
753}
754
755bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Saar Razff1e0fc2020-01-15 02:48:42 +0200756 if (const auto *TC = D->getTypeConstraint())
757 if (Visit(MakeCXCursor(TC->getImmediatelyDeclaredConstraint(), StmtParent,
758 TU, RegionOfInterest)))
759 return true;
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 // Visit the default argument.
762 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
763 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
764 if (Visit(DefArg->getTypeLoc()))
765 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500766
Guy Benyei11169dd2012-12-18 14:30:41 +0000767 return false;
768}
769
770bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
771 if (Expr *Init = D->getInitExpr())
772 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
773 return false;
774}
775
776bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000777 unsigned NumParamList = DD->getNumTemplateParameterLists();
778 for (unsigned i = 0; i < NumParamList; i++) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500779 TemplateParameterList *Params = DD->getTemplateParameterList(i);
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 if (VisitTemplateParameters(Params))
781 return true;
782 }
783
Guy Benyei11169dd2012-12-18 14:30:41 +0000784 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
785 if (Visit(TSInfo->getTypeLoc()))
786 return true;
787
788 // Visit the nested-name-specifier, if present.
789 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
790 if (VisitNestedNameSpecifierLoc(QualifierLoc))
791 return true;
792
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000793 return false;
794}
795
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000796static bool HasTrailingReturnType(FunctionDecl *ND) {
797 const QualType Ty = ND->getType();
798 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
799 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
800 return FT->hasTrailingReturn();
801 }
802
803 return false;
804}
805
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000806/// Compare two base or member initializers based on their source order.
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000807static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
808 CXXCtorInitializer *const *Y) {
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000809 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
810}
811
Guy Benyei11169dd2012-12-18 14:30:41 +0000812bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000813 unsigned NumParamList = ND->getNumTemplateParameterLists();
814 for (unsigned i = 0; i < NumParamList; i++) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500815 TemplateParameterList *Params = ND->getTemplateParameterList(i);
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000816 if (VisitTemplateParameters(Params))
817 return true;
818 }
819
Guy Benyei11169dd2012-12-18 14:30:41 +0000820 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
821 // Visit the function declaration's syntactic components in the order
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000822 // written. This requires a bit of work.
823 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
824 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000825 const bool HasTrailingRT = HasTrailingReturnType(ND);
Michael Kruse7520cf02020-03-25 09:26:14 -0500826
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000827 // If we have a function declared directly (without the use of a typedef),
828 // visit just the return type. Otherwise, just visit the function's type
829 // now.
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000830 if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
831 Visit(FTL.getReturnLoc())) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000832 (!FTL && Visit(TL)))
833 return true;
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000834
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000835 // Visit the nested-name-specifier, if present.
836 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
837 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +0000838 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500839
Guy Benyei11169dd2012-12-18 14:30:41 +0000840 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000841 if (!isa<CXXDestructorDecl>(ND))
842 if (VisitDeclarationNameInfo(ND->getNameInfo()))
843 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500844
Guy Benyei11169dd2012-12-18 14:30:41 +0000845 // FIXME: Visit explicitly-specified template arguments!
Michael Kruse7520cf02020-03-25 09:26:14 -0500846
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000847 // Visit the function parameters, if we have a function type.
848 if (FTL && VisitFunctionTypeLoc(FTL, true))
849 return true;
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000850
851 // Visit the function's trailing return type.
852 if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
853 return true;
854
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000855 // FIXME: Attributes?
856 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500857
Guy Benyei11169dd2012-12-18 14:30:41 +0000858 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
859 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
860 // Find the initializers that were written in the source.
861 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000862 for (auto *I : Constructor->inits()) {
863 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000864 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -0500865
Aaron Ballman0ad78302014-03-13 17:34:31 +0000866 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000867 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500868
Guy Benyei11169dd2012-12-18 14:30:41 +0000869 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000870 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
871 &CompareCXXCtorInitializers);
Michael Kruse7520cf02020-03-25 09:26:14 -0500872
Guy Benyei11169dd2012-12-18 14:30:41 +0000873 // Visit the initializers in source order
874 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
875 CXXCtorInitializer *Init = WrittenInits[I];
876 if (Init->isAnyMemberInitializer()) {
877 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
878 Init->getMemberLocation(), TU)))
879 return true;
880 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
881 if (Visit(TInfo->getTypeLoc()))
882 return true;
883 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500884
Guy Benyei11169dd2012-12-18 14:30:41 +0000885 // Visit the initializer value.
886 if (Expr *Initializer = Init->getInit())
887 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
888 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500889 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000890 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500891
Guy Benyei11169dd2012-12-18 14:30:41 +0000892 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
893 return true;
894 }
895
896 return false;
897}
898
899bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
900 if (VisitDeclaratorDecl(D))
901 return true;
902
903 if (Expr *BitWidth = D->getBitWidth())
904 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
905
Benjamin Kramer99f97592017-11-15 12:20:41 +0000906 if (Expr *Init = D->getInClassInitializer())
907 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
908
Guy Benyei11169dd2012-12-18 14:30:41 +0000909 return false;
910}
911
912bool CursorVisitor::VisitVarDecl(VarDecl *D) {
913 if (VisitDeclaratorDecl(D))
914 return true;
915
916 if (Expr *Init = D->getInit())
917 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
918
919 return false;
920}
921
922bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
923 if (VisitDeclaratorDecl(D))
924 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500925
Guy Benyei11169dd2012-12-18 14:30:41 +0000926 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
927 if (Expr *DefArg = D->getDefaultArgument())
928 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
Michael Kruse7520cf02020-03-25 09:26:14 -0500929
930 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000931}
932
933bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
934 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
935 // before visiting these template parameters.
936 if (VisitTemplateParameters(D->getTemplateParameters()))
937 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500938
939 auto *FD = D->getTemplatedDecl();
Jonathan Coe578ac7a2017-10-16 23:43:02 +0000940 return VisitAttributes(FD) || VisitFunctionDecl(FD);
Guy Benyei11169dd2012-12-18 14:30:41 +0000941}
942
943bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
944 // FIXME: Visit the "outer" template parameter lists on the TagDecl
945 // before visiting these template parameters.
946 if (VisitTemplateParameters(D->getTemplateParameters()))
947 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500948
949 auto *CD = D->getTemplatedDecl();
Jonathan Coe578ac7a2017-10-16 23:43:02 +0000950 return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
Guy Benyei11169dd2012-12-18 14:30:41 +0000951}
952
953bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
954 if (VisitTemplateParameters(D->getTemplateParameters()))
955 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500956
Guy Benyei11169dd2012-12-18 14:30:41 +0000957 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
958 VisitTemplateArgumentLoc(D->getDefaultArgument()))
959 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500960
Guy Benyei11169dd2012-12-18 14:30:41 +0000961 return false;
962}
963
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000964bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
965 // Visit the bound, if it's explicit.
966 if (D->hasExplicitBound()) {
967 if (auto TInfo = D->getTypeSourceInfo()) {
968 if (Visit(TInfo->getTypeLoc()))
969 return true;
970 }
971 }
972
973 return false;
974}
975
Guy Benyei11169dd2012-12-18 14:30:41 +0000976bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000977 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000978 if (Visit(TSInfo->getTypeLoc()))
979 return true;
980
David Majnemer59f77922016-06-24 04:05:48 +0000981 for (const auto *P : ND->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +0000982 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000983 return true;
984 }
985
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000986 return ND->isThisDeclarationADefinition() &&
987 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000988}
989
990template <typename DeclIt>
991static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
992 SourceManager &SM, SourceLocation EndLoc,
993 SmallVectorImpl<Decl *> &Decls) {
994 DeclIt next = *DI_current;
995 while (++next != DE_current) {
996 Decl *D_next = *next;
997 if (!D_next)
998 break;
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000999 SourceLocation L = D_next->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00001000 if (!L.isValid())
1001 break;
1002 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
1003 *DI_current = next;
1004 Decls.push_back(D_next);
1005 continue;
1006 }
1007 break;
1008 }
1009}
1010
Guy Benyei11169dd2012-12-18 14:30:41 +00001011bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
1012 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
1013 // an @implementation can lexically contain Decls that are not properly
1014 // nested in the AST. When we identify such cases, we need to retrofit
1015 // this nesting here.
1016 if (!DI_current && !FileDI_current)
1017 return VisitDeclContext(D);
1018
1019 // Scan the Decls that immediately come after the container
1020 // in the current DeclContext. If any fall within the
1021 // container's lexical region, stash them into a vector
1022 // for later processing.
1023 SmallVector<Decl *, 24> DeclsInContainer;
1024 SourceLocation EndLoc = D->getSourceRange().getEnd();
1025 SourceManager &SM = AU->getSourceManager();
1026 if (EndLoc.isValid()) {
1027 if (DI_current) {
1028 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
1029 DeclsInContainer);
1030 } else {
1031 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
1032 DeclsInContainer);
1033 }
1034 }
1035
1036 // The common case.
1037 if (DeclsInContainer.empty())
1038 return VisitDeclContext(D);
1039
1040 // Get all the Decls in the DeclContext, and sort them with the
1041 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001042 for (auto *SubDecl : D->decls()) {
1043 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001044 SubDecl->getBeginLoc().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001045 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001046 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001047 }
1048
1049 // Now sort the Decls so that they appear in lexical order.
Michael Kruse7520cf02020-03-25 09:26:14 -05001050 llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {
1051 SourceLocation L_A = A->getBeginLoc();
1052 SourceLocation L_B = B->getBeginLoc();
1053 return L_A != L_B
1054 ? SM.isBeforeInTranslationUnit(L_A, L_B)
1055 : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());
1056 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001057
1058 // Now visit the decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05001059 for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),
1060 E = DeclsInContainer.end();
1061 I != E; ++I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001062 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001063 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001064 if (!V.hasValue())
1065 continue;
1066 if (!V.getValue())
1067 return false;
1068 if (Visit(Cursor, true))
1069 return true;
1070 }
1071 return false;
1072}
1073
1074bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1075 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1076 TU)))
1077 return true;
1078
Douglas Gregore9d95f12015-07-07 03:57:35 +00001079 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1080 return true;
1081
Guy Benyei11169dd2012-12-18 14:30:41 +00001082 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1083 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001084 E = ND->protocol_end();
1085 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001086 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1087 return true;
1088
1089 return VisitObjCContainerDecl(ND);
1090}
1091
1092bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1093 if (!PID->isThisDeclarationADefinition())
1094 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001095
Guy Benyei11169dd2012-12-18 14:30:41 +00001096 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1097 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001098 E = PID->protocol_end();
1099 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001100 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101 return true;
1102
1103 return VisitObjCContainerDecl(PID);
1104}
1105
1106bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1107 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1108 return true;
1109
1110 // FIXME: This implements a workaround with @property declarations also being
1111 // installed in the DeclContext for the @interface. Eventually this code
1112 // should be removed.
1113 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1114 if (!CDecl || !CDecl->IsClassExtension())
1115 return false;
1116
1117 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1118 if (!ID)
1119 return false;
1120
1121 IdentifierInfo *PropertyId = PD->getIdentifier();
Michael Kruse7520cf02020-03-25 09:26:14 -05001122 ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
1123 cast<DeclContext>(ID), PropertyId, PD->getQueryKind());
Guy Benyei11169dd2012-12-18 14:30:41 +00001124
1125 if (!prevDecl)
1126 return false;
1127
1128 // Visit synthesized methods since they will be skipped when visiting
1129 // the @interface.
1130 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1131 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1132 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1133 return true;
1134
1135 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1136 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1137 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1138 return true;
1139
1140 return false;
1141}
1142
Douglas Gregore9d95f12015-07-07 03:57:35 +00001143bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1144 if (!typeParamList)
1145 return false;
1146
1147 for (auto *typeParam : *typeParamList) {
1148 // Visit the type parameter.
1149 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1150 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001151 }
1152
1153 return false;
1154}
1155
Guy Benyei11169dd2012-12-18 14:30:41 +00001156bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1157 if (!D->isThisDeclarationADefinition()) {
1158 // Forward declaration is treated like a reference.
1159 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1160 }
1161
Douglas Gregore9d95f12015-07-07 03:57:35 +00001162 // Objective-C type parameters.
1163 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1164 return true;
1165
Guy Benyei11169dd2012-12-18 14:30:41 +00001166 // Issue callbacks for super class.
Michael Kruse7520cf02020-03-25 09:26:14 -05001167 if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
1168 D->getSuperClass(), D->getSuperClassLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001169 return true;
1170
Douglas Gregore9d95f12015-07-07 03:57:35 +00001171 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1172 if (Visit(SuperClassTInfo->getTypeLoc()))
1173 return true;
1174
Guy Benyei11169dd2012-12-18 14:30:41 +00001175 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1176 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001177 E = D->protocol_end();
1178 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001179 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1180 return true;
1181
1182 return VisitObjCContainerDecl(D);
1183}
1184
1185bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1186 return VisitObjCContainerDecl(D);
1187}
1188
1189bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1190 // 'ID' could be null when dealing with invalid code.
1191 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1192 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1193 return true;
1194
1195 return VisitObjCImplDecl(D);
1196}
1197
1198bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1199#if 0
1200 // Issue callbacks for super class.
1201 // FIXME: No source location information!
1202 if (D->getSuperClass() &&
1203 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1204 D->getSuperClassLoc(),
1205 TU)))
1206 return true;
1207#endif
1208
1209 return VisitObjCImplDecl(D);
1210}
1211
1212bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1213 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1214 if (PD->isIvarNameSpecified())
1215 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001216
Guy Benyei11169dd2012-12-18 14:30:41 +00001217 return false;
1218}
1219
1220bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1221 return VisitDeclContext(D);
1222}
1223
1224bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1225 // Visit nested-name-specifier.
1226 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1227 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1228 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001229
1230 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001231 D->getTargetNameLoc(), TU));
1232}
1233
1234bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1235 // Visit nested-name-specifier.
1236 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1237 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1238 return true;
1239 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001240
Guy Benyei11169dd2012-12-18 14:30:41 +00001241 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1242 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001243
Guy Benyei11169dd2012-12-18 14:30:41 +00001244 return VisitDeclarationNameInfo(D->getNameInfo());
1245}
1246
1247bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1248 // Visit nested-name-specifier.
1249 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1250 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1251 return true;
1252
1253 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1254 D->getIdentLocation(), TU));
1255}
1256
1257bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1258 // Visit nested-name-specifier.
1259 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1260 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1261 return true;
1262 }
1263
1264 return VisitDeclarationNameInfo(D->getNameInfo());
1265}
1266
1267bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -05001268 UnresolvedUsingTypenameDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001269 // Visit nested-name-specifier.
1270 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1271 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1272 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001273
Guy Benyei11169dd2012-12-18 14:30:41 +00001274 return false;
1275}
1276
Olivier Goffart81978012016-06-09 16:15:55 +00001277bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
1278 if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
1279 return true;
Richard Trieuf3b77662016-09-13 01:37:01 +00001280 if (StringLiteral *Message = D->getMessage())
1281 if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
1282 return true;
Olivier Goffart81978012016-06-09 16:15:55 +00001283 return false;
1284}
1285
Olivier Goffartd211c642016-11-04 06:29:27 +00001286bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {
1287 if (NamedDecl *FriendD = D->getFriendDecl()) {
1288 if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))
1289 return true;
1290 } else if (TypeSourceInfo *TI = D->getFriendType()) {
1291 if (Visit(TI->getTypeLoc()))
1292 return true;
1293 }
1294 return false;
1295}
1296
Guy Benyei11169dd2012-12-18 14:30:41 +00001297bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1298 switch (Name.getName().getNameKind()) {
1299 case clang::DeclarationName::Identifier:
1300 case clang::DeclarationName::CXXLiteralOperatorName:
Richard Smith35845152017-02-07 01:37:30 +00001301 case clang::DeclarationName::CXXDeductionGuideName:
Guy Benyei11169dd2012-12-18 14:30:41 +00001302 case clang::DeclarationName::CXXOperatorName:
1303 case clang::DeclarationName::CXXUsingDirective:
1304 return false;
Richard Smith35845152017-02-07 01:37:30 +00001305
Guy Benyei11169dd2012-12-18 14:30:41 +00001306 case clang::DeclarationName::CXXConstructorName:
1307 case clang::DeclarationName::CXXDestructorName:
1308 case clang::DeclarationName::CXXConversionFunctionName:
1309 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1310 return Visit(TSInfo->getTypeLoc());
1311 return false;
1312
1313 case clang::DeclarationName::ObjCZeroArgSelector:
1314 case clang::DeclarationName::ObjCOneArgSelector:
1315 case clang::DeclarationName::ObjCMultiArgSelector:
1316 // FIXME: Per-identifier location info?
1317 return false;
1318 }
1319
1320 llvm_unreachable("Invalid DeclarationName::Kind!");
1321}
1322
Michael Kruse7520cf02020-03-25 09:26:14 -05001323bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
Guy Benyei11169dd2012-12-18 14:30:41 +00001324 SourceRange Range) {
1325 // FIXME: This whole routine is a hack to work around the lack of proper
1326 // source information in nested-name-specifiers (PR5791). Since we do have
1327 // a beginning source location, we can visit the first component of the
1328 // nested-name-specifier, if it's a single-token component.
1329 if (!NNS)
1330 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001331
Guy Benyei11169dd2012-12-18 14:30:41 +00001332 // Get the first component in the nested-name-specifier.
1333 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1334 NNS = Prefix;
Michael Kruse7520cf02020-03-25 09:26:14 -05001335
Guy Benyei11169dd2012-12-18 14:30:41 +00001336 switch (NNS->getKind()) {
1337 case NestedNameSpecifier::Namespace:
Michael Kruse7520cf02020-03-25 09:26:14 -05001338 return Visit(
1339 MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001340
1341 case NestedNameSpecifier::NamespaceAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05001342 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001343 Range.getBegin(), TU));
1344
1345 case NestedNameSpecifier::TypeSpec: {
1346 // If the type has a form where we know that the beginning of the source
1347 // range matches up with a reference cursor. Visit the appropriate reference
1348 // cursor.
1349 const Type *T = NNS->getAsType();
1350 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1351 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1352 if (const TagType *Tag = dyn_cast<TagType>(T))
1353 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001354 if (const TemplateSpecializationType *TST =
1355 dyn_cast<TemplateSpecializationType>(T))
Guy Benyei11169dd2012-12-18 14:30:41 +00001356 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1357 break;
1358 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001359
Guy Benyei11169dd2012-12-18 14:30:41 +00001360 case NestedNameSpecifier::TypeSpecWithTemplate:
1361 case NestedNameSpecifier::Global:
1362 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001363 case NestedNameSpecifier::Super:
Michael Kruse7520cf02020-03-25 09:26:14 -05001364 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001365 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001366
Guy Benyei11169dd2012-12-18 14:30:41 +00001367 return false;
1368}
1369
Michael Kruse7520cf02020-03-25 09:26:14 -05001370bool CursorVisitor::VisitNestedNameSpecifierLoc(
1371 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001372 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1373 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1374 Qualifiers.push_back(Qualifier);
Michael Kruse7520cf02020-03-25 09:26:14 -05001375
Guy Benyei11169dd2012-12-18 14:30:41 +00001376 while (!Qualifiers.empty()) {
1377 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1378 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1379 switch (NNS->getKind()) {
1380 case NestedNameSpecifier::Namespace:
Michael Kruse7520cf02020-03-25 09:26:14 -05001381 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1382 Q.getLocalBeginLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001383 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001384
Guy Benyei11169dd2012-12-18 14:30:41 +00001385 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001386
Guy Benyei11169dd2012-12-18 14:30:41 +00001387 case NestedNameSpecifier::NamespaceAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05001388 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1389 Q.getLocalBeginLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001390 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001391
Guy Benyei11169dd2012-12-18 14:30:41 +00001392 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001393
Guy Benyei11169dd2012-12-18 14:30:41 +00001394 case NestedNameSpecifier::TypeSpec:
1395 case NestedNameSpecifier::TypeSpecWithTemplate:
1396 if (Visit(Q.getTypeLoc()))
1397 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001398
Guy Benyei11169dd2012-12-18 14:30:41 +00001399 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001400
Guy Benyei11169dd2012-12-18 14:30:41 +00001401 case NestedNameSpecifier::Global:
1402 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001403 case NestedNameSpecifier::Super:
Michael Kruse7520cf02020-03-25 09:26:14 -05001404 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001405 }
1406 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001407
Guy Benyei11169dd2012-12-18 14:30:41 +00001408 return false;
1409}
1410
1411bool CursorVisitor::VisitTemplateParameters(
Michael Kruse7520cf02020-03-25 09:26:14 -05001412 const TemplateParameterList *Params) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001413 if (!Params)
1414 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001415
Guy Benyei11169dd2012-12-18 14:30:41 +00001416 for (TemplateParameterList::const_iterator P = Params->begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001417 PEnd = Params->end();
Guy Benyei11169dd2012-12-18 14:30:41 +00001418 P != PEnd; ++P) {
1419 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1420 return true;
1421 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001422
Guy Benyei11169dd2012-12-18 14:30:41 +00001423 return false;
1424}
1425
1426bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1427 switch (Name.getKind()) {
1428 case TemplateName::Template:
1429 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1430
1431 case TemplateName::OverloadedTemplate:
1432 // Visit the overloaded template set.
1433 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1434 return true;
1435
1436 return false;
1437
Richard Smithb23c5e82019-05-09 03:31:27 +00001438 case TemplateName::AssumedTemplate:
1439 // FIXME: Visit DeclarationName?
1440 return false;
1441
Guy Benyei11169dd2012-12-18 14:30:41 +00001442 case TemplateName::DependentTemplate:
1443 // FIXME: Visit nested-name-specifier.
1444 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001445
Guy Benyei11169dd2012-12-18 14:30:41 +00001446 case TemplateName::QualifiedTemplate:
1447 // FIXME: Visit nested-name-specifier.
1448 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001449 Name.getAsQualifiedTemplateName()->getDecl(), Loc, TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001450
1451 case TemplateName::SubstTemplateTemplateParm:
1452 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001453 Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));
1454
Guy Benyei11169dd2012-12-18 14:30:41 +00001455 case TemplateName::SubstTemplateTemplateParmPack:
1456 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001457 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
1458 TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001459 }
1460
1461 llvm_unreachable("Invalid TemplateName::Kind!");
1462}
1463
1464bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1465 switch (TAL.getArgument().getKind()) {
1466 case TemplateArgument::Null:
1467 case TemplateArgument::Integral:
1468 case TemplateArgument::Pack:
1469 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001470
Guy Benyei11169dd2012-12-18 14:30:41 +00001471 case TemplateArgument::Type:
1472 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1473 return Visit(TSInfo->getTypeLoc());
1474 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001475
Guy Benyei11169dd2012-12-18 14:30:41 +00001476 case TemplateArgument::Declaration:
1477 if (Expr *E = TAL.getSourceDeclExpression())
1478 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1479 return false;
1480
1481 case TemplateArgument::NullPtr:
1482 if (Expr *E = TAL.getSourceNullPtrExpression())
1483 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1484 return false;
1485
1486 case TemplateArgument::Expression:
1487 if (Expr *E = TAL.getSourceExpression())
1488 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1489 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001490
Guy Benyei11169dd2012-12-18 14:30:41 +00001491 case TemplateArgument::Template:
1492 case TemplateArgument::TemplateExpansion:
1493 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1494 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001495
1496 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001497 TAL.getTemplateNameLoc());
1498 }
1499
1500 llvm_unreachable("Invalid TemplateArgument::Kind!");
1501}
1502
1503bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1504 return VisitDeclContext(D);
1505}
1506
1507bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1508 return Visit(TL.getUnqualifiedLoc());
1509}
1510
1511bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1512 ASTContext &Context = AU->getASTContext();
1513
1514 // Some builtin types (such as Objective-C's "id", "sel", and
1515 // "Class") have associated declarations. Create cursors for those.
1516 QualType VisitType;
1517 switch (TL.getTypePtr()->getKind()) {
1518
1519 case BuiltinType::Void:
1520 case BuiltinType::NullPtr:
1521 case BuiltinType::Dependent:
Michael Kruse7520cf02020-03-25 09:26:14 -05001522#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
Alexey Bader954ba212016-04-08 13:40:33 +00001523 case BuiltinType::Id:
Alexey Baderb62f1442016-04-13 08:33:41 +00001524#include "clang/Basic/OpenCLImageTypes.def"
Michael Kruse7520cf02020-03-25 09:26:14 -05001525#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
Andrew Savonichev3fee3512018-11-08 11:25:41 +00001526#include "clang/Basic/OpenCLExtensionTypes.def"
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001527 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001528 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001529 case BuiltinType::OCLClkEvent:
1530 case BuiltinType::OCLQueue:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001531 case BuiltinType::OCLReserveID:
Michael Kruse7520cf02020-03-25 09:26:14 -05001532#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
Richard Sandifordeb485fb2019-08-09 08:52:54 +00001533#include "clang/Basic/AArch64SVEACLETypes.def"
Guy Benyei11169dd2012-12-18 14:30:41 +00001534#define BUILTIN_TYPE(Id, SingletonId)
1535#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1536#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1537#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1538#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1539#include "clang/AST/BuiltinTypes.def"
1540 break;
1541
1542 case BuiltinType::ObjCId:
1543 VisitType = Context.getObjCIdType();
1544 break;
1545
1546 case BuiltinType::ObjCClass:
1547 VisitType = Context.getObjCClassType();
1548 break;
1549
1550 case BuiltinType::ObjCSel:
1551 VisitType = Context.getObjCSelType();
1552 break;
1553 }
1554
1555 if (!VisitType.isNull()) {
1556 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Michael Kruse7520cf02020-03-25 09:26:14 -05001557 return Visit(
1558 MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001559 }
1560
1561 return false;
1562}
1563
1564bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1565 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1566}
1567
1568bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1569 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1570}
1571
1572bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1573 if (TL.isDefinition())
1574 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1575
1576 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1577}
1578
1579bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1580 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1581}
1582
1583bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001584 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001585}
1586
Manman Rene6be26c2016-09-13 17:25:08 +00001587bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001588 if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
Manman Rene6be26c2016-09-13 17:25:08 +00001589 return true;
1590 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1591 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1592 TU)))
1593 return true;
1594 }
1595
1596 return false;
1597}
1598
Guy Benyei11169dd2012-12-18 14:30:41 +00001599bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1600 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1601 return true;
1602
Douglas Gregore9d95f12015-07-07 03:57:35 +00001603 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1604 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1605 return true;
1606 }
1607
Guy Benyei11169dd2012-12-18 14:30:41 +00001608 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1609 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1610 TU)))
1611 return true;
1612 }
1613
1614 return false;
1615}
1616
1617bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1618 return Visit(TL.getPointeeLoc());
1619}
1620
1621bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1622 return Visit(TL.getInnerLoc());
1623}
1624
Leonard Chanc72aaf62019-05-07 03:20:17 +00001625bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
1626 return Visit(TL.getInnerLoc());
1627}
1628
Guy Benyei11169dd2012-12-18 14:30:41 +00001629bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1630 return Visit(TL.getPointeeLoc());
1631}
1632
1633bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1634 return Visit(TL.getPointeeLoc());
1635}
1636
1637bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1638 return Visit(TL.getPointeeLoc());
1639}
1640
1641bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1642 return Visit(TL.getPointeeLoc());
1643}
1644
1645bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1646 return Visit(TL.getPointeeLoc());
1647}
1648
1649bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1650 return Visit(TL.getModifiedLoc());
1651}
1652
Michael Kruse7520cf02020-03-25 09:26:14 -05001653bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
Guy Benyei11169dd2012-12-18 14:30:41 +00001654 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001655 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001656 return true;
1657
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001658 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1659 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001660 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1661 return true;
1662
1663 return false;
1664}
1665
1666bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1667 if (Visit(TL.getElementLoc()))
1668 return true;
1669
1670 if (Expr *Size = TL.getSizeExpr())
1671 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1672
1673 return false;
1674}
1675
Reid Kleckner8a365022013-06-24 17:51:48 +00001676bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1677 return Visit(TL.getOriginalLoc());
1678}
1679
Reid Kleckner0503a872013-12-05 01:23:43 +00001680bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1681 return Visit(TL.getOriginalLoc());
1682}
1683
Richard Smith600b5262017-01-26 20:40:47 +00001684bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
1685 DeducedTemplateSpecializationTypeLoc TL) {
Michael Kruse7520cf02020-03-25 09:26:14 -05001686 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Richard Smith600b5262017-01-26 20:40:47 +00001687 TL.getTemplateNameLoc()))
1688 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001689
Richard Smith600b5262017-01-26 20:40:47 +00001690 return false;
1691}
1692
Guy Benyei11169dd2012-12-18 14:30:41 +00001693bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001694 TemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001695 // Visit the template name.
Michael Kruse7520cf02020-03-25 09:26:14 -05001696 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001697 TL.getTemplateNameLoc()))
1698 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001699
Guy Benyei11169dd2012-12-18 14:30:41 +00001700 // Visit the template arguments.
1701 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1702 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1703 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001704
Guy Benyei11169dd2012-12-18 14:30:41 +00001705 return false;
1706}
1707
1708bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1709 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1710}
1711
1712bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1713 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1714 return Visit(TSInfo->getTypeLoc());
1715
1716 return false;
1717}
1718
1719bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1720 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1721 return Visit(TSInfo->getTypeLoc());
1722
1723 return false;
1724}
1725
1726bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001727 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001728}
1729
1730bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001731 DependentTemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001732 // Visit the nested-name-specifier, if there is one.
Michael Kruse7520cf02020-03-25 09:26:14 -05001733 if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001734 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001735
Guy Benyei11169dd2012-12-18 14:30:41 +00001736 // Visit the template arguments.
1737 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1738 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1739 return true;
1740
1741 return false;
1742}
1743
1744bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1745 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1746 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001747
Guy Benyei11169dd2012-12-18 14:30:41 +00001748 return Visit(TL.getNamedTypeLoc());
1749}
1750
1751bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1752 return Visit(TL.getPatternLoc());
1753}
1754
1755bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1756 if (Expr *E = TL.getUnderlyingExpr())
1757 return Visit(MakeCXCursor(E, StmtParent, TU));
1758
1759 return false;
1760}
1761
1762bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1763 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1764}
1765
1766bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1767 return Visit(TL.getValueLoc());
1768}
1769
Xiuli Pan9c14e282016-01-09 12:53:17 +00001770bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1771 return Visit(TL.getValueLoc());
1772}
1773
Michael Kruse7520cf02020-03-25 09:26:14 -05001774#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1775 bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1776 return Visit##PARENT##Loc(TL); \
1777 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001778
1779DEFAULT_TYPELOC_IMPL(Complex, Type)
1780DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1781DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1782DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1783DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
Andrew Gozillon572bbb02017-10-02 06:25:51 +00001784DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
Erich Keanef702b022018-07-13 19:46:04 +00001785DEFAULT_TYPELOC_IMPL(DependentVector, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001786DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1787DEFAULT_TYPELOC_IMPL(Vector, Type)
1788DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1789DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1790DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1791DEFAULT_TYPELOC_IMPL(Record, TagType)
1792DEFAULT_TYPELOC_IMPL(Enum, TagType)
1793DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1794DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1795DEFAULT_TYPELOC_IMPL(Auto, Type)
1796
1797bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1798 // Visit the nested-name-specifier, if present.
1799 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1800 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1801 return true;
1802
1803 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001804 for (const auto &I : D->bases()) {
1805 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001806 return true;
1807 }
1808 }
1809
1810 return VisitTagDecl(D);
1811}
1812
1813bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001814 for (const auto *I : D->attrs())
Michael Wu40ff1052018-08-03 05:20:23 +00001815 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1816 !I->isImplicit()) &&
1817 Visit(MakeCXCursor(I, D, TU)))
Michael Kruse7520cf02020-03-25 09:26:14 -05001818 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00001819
1820 return false;
1821}
1822
1823//===----------------------------------------------------------------------===//
1824// Data-recursive visitor methods.
1825//===----------------------------------------------------------------------===//
1826
1827namespace {
Michael Kruse7520cf02020-03-25 09:26:14 -05001828#define DEF_JOB(NAME, DATA, KIND) \
1829 class NAME : public VisitorJob { \
1830 public: \
1831 NAME(const DATA *d, CXCursor parent) \
1832 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1833 static bool classof(const VisitorJob *VJ) { \
1834 return VJ->getKind() == KIND; \
1835 } \
1836 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1837 };
Guy Benyei11169dd2012-12-18 14:30:41 +00001838
1839DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1840DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1841DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1842DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001843DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1844DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1845DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1846#undef DEF_JOB
1847
James Y Knight04ec5bf2015-12-24 02:59:37 +00001848class ExplicitTemplateArgsVisit : public VisitorJob {
1849public:
1850 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1851 const TemplateArgumentLoc *End, CXCursor parent)
1852 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1853 End) {}
1854 static bool classof(const VisitorJob *VJ) {
1855 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1856 }
1857 const TemplateArgumentLoc *begin() const {
1858 return static_cast<const TemplateArgumentLoc *>(data[0]);
1859 }
1860 const TemplateArgumentLoc *end() {
1861 return static_cast<const TemplateArgumentLoc *>(data[1]);
1862 }
1863};
Guy Benyei11169dd2012-12-18 14:30:41 +00001864class DeclVisit : public VisitorJob {
1865public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001866 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1867 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1868 isFirst ? (void *)1 : (void *)nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001869 static bool classof(const VisitorJob *VJ) {
1870 return VJ->getKind() == DeclVisitKind;
1871 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001873 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001874};
1875class TypeLocVisit : public VisitorJob {
1876public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001877 TypeLocVisit(TypeLoc tl, CXCursor parent)
1878 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1879 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001880
1881 static bool classof(const VisitorJob *VJ) {
1882 return VJ->getKind() == TypeLocVisitKind;
1883 }
1884
Michael Kruse7520cf02020-03-25 09:26:14 -05001885 TypeLoc get() const {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001888 }
1889};
1890
1891class LabelRefVisit : public VisitorJob {
1892public:
1893 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001894 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1895 labelLoc.getPtrEncoding()) {}
1896
Guy Benyei11169dd2012-12-18 14:30:41 +00001897 static bool classof(const VisitorJob *VJ) {
1898 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1899 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 const LabelDecl *get() const {
1901 return static_cast<const LabelDecl *>(data[0]);
1902 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001903 SourceLocation getLoc() const {
1904 return SourceLocation::getFromPtrEncoding(data[1]);
1905 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001906};
Michael Kruse7520cf02020-03-25 09:26:14 -05001907
Guy Benyei11169dd2012-12-18 14:30:41 +00001908class NestedNameSpecifierLocVisit : public VisitorJob {
1909public:
1910 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001911 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1912 Qualifier.getNestedNameSpecifier(),
1913 Qualifier.getOpaqueData()) {}
1914
Guy Benyei11169dd2012-12-18 14:30:41 +00001915 static bool classof(const VisitorJob *VJ) {
1916 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1917 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001918
Guy Benyei11169dd2012-12-18 14:30:41 +00001919 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001920 return NestedNameSpecifierLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001921 const_cast<NestedNameSpecifier *>(
1922 static_cast<const NestedNameSpecifier *>(data[0])),
1923 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001924 }
1925};
Michael Kruse7520cf02020-03-25 09:26:14 -05001926
Guy Benyei11169dd2012-12-18 14:30:41 +00001927class DeclarationNameInfoVisit : public VisitorJob {
1928public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001929 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001930 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001931 static bool classof(const VisitorJob *VJ) {
1932 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1933 }
1934 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001935 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001936 switch (S->getStmtClass()) {
1937 default:
1938 llvm_unreachable("Unhandled Stmt");
1939 case clang::Stmt::MSDependentExistsStmtClass:
1940 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1941 case Stmt::CXXDependentScopeMemberExprClass:
1942 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1943 case Stmt::DependentScopeDeclRefExprClass:
1944 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001945 case Stmt::OMPCriticalDirectiveClass:
1946 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001947 }
1948 }
1949};
1950class MemberRefVisit : public VisitorJob {
1951public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001952 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001953 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1954 L.getPtrEncoding()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001955 static bool classof(const VisitorJob *VJ) {
1956 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1957 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001958 const FieldDecl *get() const {
1959 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001960 }
1961 SourceLocation getLoc() const {
Michael Kruse7520cf02020-03-25 09:26:14 -05001962 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001963 }
1964};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001966 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001967 VisitorWorkList &WL;
1968 CXCursor Parent;
Michael Kruse7520cf02020-03-25 09:26:14 -05001969
Guy Benyei11169dd2012-12-18 14:30:41 +00001970public:
1971 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001972 : WL(wl), Parent(parent) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001973
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1975 void VisitBlockExpr(const BlockExpr *B);
1976 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1977 void VisitCompoundStmt(const CompoundStmt *S);
Michael Kruse7520cf02020-03-25 09:26:14 -05001978 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
1979 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001980 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1981 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1982 void VisitCXXNewExpr(const CXXNewExpr *E);
1983 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1984 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1985 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1986 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1987 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1988 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1989 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1990 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001991 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001992 void VisitDeclRefExpr(const DeclRefExpr *D);
1993 void VisitDeclStmt(const DeclStmt *S);
1994 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1995 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1996 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1997 void VisitForStmt(const ForStmt *FS);
1998 void VisitGotoStmt(const GotoStmt *GS);
1999 void VisitIfStmt(const IfStmt *If);
2000 void VisitInitListExpr(const InitListExpr *IE);
2001 void VisitMemberExpr(const MemberExpr *M);
2002 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2003 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2004 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2005 void VisitOverloadExpr(const OverloadExpr *E);
2006 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2007 void VisitStmt(const Stmt *S);
2008 void VisitSwitchStmt(const SwitchStmt *S);
2009 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2011 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2012 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2013 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2014 void VisitVAArgExpr(const VAArgExpr *E);
2015 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2016 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2017 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2018 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002019 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00002020 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002021 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002022 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002023 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00002024 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002025 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002026 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002027 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00002028 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002029 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002030 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002031 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
cchen47d60942019-12-05 13:43:48 -05002032 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002033 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002034 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00002035 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002036 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00002037 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002038 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002039 void
2040 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00002041 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00002042 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataevc112e942020-02-28 09:52:15 -05002043 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002044 void VisitOMPScanDirective(const OMPScanDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002045 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00002046 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002047 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00002048 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00002049 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00002050 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002051 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002052 void
2053 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00002054 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00002055 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002056 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Alexey Bataev60e51c42019-10-10 20:13:02 +00002057 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002058 void
2059 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002060 void VisitOMPParallelMasterTaskLoopDirective(
2061 const OMPParallelMasterTaskLoopDirective *D);
Alexey Bataev14a388f2019-10-25 10:27:13 -04002062 void VisitOMPParallelMasterTaskLoopSimdDirective(
2063 const OMPParallelMasterTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002064 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002065 void VisitOMPDistributeParallelForDirective(
2066 const OMPDistributeParallelForDirective *D);
Kelvin Li4a39add2016-07-05 05:00:15 +00002067 void VisitOMPDistributeParallelForSimdDirective(
2068 const OMPDistributeParallelForSimdDirective *D);
Kelvin Li787f3fc2016-07-06 04:45:38 +00002069 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
Kelvin Lia579b912016-07-14 02:54:56 +00002070 void VisitOMPTargetParallelForSimdDirective(
2071 const OMPTargetParallelForSimdDirective *D);
Kelvin Li986330c2016-07-20 22:57:10 +00002072 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
Kelvin Li02532872016-08-05 14:37:37 +00002073 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
Kelvin Li4e325f72016-10-25 12:50:55 +00002074 void VisitOMPTeamsDistributeSimdDirective(
2075 const OMPTeamsDistributeSimdDirective *D);
Kelvin Li579e41c2016-11-30 23:51:03 +00002076 void VisitOMPTeamsDistributeParallelForSimdDirective(
2077 const OMPTeamsDistributeParallelForSimdDirective *D);
Kelvin Li7ade93f2016-12-09 03:24:30 +00002078 void VisitOMPTeamsDistributeParallelForDirective(
2079 const OMPTeamsDistributeParallelForDirective *D);
Kelvin Libf594a52016-12-17 05:48:59 +00002080 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
Kelvin Li83c451e2016-12-25 04:52:54 +00002081 void VisitOMPTargetTeamsDistributeDirective(
2082 const OMPTargetTeamsDistributeDirective *D);
Kelvin Li80e8f562016-12-29 22:16:30 +00002083 void VisitOMPTargetTeamsDistributeParallelForDirective(
2084 const OMPTargetTeamsDistributeParallelForDirective *D);
Kelvin Li1851df52017-01-03 05:23:48 +00002085 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2086 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
Kelvin Lida681182017-01-10 18:08:18 +00002087 void VisitOMPTargetTeamsDistributeSimdDirective(
2088 const OMPTargetTeamsDistributeSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002089
Guy Benyei11169dd2012-12-18 14:30:41 +00002090private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002091 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002092 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00002093 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2094 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2096 void AddStmt(const Stmt *S);
2097 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002100 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002101};
Michael Kruse7520cf02020-03-25 09:26:14 -05002102} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00002103
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 // 'S' should always be non-null, since it comes from the
2106 // statement we are visiting.
2107 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2108}
2109
Michael Kruse7520cf02020-03-25 09:26:14 -05002110void EnqueueVisitor::AddNestedNameSpecifierLoc(
2111 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 if (Qualifier)
2113 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2114}
2115
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 if (S)
2118 WL.push_back(StmtVisit(S, Parent));
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 if (D)
2122 WL.push_back(DeclVisit(D, Parent, isFirst));
2123}
James Y Knight04ec5bf2015-12-24 02:59:37 +00002124void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2125 unsigned NumTemplateArgs) {
2126 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002127}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002128void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 if (D)
2130 WL.push_back(MemberRefVisit(D, L, Parent));
2131}
2132void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2133 if (TI)
2134 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002138 for (const Stmt *SubStmt : S->children()) {
2139 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 }
2141 if (size == WL.size())
2142 return;
2143 // Now reverse the entries we just added. This will match the DFS
2144 // ordering performed by the worklist.
2145 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2146 std::reverse(I, E);
2147}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002148namespace {
2149class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2150 EnqueueVisitor *Visitor;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002151 /// Process clauses with list of variables.
Michael Kruse7520cf02020-03-25 09:26:14 -05002152 template <typename T> void VisitOMPClauseList(T *Node);
2153
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002154public:
Michael Kruse7520cf02020-03-25 09:26:14 -05002155 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
Johannes Doerfert419a5592020-03-30 19:58:40 -05002156#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2157#include "llvm/Frontend/OpenMP/OMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002158 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002159 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002160};
2161
Alexey Bataev3392d762016-02-16 11:18:12 +00002162void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2163 const OMPClauseWithPreInit *C) {
2164 Visitor->AddStmt(C->getPreInitStmt());
2165}
2166
Alexey Bataev005248a2016-02-25 05:25:57 +00002167void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2168 const OMPClauseWithPostUpdate *C) {
Alexey Bataev37e594c2016-03-04 07:21:16 +00002169 VisitOMPClauseWithPreInit(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002170 Visitor->AddStmt(C->getPostUpdateExpr());
2171}
2172
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002173void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00002174 VisitOMPClauseWithPreInit(C);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002175 Visitor->AddStmt(C->getCondition());
2176}
2177
Alexey Bataev3778b602014-07-17 07:32:53 +00002178void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2179 Visitor->AddStmt(C->getCondition());
2180}
2181
Alexey Bataev568a8332014-03-06 06:15:19 +00002182void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00002183 VisitOMPClauseWithPreInit(C);
Alexey Bataev568a8332014-03-06 06:15:19 +00002184 Visitor->AddStmt(C->getNumThreads());
2185}
2186
Alexey Bataev62c87d22014-03-21 04:51:18 +00002187void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2188 Visitor->AddStmt(C->getSafelen());
2189}
2190
Alexey Bataev66b15b52015-08-21 11:14:16 +00002191void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2192 Visitor->AddStmt(C->getSimdlen());
2193}
2194
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002195void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2196 Visitor->AddStmt(C->getAllocator());
2197}
2198
Alexander Musman8bd31e62014-05-27 15:12:19 +00002199void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2200 Visitor->AddStmt(C->getNumForLoops());
2201}
2202
Michael Kruse7520cf02020-03-25 09:26:14 -05002203void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
Alexey Bataev756c1962013-09-24 03:17:45 +00002204
Michael Kruse7520cf02020-03-25 09:26:14 -05002205void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002206
Alexey Bataev56dafe82014-06-20 07:16:17 +00002207void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002208 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002209 Visitor->AddStmt(C->getChunkSize());
2210}
2211
Alexey Bataev10e775f2015-07-30 11:36:16 +00002212void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2213 Visitor->AddStmt(C->getNumForLoops());
2214}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002215
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002216void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2217 Visitor->AddStmt(C->getEventHandler());
2218}
2219
Alexey Bataev236070f2014-06-20 11:19:47 +00002220void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2221
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002222void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2223
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002224void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2225
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002226void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2227
Alexey Bataevdea47612014-07-23 07:46:59 +00002228void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2229
Alexey Bataev67a4f222014-07-23 10:25:33 +00002230void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2231
Alexey Bataev459dec02014-07-24 06:46:57 +00002232void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2233
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002234void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2235
Alexey Bataevea9166b2020-02-06 16:30:23 -05002236void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2237
Alexey Bataev04a830f2020-02-10 14:30:39 -05002238void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2239
Alexey Bataev95598342020-02-10 15:49:05 -05002240void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2241
Alexey Bataev9a8defc2020-02-11 11:10:43 -05002242void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2243
Alexey Bataev346265e2015-09-25 10:37:12 +00002244void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2245
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002246void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2247
Alexey Bataevb825de12015-12-07 10:51:44 +00002248void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2249
Alexey Bataev375437a2020-03-02 14:21:20 -05002250void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {}
2251
Kelvin Li1408f912018-09-26 04:28:39 +00002252void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2253 const OMPUnifiedAddressClause *) {}
2254
Patrick Lyster4a370b92018-10-01 13:47:43 +00002255void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2256 const OMPUnifiedSharedMemoryClause *) {}
2257
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00002258void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2259 const OMPReverseOffloadClause *) {}
2260
Patrick Lyster3fe9e392018-10-11 14:41:10 +00002261void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2262 const OMPDynamicAllocatorsClause *) {}
2263
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002264void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2265 const OMPAtomicDefaultMemOrderClause *) {}
2266
Michael Wonge710d542015-08-07 16:16:36 +00002267void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2268 Visitor->AddStmt(C->getDevice());
2269}
2270
Kelvin Li099bb8c2015-11-24 20:50:12 +00002271void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00002272 VisitOMPClauseWithPreInit(C);
Kelvin Li099bb8c2015-11-24 20:50:12 +00002273 Visitor->AddStmt(C->getNumTeams());
2274}
2275
Michael Kruse7520cf02020-03-25 09:26:14 -05002276void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2277 const OMPThreadLimitClause *C) {
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00002278 VisitOMPClauseWithPreInit(C);
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002279 Visitor->AddStmt(C->getThreadLimit());
2280}
2281
Alexey Bataeva0569352015-12-01 10:17:31 +00002282void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2283 Visitor->AddStmt(C->getPriority());
2284}
2285
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002286void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2287 Visitor->AddStmt(C->getGrainsize());
2288}
2289
Alexey Bataev382967a2015-12-08 12:06:20 +00002290void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2291 Visitor->AddStmt(C->getNumTasks());
2292}
2293
Alexey Bataev28c75412015-12-15 08:19:24 +00002294void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2295 Visitor->AddStmt(C->getHint());
2296}
2297
Michael Kruse7520cf02020-03-25 09:26:14 -05002298template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002299 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002300 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002301 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002302}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002303
Alexey Bataev06dea732020-03-20 09:41:22 -04002304void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2305 VisitOMPClauseList(C);
2306}
Alexey Bataev63828a32020-03-23 10:41:08 -04002307void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2308 VisitOMPClauseList(C);
2309}
Alexey Bataeve04483e2019-03-27 14:14:31 +00002310void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2311 VisitOMPClauseList(C);
2312 Visitor->AddStmt(C->getAllocator());
2313}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002314void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002315 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002316 for (const auto *E : C->private_copies()) {
2317 Visitor->AddStmt(E);
2318 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002319}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002320void OMPClauseEnqueue::VisitOMPFirstprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002321 const OMPFirstprivateClause *C) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002322 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002323 VisitOMPClauseWithPreInit(C);
2324 for (const auto *E : C->private_copies()) {
2325 Visitor->AddStmt(E);
2326 }
2327 for (const auto *E : C->inits()) {
2328 Visitor->AddStmt(E);
2329 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002330}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002331void OMPClauseEnqueue::VisitOMPLastprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002332 const OMPLastprivateClause *C) {
Alexander Musman1bb328c2014-06-04 13:06:39 +00002333 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002334 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002335 for (auto *E : C->private_copies()) {
2336 Visitor->AddStmt(E);
2337 }
2338 for (auto *E : C->source_exprs()) {
2339 Visitor->AddStmt(E);
2340 }
2341 for (auto *E : C->destination_exprs()) {
2342 Visitor->AddStmt(E);
2343 }
2344 for (auto *E : C->assignment_ops()) {
2345 Visitor->AddStmt(E);
2346 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002347}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002348void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002349 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002350}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002351void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2352 VisitOMPClauseList(C);
Alexey Bataev61205072016-03-02 04:57:40 +00002353 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002354 for (auto *E : C->privates()) {
2355 Visitor->AddStmt(E);
2356 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002357 for (auto *E : C->lhs_exprs()) {
2358 Visitor->AddStmt(E);
2359 }
2360 for (auto *E : C->rhs_exprs()) {
2361 Visitor->AddStmt(E);
2362 }
2363 for (auto *E : C->reduction_ops()) {
2364 Visitor->AddStmt(E);
2365 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002366}
Alexey Bataev169d96a2017-07-18 20:17:46 +00002367void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2368 const OMPTaskReductionClause *C) {
2369 VisitOMPClauseList(C);
2370 VisitOMPClauseWithPostUpdate(C);
2371 for (auto *E : C->privates()) {
2372 Visitor->AddStmt(E);
2373 }
2374 for (auto *E : C->lhs_exprs()) {
2375 Visitor->AddStmt(E);
2376 }
2377 for (auto *E : C->rhs_exprs()) {
2378 Visitor->AddStmt(E);
2379 }
2380 for (auto *E : C->reduction_ops()) {
2381 Visitor->AddStmt(E);
2382 }
2383}
Alexey Bataevfa312f32017-07-21 18:48:21 +00002384void OMPClauseEnqueue::VisitOMPInReductionClause(
2385 const OMPInReductionClause *C) {
2386 VisitOMPClauseList(C);
2387 VisitOMPClauseWithPostUpdate(C);
2388 for (auto *E : C->privates()) {
2389 Visitor->AddStmt(E);
2390 }
2391 for (auto *E : C->lhs_exprs()) {
2392 Visitor->AddStmt(E);
2393 }
2394 for (auto *E : C->rhs_exprs()) {
2395 Visitor->AddStmt(E);
2396 }
2397 for (auto *E : C->reduction_ops()) {
2398 Visitor->AddStmt(E);
2399 }
Alexey Bataev88202be2017-07-27 13:20:36 +00002400 for (auto *E : C->taskgroup_descriptors())
2401 Visitor->AddStmt(E);
Alexey Bataevfa312f32017-07-21 18:48:21 +00002402}
Alexander Musman8dba6642014-04-22 13:09:42 +00002403void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2404 VisitOMPClauseList(C);
Alexey Bataev78849fb2016-03-09 09:49:00 +00002405 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002406 for (const auto *E : C->privates()) {
2407 Visitor->AddStmt(E);
2408 }
Alexander Musman3276a272015-03-21 10:12:56 +00002409 for (const auto *E : C->inits()) {
2410 Visitor->AddStmt(E);
2411 }
2412 for (const auto *E : C->updates()) {
2413 Visitor->AddStmt(E);
2414 }
2415 for (const auto *E : C->finals()) {
2416 Visitor->AddStmt(E);
2417 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002418 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002419 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002420}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002421void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2422 VisitOMPClauseList(C);
2423 Visitor->AddStmt(C->getAlignment());
2424}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002425void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2426 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002427 for (auto *E : C->source_exprs()) {
2428 Visitor->AddStmt(E);
2429 }
2430 for (auto *E : C->destination_exprs()) {
2431 Visitor->AddStmt(E);
2432 }
2433 for (auto *E : C->assignment_ops()) {
2434 Visitor->AddStmt(E);
2435 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002436}
Michael Kruse7520cf02020-03-25 09:26:14 -05002437void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2438 const OMPCopyprivateClause *C) {
Alexey Bataevbae9a792014-06-27 10:37:06 +00002439 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002440 for (auto *E : C->source_exprs()) {
2441 Visitor->AddStmt(E);
2442 }
2443 for (auto *E : C->destination_exprs()) {
2444 Visitor->AddStmt(E);
2445 }
2446 for (auto *E : C->assignment_ops()) {
2447 Visitor->AddStmt(E);
2448 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002449}
Alexey Bataev6125da92014-07-21 11:26:11 +00002450void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2451 VisitOMPClauseList(C);
2452}
Alexey Bataevc112e942020-02-28 09:52:15 -05002453void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2454 Visitor->AddStmt(C->getDepobj());
2455}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002456void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2457 VisitOMPClauseList(C);
2458}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002459void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2460 VisitOMPClauseList(C);
2461}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002462void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2463 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002464 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002465 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002466}
Alexey Bataev3392d762016-02-16 11:18:12 +00002467void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2468 const OMPDefaultmapClause * /*C*/) {}
Samuel Antao661c0902016-05-26 17:39:58 +00002469void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2470 VisitOMPClauseList(C);
2471}
Samuel Antaoec172c62016-05-26 17:49:04 +00002472void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2473 VisitOMPClauseList(C);
2474}
Michael Kruse7520cf02020-03-25 09:26:14 -05002475void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2476 const OMPUseDevicePtrClause *C) {
Carlo Bertolli2404b172016-07-13 15:37:16 +00002477 VisitOMPClauseList(C);
2478}
Michael Kruse7520cf02020-03-25 09:26:14 -05002479void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2480 const OMPIsDevicePtrClause *C) {
Carlo Bertolli70594e92016-07-13 17:16:49 +00002481 VisitOMPClauseList(C);
2482}
Alexey Bataevb6e70842019-12-16 15:54:17 -05002483void OMPClauseEnqueue::VisitOMPNontemporalClause(
2484 const OMPNontemporalClause *C) {
2485 VisitOMPClauseList(C);
Alexey Bataev0860db92019-12-19 10:01:10 -05002486 for (const auto *E : C->private_refs())
2487 Visitor->AddStmt(E);
Alexey Bataevb6e70842019-12-16 15:54:17 -05002488}
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002489void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
Michael Kruse7520cf02020-03-25 09:26:14 -05002490} // namespace
Alexey Bataev756c1962013-09-24 03:17:45 +00002491
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002492void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2493 unsigned size = WL.size();
2494 OMPClauseEnqueue Visitor(this);
2495 Visitor.Visit(S);
2496 if (size == WL.size())
2497 return;
2498 // Now reverse the entries we just added. This will match the DFS
2499 // ordering performed by the worklist.
2500 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2501 std::reverse(I, E);
2502}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002503void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002504 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2505}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002506void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002507 AddDecl(B->getBlockDecl());
2508}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002509void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002510 EnqueueChildren(E);
2511 AddTypeLoc(E->getTypeSourceInfo());
2512}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002513void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002514 for (auto &I : llvm::reverse(S->body()))
2515 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002516}
Michael Kruse7520cf02020-03-25 09:26:14 -05002517void EnqueueVisitor::VisitMSDependentExistsStmt(
2518 const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002519 AddStmt(S->getSubStmt());
2520 AddDeclarationNameInfo(S);
2521 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2522 AddNestedNameSpecifierLoc(QualifierLoc);
2523}
2524
Michael Kruse7520cf02020-03-25 09:26:14 -05002525void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2526 const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002527 if (E->hasExplicitTemplateArgs())
2528 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002529 AddDeclarationNameInfo(E);
2530 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2531 AddNestedNameSpecifierLoc(QualifierLoc);
2532 if (!E->isImplicitAccess())
2533 AddStmt(E->getBase());
2534}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002535void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002536 // Enqueue the initializer , if any.
2537 AddStmt(E->getInitializer());
2538 // Enqueue the array size, if any.
Richard Smithb9fb1212019-05-06 03:47:15 +00002539 AddStmt(E->getArraySize().getValueOr(nullptr));
Guy Benyei11169dd2012-12-18 14:30:41 +00002540 // Enqueue the allocated type.
2541 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2542 // Enqueue the placement arguments.
2543 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002544 AddStmt(E->getPlacementArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002545}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002546void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002547 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002548 AddStmt(CE->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002549 AddStmt(CE->getCallee());
2550 AddStmt(CE->getArg(0));
2551}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002552void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002553 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002554 // Visit the name of the type being destroyed.
2555 AddTypeLoc(E->getDestroyedTypeInfo());
2556 // Visit the scope type that looks disturbingly like the nested-name-specifier
2557 // but isn't.
2558 AddTypeLoc(E->getScopeTypeInfo());
2559 // Visit the nested-name-specifier.
2560 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2561 AddNestedNameSpecifierLoc(QualifierLoc);
2562 // Visit base expression.
2563 AddStmt(E->getBase());
2564}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002565void EnqueueVisitor::VisitCXXScalarValueInitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002566 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002567 AddTypeLoc(E->getTypeSourceInfo());
2568}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002569void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002570 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002571 EnqueueChildren(E);
2572 AddTypeLoc(E->getTypeSourceInfo());
2573}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002574void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002575 EnqueueChildren(E);
2576 if (E->isTypeOperand())
2577 AddTypeLoc(E->getTypeOperandSourceInfo());
2578}
2579
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002580void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002581 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002582 EnqueueChildren(E);
2583 AddTypeLoc(E->getTypeSourceInfo());
2584}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002585void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002586 EnqueueChildren(E);
2587 if (E->isTypeOperand())
2588 AddTypeLoc(E->getTypeOperandSourceInfo());
2589}
2590
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002591void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002592 EnqueueChildren(S);
2593 AddDecl(S->getExceptionDecl());
2594}
2595
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002596void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002597 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002598 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002599 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002600}
2601
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002602void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002603 if (DR->hasExplicitTemplateArgs())
2604 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002605 WL.push_back(DeclRefExprParts(DR, Parent));
2606}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002607void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002608 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002609 if (E->hasExplicitTemplateArgs())
2610 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002611 AddDeclarationNameInfo(E);
2612 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2613}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002614void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002615 unsigned size = WL.size();
2616 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002617 for (const auto *D : S->decls()) {
2618 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002619 isFirst = false;
2620 }
2621 if (size == WL.size())
2622 return;
2623 // Now reverse the entries we just added. This will match the DFS
2624 // ordering performed by the worklist.
2625 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2626 std::reverse(I, E);
2627}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002628void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002629 AddStmt(E->getInit());
David Majnemerf7e36092016-06-23 00:15:04 +00002630 for (const DesignatedInitExpr::Designator &D :
2631 llvm::reverse(E->designators())) {
2632 if (D.isFieldDesignator()) {
2633 if (FieldDecl *Field = D.getField())
2634 AddMemberRef(Field, D.getFieldLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00002635 continue;
2636 }
David Majnemerf7e36092016-06-23 00:15:04 +00002637 if (D.isArrayDesignator()) {
2638 AddStmt(E->getArrayIndex(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002639 continue;
2640 }
David Majnemerf7e36092016-06-23 00:15:04 +00002641 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2642 AddStmt(E->getArrayRangeEnd(D));
2643 AddStmt(E->getArrayRangeStart(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002644 }
2645}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002646void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002647 EnqueueChildren(E);
2648 AddTypeLoc(E->getTypeInfoAsWritten());
2649}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002650void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002651 AddStmt(FS->getBody());
2652 AddStmt(FS->getInc());
2653 AddStmt(FS->getCond());
2654 AddDecl(FS->getConditionVariable());
2655 AddStmt(FS->getInit());
2656}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002657void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002658 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2659}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002660void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002661 AddStmt(If->getElse());
2662 AddStmt(If->getThen());
2663 AddStmt(If->getCond());
2664 AddDecl(If->getConditionVariable());
2665}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002666void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002667 // We care about the syntactic form of the initializer list, only.
2668 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2669 IE = Syntactic;
2670 EnqueueChildren(IE);
2671}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002672void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002673 WL.push_back(MemberExprParts(M, Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002674
Guy Benyei11169dd2012-12-18 14:30:41 +00002675 // If the base of the member access expression is an implicit 'this', don't
2676 // visit it.
2677 // FIXME: If we ever want to show these implicit accesses, this will be
2678 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002679 if (M->isImplicitAccess())
2680 return;
2681
2682 // Ignore base anonymous struct/union fields, otherwise they will shadow the
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00002683 // real field that we are interested in.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002684 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2685 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2686 if (FD->isAnonymousStructOrUnion()) {
2687 AddStmt(SubME->getBase());
2688 return;
2689 }
2690 }
2691 }
2692
2693 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002694}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002695void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002696 AddTypeLoc(E->getEncodedTypeSourceInfo());
2697}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002698void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002699 EnqueueChildren(M);
2700 AddTypeLoc(M->getClassReceiverTypeInfo());
2701}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002702void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002703 // Visit the components of the offsetof expression.
2704 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Michael Kruse7520cf02020-03-25 09:26:14 -05002705 const OffsetOfNode &Node = E->getComponent(I - 1);
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 switch (Node.getKind()) {
2707 case OffsetOfNode::Array:
2708 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2709 break;
2710 case OffsetOfNode::Field:
2711 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2712 break;
2713 case OffsetOfNode::Identifier:
2714 case OffsetOfNode::Base:
2715 continue;
2716 }
2717 }
2718 // Visit the type into which we're computing the offset.
2719 AddTypeLoc(E->getTypeSourceInfo());
2720}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002721void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002722 if (E->hasExplicitTemplateArgs())
2723 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002724 WL.push_back(OverloadExprParts(E, Parent));
2725}
2726void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002727 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002728 EnqueueChildren(E);
2729 if (E->isArgumentType())
2730 AddTypeLoc(E->getArgumentTypeInfo());
2731}
Michael Kruse7520cf02020-03-25 09:26:14 -05002732void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002733void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002734 AddStmt(S->getBody());
2735 AddStmt(S->getCond());
2736 AddDecl(S->getConditionVariable());
2737}
2738
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002739void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002740 AddStmt(W->getBody());
2741 AddStmt(W->getCond());
2742 AddDecl(W->getConditionVariable());
2743}
2744
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002745void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002746 for (unsigned I = E->getNumArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002747 AddTypeLoc(E->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002748}
2749
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002750void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002751 AddTypeLoc(E->getQueriedTypeSourceInfo());
2752}
2753
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002754void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002755 EnqueueChildren(E);
2756}
2757
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002758void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002759 VisitOverloadExpr(U);
2760 if (!U->isImplicitAccess())
2761 AddStmt(U->getBase());
2762}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002763void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002764 AddStmt(E->getSubExpr());
2765 AddTypeLoc(E->getWrittenTypeInfo());
2766}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002767void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002768 WL.push_back(SizeOfPackExprParts(E, Parent));
2769}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002770void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002771 // If the opaque value has a source expression, just transparently
2772 // visit that. This is useful for (e.g.) pseudo-object expressions.
2773 if (Expr *SourceExpr = E->getSourceExpr())
2774 return Visit(SourceExpr);
2775}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002776void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002777 AddStmt(E->getBody());
2778 WL.push_back(LambdaExprParts(E, Parent));
2779}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002780void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002781 // Treat the expression like its syntactic form.
2782 Visit(E->getSyntacticForm());
2783}
2784
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002785void EnqueueVisitor::VisitOMPExecutableDirective(
Michael Kruse7520cf02020-03-25 09:26:14 -05002786 const OMPExecutableDirective *D) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002787 EnqueueChildren(D);
2788 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2789 E = D->clauses().end();
2790 I != E; ++I)
2791 EnqueueChildren(*I);
2792}
2793
Alexander Musman3aaab662014-08-19 11:27:13 +00002794void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2795 VisitOMPExecutableDirective(D);
2796}
2797
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002798void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2799 VisitOMPExecutableDirective(D);
2800}
2801
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002802void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002803 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002804}
2805
Alexey Bataevf29276e2014-06-18 04:14:57 +00002806void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002807 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002808}
2809
Alexander Musmanf82886e2014-09-18 05:12:34 +00002810void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2811 VisitOMPLoopDirective(D);
2812}
2813
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002814void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2815 VisitOMPExecutableDirective(D);
2816}
2817
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002818void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2819 VisitOMPExecutableDirective(D);
2820}
2821
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002822void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2823 VisitOMPExecutableDirective(D);
2824}
2825
Alexander Musman80c22892014-07-17 08:54:58 +00002826void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2827 VisitOMPExecutableDirective(D);
2828}
2829
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002830void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2831 VisitOMPExecutableDirective(D);
2832 AddDeclarationNameInfo(D);
2833}
2834
Michael Kruse7520cf02020-03-25 09:26:14 -05002835void EnqueueVisitor::VisitOMPParallelForDirective(
2836 const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002837 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002838}
2839
Alexander Musmane4e893b2014-09-23 09:33:00 +00002840void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2841 const OMPParallelForSimdDirective *D) {
2842 VisitOMPLoopDirective(D);
2843}
2844
cchen47d60942019-12-05 13:43:48 -05002845void EnqueueVisitor::VisitOMPParallelMasterDirective(
2846 const OMPParallelMasterDirective *D) {
2847 VisitOMPExecutableDirective(D);
2848}
2849
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002850void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2851 const OMPParallelSectionsDirective *D) {
2852 VisitOMPExecutableDirective(D);
2853}
2854
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002855void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2856 VisitOMPExecutableDirective(D);
2857}
2858
Michael Kruse7520cf02020-03-25 09:26:14 -05002859void EnqueueVisitor::VisitOMPTaskyieldDirective(
2860 const OMPTaskyieldDirective *D) {
Alexey Bataev68446b72014-07-18 07:47:19 +00002861 VisitOMPExecutableDirective(D);
2862}
2863
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002864void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2865 VisitOMPExecutableDirective(D);
2866}
2867
Alexey Bataev2df347a2014-07-18 10:17:07 +00002868void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2869 VisitOMPExecutableDirective(D);
2870}
2871
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002872void EnqueueVisitor::VisitOMPTaskgroupDirective(
2873 const OMPTaskgroupDirective *D) {
2874 VisitOMPExecutableDirective(D);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00002875 if (const Expr *E = D->getReductionRef())
2876 VisitStmt(E);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002877}
2878
Alexey Bataev6125da92014-07-21 11:26:11 +00002879void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2880 VisitOMPExecutableDirective(D);
2881}
2882
Alexey Bataevc112e942020-02-28 09:52:15 -05002883void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
2884 VisitOMPExecutableDirective(D);
2885}
2886
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002887void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
2888 VisitOMPExecutableDirective(D);
2889}
2890
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002891void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2892 VisitOMPExecutableDirective(D);
2893}
2894
Alexey Bataev0162e452014-07-22 10:10:35 +00002895void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2896 VisitOMPExecutableDirective(D);
2897}
2898
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002899void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2900 VisitOMPExecutableDirective(D);
2901}
2902
Alexey Bataevc112e942020-02-28 09:52:15 -05002903void EnqueueVisitor::VisitOMPTargetDataDirective(
2904 const OMPTargetDataDirective *D) {
Michael Wong65f367f2015-07-21 13:44:28 +00002905 VisitOMPExecutableDirective(D);
2906}
2907
Samuel Antaodf67fc42016-01-19 19:15:56 +00002908void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2909 const OMPTargetEnterDataDirective *D) {
2910 VisitOMPExecutableDirective(D);
2911}
2912
Samuel Antao72590762016-01-19 20:04:50 +00002913void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2914 const OMPTargetExitDataDirective *D) {
2915 VisitOMPExecutableDirective(D);
2916}
2917
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002918void EnqueueVisitor::VisitOMPTargetParallelDirective(
2919 const OMPTargetParallelDirective *D) {
2920 VisitOMPExecutableDirective(D);
2921}
2922
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002923void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2924 const OMPTargetParallelForDirective *D) {
2925 VisitOMPLoopDirective(D);
2926}
2927
Alexey Bataev13314bf2014-10-09 04:18:56 +00002928void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2929 VisitOMPExecutableDirective(D);
2930}
2931
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002932void EnqueueVisitor::VisitOMPCancellationPointDirective(
2933 const OMPCancellationPointDirective *D) {
2934 VisitOMPExecutableDirective(D);
2935}
2936
Alexey Bataev80909872015-07-02 11:25:17 +00002937void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2938 VisitOMPExecutableDirective(D);
2939}
2940
Alexey Bataev49f6e782015-12-01 04:18:41 +00002941void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2942 VisitOMPLoopDirective(D);
2943}
2944
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002945void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2946 const OMPTaskLoopSimdDirective *D) {
2947 VisitOMPLoopDirective(D);
2948}
2949
Alexey Bataev60e51c42019-10-10 20:13:02 +00002950void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
2951 const OMPMasterTaskLoopDirective *D) {
2952 VisitOMPLoopDirective(D);
2953}
2954
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002955void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
2956 const OMPMasterTaskLoopSimdDirective *D) {
2957 VisitOMPLoopDirective(D);
2958}
2959
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002960void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
2961 const OMPParallelMasterTaskLoopDirective *D) {
2962 VisitOMPLoopDirective(D);
2963}
2964
Alexey Bataev14a388f2019-10-25 10:27:13 -04002965void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
2966 const OMPParallelMasterTaskLoopSimdDirective *D) {
2967 VisitOMPLoopDirective(D);
2968}
2969
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002970void EnqueueVisitor::VisitOMPDistributeDirective(
2971 const OMPDistributeDirective *D) {
2972 VisitOMPLoopDirective(D);
2973}
2974
Carlo Bertolli9925f152016-06-27 14:55:37 +00002975void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
2976 const OMPDistributeParallelForDirective *D) {
2977 VisitOMPLoopDirective(D);
2978}
2979
Kelvin Li4a39add2016-07-05 05:00:15 +00002980void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
2981 const OMPDistributeParallelForSimdDirective *D) {
2982 VisitOMPLoopDirective(D);
2983}
2984
Kelvin Li787f3fc2016-07-06 04:45:38 +00002985void EnqueueVisitor::VisitOMPDistributeSimdDirective(
2986 const OMPDistributeSimdDirective *D) {
2987 VisitOMPLoopDirective(D);
2988}
2989
Kelvin Lia579b912016-07-14 02:54:56 +00002990void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
2991 const OMPTargetParallelForSimdDirective *D) {
2992 VisitOMPLoopDirective(D);
2993}
2994
Kelvin Li986330c2016-07-20 22:57:10 +00002995void EnqueueVisitor::VisitOMPTargetSimdDirective(
2996 const OMPTargetSimdDirective *D) {
2997 VisitOMPLoopDirective(D);
2998}
2999
Kelvin Li02532872016-08-05 14:37:37 +00003000void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3001 const OMPTeamsDistributeDirective *D) {
3002 VisitOMPLoopDirective(D);
3003}
3004
Kelvin Li4e325f72016-10-25 12:50:55 +00003005void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3006 const OMPTeamsDistributeSimdDirective *D) {
3007 VisitOMPLoopDirective(D);
3008}
3009
Kelvin Li579e41c2016-11-30 23:51:03 +00003010void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3011 const OMPTeamsDistributeParallelForSimdDirective *D) {
3012 VisitOMPLoopDirective(D);
3013}
3014
Kelvin Li7ade93f2016-12-09 03:24:30 +00003015void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3016 const OMPTeamsDistributeParallelForDirective *D) {
3017 VisitOMPLoopDirective(D);
3018}
3019
Kelvin Libf594a52016-12-17 05:48:59 +00003020void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3021 const OMPTargetTeamsDirective *D) {
3022 VisitOMPExecutableDirective(D);
3023}
3024
Kelvin Li83c451e2016-12-25 04:52:54 +00003025void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3026 const OMPTargetTeamsDistributeDirective *D) {
3027 VisitOMPLoopDirective(D);
3028}
3029
Kelvin Li80e8f562016-12-29 22:16:30 +00003030void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3031 const OMPTargetTeamsDistributeParallelForDirective *D) {
3032 VisitOMPLoopDirective(D);
3033}
3034
Kelvin Li1851df52017-01-03 05:23:48 +00003035void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3036 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3037 VisitOMPLoopDirective(D);
3038}
3039
Kelvin Lida681182017-01-10 18:08:18 +00003040void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3041 const OMPTargetTeamsDistributeSimdDirective *D) {
3042 VisitOMPLoopDirective(D);
3043}
3044
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003045void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003046 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3047 .Visit(S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003048}
3049
3050bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3051 if (RegionOfInterest.isValid()) {
3052 SourceRange Range = getRawCursorExtent(C);
3053 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3054 return false;
3055 }
3056 return true;
3057}
3058
3059bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3060 while (!WL.empty()) {
3061 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00003062 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00003063
3064 // Set the Parent field, then back to its old value once we're done.
3065 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
Michael Kruse7520cf02020-03-25 09:26:14 -05003066
Guy Benyei11169dd2012-12-18 14:30:41 +00003067 switch (LI.getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003068 case VisitorJob::DeclVisitKind: {
3069 const Decl *D = cast<DeclVisit>(&LI)->get();
3070 if (!D)
3071 continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00003072
Michael Kruse7520cf02020-03-25 09:26:14 -05003073 // For now, perform default visitation for Decls.
3074 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3075 cast<DeclVisit>(&LI)->isFirst())))
3076 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003077
Michael Kruse7520cf02020-03-25 09:26:14 -05003078 continue;
3079 }
3080 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3081 for (const TemplateArgumentLoc &Arg :
3082 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3083 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003086 continue;
3087 }
3088 case VisitorJob::TypeLocVisitKind: {
3089 // Perform default visitation for TypeLocs.
3090 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3091 return true;
3092 continue;
3093 }
3094 case VisitorJob::LabelRefVisitKind: {
3095 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3096 if (LabelStmt *stmt = LS->getStmt()) {
3097 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3098 TU))) {
3099 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003102 continue;
3103 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003104
Michael Kruse7520cf02020-03-25 09:26:14 -05003105 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3106 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3107 if (VisitNestedNameSpecifierLoc(V->get()))
3108 return true;
3109 continue;
3110 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003111
Michael Kruse7520cf02020-03-25 09:26:14 -05003112 case VisitorJob::DeclarationNameInfoVisitKind: {
3113 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3114 return true;
3115 continue;
3116 }
3117 case VisitorJob::MemberRefVisitKind: {
3118 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3119 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3120 return true;
3121 continue;
3122 }
3123 case VisitorJob::StmtVisitKind: {
3124 const Stmt *S = cast<StmtVisit>(&LI)->get();
3125 if (!S)
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 continue;
Richard Smithba71c082013-05-16 06:20:58 +00003127
Michael Kruse7520cf02020-03-25 09:26:14 -05003128 // Update the current cursor.
3129 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3130 if (!IsInRegionOfInterest(Cursor))
3131 continue;
3132 switch (Visitor(Cursor, Parent, ClientData)) {
3133 case CXChildVisit_Break:
3134 return true;
3135 case CXChildVisit_Continue:
3136 break;
3137 case CXChildVisit_Recurse:
3138 if (PostChildrenVisitor)
3139 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3140 EnqueueWorkList(WL, S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 break;
3142 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003143 continue;
3144 }
3145 case VisitorJob::MemberExprPartsKind: {
3146 // Handle the other pieces in the MemberExpr besides the base.
3147 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00003148
Michael Kruse7520cf02020-03-25 09:26:14 -05003149 // Visit the nested-name-specifier
3150 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3151 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +00003152 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05003153
3154 // Visit the declaration name.
3155 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3156 return true;
3157
3158 // Visit the explicitly-specified template arguments, if any.
3159 if (M->hasExplicitTemplateArgs()) {
3160 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3161 *ArgEnd = Arg + M->getNumTemplateArgs();
3162 Arg != ArgEnd; ++Arg) {
3163 if (VisitTemplateArgumentLoc(*Arg))
3164 return true;
3165 }
3166 }
3167 continue;
3168 }
3169 case VisitorJob::DeclRefExprPartsKind: {
3170 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3171 // Visit nested-name-specifier, if present.
3172 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3173 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3174 return true;
3175 // Visit declaration name.
3176 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3177 return true;
3178 continue;
3179 }
3180 case VisitorJob::OverloadExprPartsKind: {
3181 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3182 // Visit the nested-name-specifier.
3183 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3185 return true;
3186 // Visit the declaration name.
3187 if (VisitDeclarationNameInfo(O->getNameInfo()))
3188 return true;
3189 // Visit the overloaded declaration reference.
3190 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3191 return true;
3192 continue;
3193 }
3194 case VisitorJob::SizeOfPackExprPartsKind: {
3195 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3196 NamedDecl *Pack = E->getPack();
3197 if (isa<TemplateTypeParmDecl>(Pack)) {
3198 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3199 E->getPackLoc(), TU)))
3200 return true;
3201
3202 continue;
3203 }
3204
3205 if (isa<TemplateTemplateParmDecl>(Pack)) {
3206 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3207 E->getPackLoc(), TU)))
3208 return true;
3209
3210 continue;
3211 }
3212
3213 // Non-type template parameter packs and function parameter packs are
3214 // treated like DeclRefExpr cursors.
3215 continue;
3216 }
3217
3218 case VisitorJob::LambdaExprPartsKind: {
3219 // Visit non-init captures.
3220 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3221 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3222 CEnd = E->explicit_capture_end();
3223 C != CEnd; ++C) {
3224 if (!C->capturesVariable())
3225 continue;
3226
3227 if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
3228 TU)))
3229 return true;
3230 }
3231 // Visit init captures
3232 for (auto InitExpr : E->capture_inits()) {
3233 if (Visit(InitExpr))
3234 return true;
3235 }
3236
3237 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3238 // Visit parameters and return type, if present.
3239 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3240 if (E->hasExplicitParameters()) {
3241 // Visit parameters.
3242 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3243 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3244 return true;
3245 }
3246 if (E->hasExplicitResultType()) {
3247 // Visit result type.
3248 if (Visit(Proto.getReturnLoc()))
3249 return true;
3250 }
3251 }
3252 break;
3253 }
3254
3255 case VisitorJob::PostChildrenVisitKind:
3256 if (PostChildrenVisitor(Parent, ClientData))
3257 return true;
3258 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 }
3260 }
3261 return false;
3262}
3263
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003264bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00003265 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 if (!WorkListFreeList.empty()) {
3267 WL = WorkListFreeList.back();
3268 WL->clear();
3269 WorkListFreeList.pop_back();
Michael Kruse7520cf02020-03-25 09:26:14 -05003270 } else {
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 WL = new VisitorWorkList();
3272 WorkListCache.push_back(WL);
3273 }
3274 EnqueueWorkList(*WL, S);
3275 bool result = RunVisitorWorkList(*WL);
3276 WorkListFreeList.push_back(WL);
3277 return result;
3278}
3279
3280namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003281typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00003282RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3283 const DeclarationNameInfo &NI, SourceRange QLoc,
3284 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3286 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3287 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
Michael Kruse7520cf02020-03-25 09:26:14 -05003288
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
Michael Kruse7520cf02020-03-25 09:26:14 -05003290
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 RefNamePieces Pieces;
3292
3293 if (WantQualifier && QLoc.isValid())
3294 Pieces.push_back(QLoc);
Michael Kruse7520cf02020-03-25 09:26:14 -05003295
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3297 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00003298
3299 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3300 Pieces.push_back(*TemplateArgsLoc);
3301
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 if (Kind == DeclarationName::CXXOperatorName) {
3303 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003304 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003306 NI.getInfo().CXXOperatorName.EndOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003308
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 if (WantSinglePiece) {
3310 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3311 Pieces.clear();
3312 Pieces.push_back(R);
Michael Kruse7520cf02020-03-25 09:26:14 -05003313 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003314
Michael Kruse7520cf02020-03-25 09:26:14 -05003315 return Pieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00003316}
Michael Kruse7520cf02020-03-25 09:26:14 -05003317} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00003318
3319//===----------------------------------------------------------------------===//
3320// Misc. API hooks.
Michael Kruse7520cf02020-03-25 09:26:14 -05003321//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00003322
Chandler Carruth66660742014-06-27 16:37:27 +00003323namespace {
3324struct RegisterFatalErrorHandler {
3325 RegisterFatalErrorHandler() {
Jan Korousf7d23762019-09-12 22:55:55 +00003326 clang_install_aborting_llvm_fatal_error_handler();
Chandler Carruth66660742014-06-27 16:37:27 +00003327 }
3328};
Michael Kruse7520cf02020-03-25 09:26:14 -05003329} // namespace
Chandler Carruth66660742014-06-27 16:37:27 +00003330
Michael Kruse7520cf02020-03-25 09:26:14 -05003331static llvm::ManagedStatic<RegisterFatalErrorHandler>
3332 RegisterFatalErrorHandlerOnce;
Chandler Carruth66660742014-06-27 16:37:27 +00003333
Guy Benyei11169dd2012-12-18 14:30:41 +00003334CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3335 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 // We use crash recovery to make some of our APIs more reliable, implicitly
3337 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003338 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3339 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003340
Chandler Carruth66660742014-06-27 16:37:27 +00003341 // Look through the managed static to trigger construction of the managed
3342 // static which registers our fatal error handler. This ensures it is only
3343 // registered once.
3344 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003345
Adrian Prantlbc068582015-07-08 01:00:30 +00003346 // Initialize targets for clang module support.
3347 llvm::InitializeAllTargets();
3348 llvm::InitializeAllTargetMCs();
3349 llvm::InitializeAllAsmPrinters();
3350 llvm::InitializeAllAsmParsers();
3351
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003352 CIndexer *CIdxr = new CIndexer();
3353
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 if (excludeDeclarationsFromPCH)
3355 CIdxr->setOnlyLocalDecls();
3356 if (displayDiagnostics)
3357 CIdxr->setDisplayDiagnostics();
3358
3359 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3360 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3361 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3362 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3363 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3364 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3365
3366 return CIdxr;
3367}
3368
3369void clang_disposeIndex(CXIndex CIdx) {
3370 if (CIdx)
3371 delete static_cast<CIndexer *>(CIdx);
3372}
3373
3374void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3375 if (CIdx)
3376 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3377}
3378
3379unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3380 if (CIdx)
3381 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3382 return 0;
3383}
3384
Alex Lorenz08615792017-12-04 21:56:36 +00003385void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
3386 const char *Path) {
3387 if (CIdx)
3388 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
3389}
3390
Guy Benyei11169dd2012-12-18 14:30:41 +00003391void clang_toggleCrashRecovery(unsigned isEnabled) {
3392 if (isEnabled)
3393 llvm::CrashRecoveryContext::Enable();
3394 else
3395 llvm::CrashRecoveryContext::Disable();
3396}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003397
Guy Benyei11169dd2012-12-18 14:30:41 +00003398CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3399 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003400 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003401 enum CXErrorCode Result =
3402 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003403 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003404 assert((TU && Result == CXError_Success) ||
3405 (!TU && Result != CXError_Success));
3406 return TU;
3407}
3408
3409enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3410 const char *ast_filename,
3411 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003412 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003413 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003414
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003415 if (!CIdx || !ast_filename || !out_TU)
3416 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003417
Michael Kruse7520cf02020-03-25 09:26:14 -05003418 LOG_FUNC_SECTION { *Log << ast_filename; }
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003419
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3421 FileSystemOptions FileSystemOpts;
3422
Justin Bognerd512c1e2014-10-15 00:33:06 +00003423 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3424 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003425 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Richard Smithdbafb6c2017-06-29 23:23:46 +00003426 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
Michael Kruse7520cf02020-03-25 09:26:14 -05003427 ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3428 CXXIdx->getOnlyLocalDecls(), None, CaptureDiagsKind::All,
David Blaikie6f7382d2014-08-10 19:08:04 +00003429 /*AllowPCHWithCompilerErrors=*/true,
3430 /*UserFilesAreVolatile=*/true);
David Blaikieea4395e2017-01-06 19:49:01 +00003431 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003432 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003433}
3434
3435unsigned clang_defaultEditingTranslationUnitOptions() {
Michael Kruse7520cf02020-03-25 09:26:14 -05003436 return CXTranslationUnit_PrecompiledPreamble |
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 CXTranslationUnit_CacheCompletionResults;
3438}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003439
Michael Kruse7520cf02020-03-25 09:26:14 -05003440CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3441 CXIndex CIdx, const char *source_filename, int num_command_line_args,
3442 const char *const *command_line_args, unsigned num_unsaved_files,
3443 struct CXUnsavedFile *unsaved_files) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003444 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
Michael Kruse7520cf02020-03-25 09:26:14 -05003445 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3446 num_command_line_args, unsaved_files,
3447 num_unsaved_files, Options);
Guy Benyei11169dd2012-12-18 14:30:41 +00003448}
3449
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003450static CXErrorCode
3451clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3452 const char *const *command_line_args,
3453 int num_command_line_args,
3454 ArrayRef<CXUnsavedFile> unsaved_files,
3455 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003456 // Set up the initial return values.
3457 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003458 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003459
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003460 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003461 if (!CIdx || !out_TU)
3462 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003463
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3465
3466 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3467 setThreadBackgroundPriority();
3468
3469 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003470 bool CreatePreambleOnFirstParse =
3471 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 // FIXME: Add a flag for modules.
Michael Kruse7520cf02020-03-25 09:26:14 -05003473 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3474 CXTranslationUnit_SingleFileParse))
3475 ? TU_Prefix
3476 : TU_Complete;
3477 bool CacheCodeCompletionResults =
3478 options & CXTranslationUnit_CacheCompletionResults;
3479 bool IncludeBriefCommentsInCodeCompletion =
3480 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003481 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
3482 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
Michael Kruse7520cf02020-03-25 09:26:14 -05003483 bool RetainExcludedCB =
3484 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
Ivan Donchevskii6e895282018-05-17 09:24:37 +00003485 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
3486 if (options & CXTranslationUnit_SkipFunctionBodies) {
3487 SkipFunctionBodies =
3488 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
3489 ? SkipFunctionBodiesScope::Preamble
3490 : SkipFunctionBodiesScope::PreambleAndMainFile;
3491 }
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003492
3493 // Configure the diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05003494 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3495 CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003496
Manuel Klimek016c0242016-03-01 10:56:19 +00003497 if (options & CXTranslationUnit_KeepGoing)
Ivan Donchevskii878271b2019-03-07 10:13:50 +00003498 Diags->setFatalsAsError(true);
Manuel Klimek016c0242016-03-01 10:56:19 +00003499
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003500 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
3501 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
3502 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
3503
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003505 llvm::CrashRecoveryContextCleanupRegistrar<
3506 DiagnosticsEngine,
3507 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
3508 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003509
Ahmed Charlesb8984322014-03-07 20:03:18 +00003510 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3511 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003512
3513 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003514 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3515 RemappedCleanup(RemappedFiles.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003516
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003517 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003518 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003519 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003520 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 }
3522
Ahmed Charlesb8984322014-03-07 20:03:18 +00003523 std::unique_ptr<std::vector<const char *>> Args(
3524 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003525
3526 // Recover resources if we crash before exiting this method.
Michael Kruse7520cf02020-03-25 09:26:14 -05003527 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
3528 ArgsCleanup(Args.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003529
3530 // Since the Clang C library is primarily used by batch tools dealing with
3531 // (often very broken) source code, where spell-checking can have a
Michael Kruse7520cf02020-03-25 09:26:14 -05003532 // significant negative impact on performance (particularly when
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 // precompiled headers are involved), we disable it by default.
3534 // Only do this if we haven't found a spell-checking-related argument.
3535 bool FoundSpellCheckingArgument = false;
3536 for (int I = 0; I != num_command_line_args; ++I) {
3537 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3538 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3539 FoundSpellCheckingArgument = true;
3540 break;
3541 }
3542 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 Args->insert(Args->end(), command_line_args,
3544 command_line_args + num_command_line_args);
3545
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003546 if (!FoundSpellCheckingArgument)
3547 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3548
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 // The 'source_filename' argument is optional. If the caller does not
3550 // specify it then it is assumed that the source file is specified
3551 // in the actual argument list.
3552 // Put the source file after command_line_args otherwise if '-x' flag is
3553 // present it will be unused.
3554 if (source_filename)
3555 Args->push_back(source_filename);
3556
3557 // Do we need the detailed preprocessing record?
3558 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3559 Args->push_back("-Xclang");
3560 Args->push_back("-detailed-preprocessing-record");
3561 }
Alex Lorenzcb006402017-04-27 13:47:03 +00003562
3563 // Suppress any editor placeholder diagnostics.
3564 Args->push_back("-fallow-editor-placeholders");
3565
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003567 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003568 // Unless the user specified that they want the preamble on the first parse
3569 // set it up to be created on the first reparse. This makes the first parse
3570 // faster, trading for a slower (first) reparse.
3571 unsigned PrecompilePreambleAfterNParses =
3572 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Alex Lorenz08615792017-12-04 21:56:36 +00003573
Alex Lorenz08615792017-12-04 21:56:36 +00003574 LibclangInvocationReporter InvocationReporter(
3575 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
Alex Lorenz690f0e22017-12-07 20:37:50 +00003576 options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
3577 unsaved_files);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003578 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003579 Args->data(), Args->data() + Args->size(),
3580 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003581 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003582 CaptureDiagnostics, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003583 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3584 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Argyrios Kyrtzidis735e92c2017-06-09 01:20:48 +00003585 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
Evgeny Mankov2ed2e622019-08-27 22:15:32 +00003586 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003587 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3588 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003589
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003590 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003591 if (!Unit && !ErrUnit)
3592 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003593
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 if (NumErrors != Diags->getClient()->getNumErrors()) {
3595 // Make sure to check that 'Unit' is non-NULL.
3596 if (CXXIdx->getDisplayDiagnostics())
3597 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3598 }
3599
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003600 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3601 return CXError_ASTReadError;
3602
David Blaikieea4395e2017-01-06 19:49:01 +00003603 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
Alex Lorenz690f0e22017-12-07 20:37:50 +00003604 if (CXTranslationUnitImpl *TU = *out_TU) {
3605 TU->ParsingOptions = options;
3606 TU->Arguments.reserve(Args->size());
3607 for (const char *Arg : *Args)
3608 TU->Arguments.push_back(Arg);
3609 return CXError_Success;
3610 }
3611 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003612}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003613
3614CXTranslationUnit
Michael Kruse7520cf02020-03-25 09:26:14 -05003615clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003616 const char *const *command_line_args,
3617 int num_command_line_args,
3618 struct CXUnsavedFile *unsaved_files,
Michael Kruse7520cf02020-03-25 09:26:14 -05003619 unsigned num_unsaved_files, unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003620 CXTranslationUnit TU;
3621 enum CXErrorCode Result = clang_parseTranslationUnit2(
3622 CIdx, source_filename, command_line_args, num_command_line_args,
3623 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003624 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003625 assert((TU && Result == CXError_Success) ||
3626 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003627 return TU;
3628}
3629
3630enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003631 CXIndex CIdx, const char *source_filename,
3632 const char *const *command_line_args, int num_command_line_args,
3633 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3634 unsigned options, CXTranslationUnit *out_TU) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003635 noteBottomOfStack();
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003636 SmallVector<const char *, 4> Args;
3637 Args.push_back("clang");
3638 Args.append(command_line_args, command_line_args + num_command_line_args);
3639 return clang_parseTranslationUnit2FullArgv(
3640 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3641 num_unsaved_files, options, out_TU);
3642}
3643
3644enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3645 CXIndex CIdx, const char *source_filename,
3646 const char *const *command_line_args, int num_command_line_args,
3647 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3648 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003649 LOG_FUNC_SECTION {
3650 *Log << source_filename << ": ";
3651 for (int i = 0; i != num_command_line_args; ++i)
3652 *Log << command_line_args[i] << " ";
3653 }
3654
Alp Toker9d85b182014-07-07 01:23:14 +00003655 if (num_unsaved_files && !unsaved_files)
3656 return CXError_InvalidArguments;
3657
Alp Toker5c532982014-07-07 22:42:03 +00003658 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003659 auto ParseTranslationUnitImpl = [=, &result] {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003660 noteBottomOfStack();
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003661 result = clang_parseTranslationUnit_Impl(
3662 CIdx, source_filename, command_line_args, num_command_line_args,
3663 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3664 };
Erik Verbruggen284848d2017-08-29 09:08:02 +00003665
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 llvm::CrashRecoveryContext CRC;
3667
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003668 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3670 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3671 fprintf(stderr, " 'command_line_args' : [");
3672 for (int i = 0; i != num_command_line_args; ++i) {
3673 if (i)
3674 fprintf(stderr, ", ");
3675 fprintf(stderr, "'%s'", command_line_args[i]);
3676 }
3677 fprintf(stderr, "],\n");
3678 fprintf(stderr, " 'unsaved_files' : [");
3679 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3680 if (i)
3681 fprintf(stderr, ", ");
3682 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3683 unsaved_files[i].Length);
3684 }
3685 fprintf(stderr, "],\n");
3686 fprintf(stderr, " 'options' : %d,\n", options);
3687 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003688
3689 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003691 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003692 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 }
Alp Toker5c532982014-07-07 22:42:03 +00003694
3695 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003696}
3697
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003698CXString clang_Type_getObjCEncoding(CXType CT) {
3699 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3700 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3701 std::string encoding;
Michael Kruse7520cf02020-03-25 09:26:14 -05003702 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003703
3704 return cxstring::createDup(encoding);
3705}
3706
3707static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3708 if (C.kind == CXCursor_MacroDefinition) {
3709 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3710 return MDR->getName();
3711 } else if (C.kind == CXCursor_MacroExpansion) {
3712 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3713 return ME.getName();
3714 }
3715 return nullptr;
3716}
3717
3718unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3719 const IdentifierInfo *II = getMacroIdentifier(C);
3720 if (!II) {
3721 return false;
3722 }
3723 ASTUnit *ASTU = getCursorASTUnit(C);
3724 Preprocessor &PP = ASTU->getPreprocessor();
3725 if (const MacroInfo *MI = PP.getMacroInfo(II))
3726 return MI->isFunctionLike();
3727 return false;
3728}
3729
3730unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3731 const IdentifierInfo *II = getMacroIdentifier(C);
3732 if (!II) {
3733 return false;
3734 }
3735 ASTUnit *ASTU = getCursorASTUnit(C);
3736 Preprocessor &PP = ASTU->getPreprocessor();
3737 if (const MacroInfo *MI = PP.getMacroInfo(II))
3738 return MI->isBuiltinMacro();
3739 return false;
3740}
3741
3742unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3743 const Decl *D = getCursorDecl(C);
3744 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3745 if (!FD) {
3746 return false;
3747 }
3748 return FD->isInlined();
3749}
3750
Michael Kruse7520cf02020-03-25 09:26:14 -05003751static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003752 if (callExpr->getNumArgs() != 1) {
3753 return nullptr;
3754 }
3755
3756 StringLiteral *S = nullptr;
3757 auto *arg = callExpr->getArg(0);
3758 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3759 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3760 auto *subExpr = I->getSubExprAsWritten();
3761
Michael Kruse7520cf02020-03-25 09:26:14 -05003762 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003763 return nullptr;
3764 }
3765
3766 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3767 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3768 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3769 } else {
3770 return nullptr;
3771 }
3772 return S;
3773}
3774
David Blaikie59272572016-04-13 18:23:33 +00003775struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003776 CXEvalResultKind EvalType;
3777 union {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003778 unsigned long long unsignedVal;
3779 long long intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003780 double floatVal;
3781 char *stringVal;
3782 } EvalData;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003783 bool IsUnsignedInt;
David Blaikie59272572016-04-13 18:23:33 +00003784 ~ExprEvalResult() {
3785 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3786 EvalType != CXEval_Int) {
Alex Lorenza19cb2e2019-01-08 23:28:37 +00003787 delete[] EvalData.stringVal;
David Blaikie59272572016-04-13 18:23:33 +00003788 }
3789 }
3790};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003791
3792void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003793 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003794}
3795
3796CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3797 if (!E) {
3798 return CXEval_UnExposed;
3799 }
3800 return ((ExprEvalResult *)E)->EvalType;
3801}
3802
3803int clang_EvalResult_getAsInt(CXEvalResult E) {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003804 return clang_EvalResult_getAsLongLong(E);
3805}
3806
3807long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003808 if (!E) {
3809 return 0;
3810 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003811 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003812 if (Result->IsUnsignedInt)
3813 return Result->EvalData.unsignedVal;
3814 return Result->EvalData.intVal;
3815}
3816
3817unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
3818 return ((ExprEvalResult *)E)->IsUnsignedInt;
3819}
3820
3821unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
3822 if (!E) {
3823 return 0;
3824 }
3825
Michael Kruse7520cf02020-03-25 09:26:14 -05003826 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003827 if (Result->IsUnsignedInt)
3828 return Result->EvalData.unsignedVal;
3829 return Result->EvalData.intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003830}
3831
3832double clang_EvalResult_getAsDouble(CXEvalResult E) {
3833 if (!E) {
3834 return 0;
3835 }
3836 return ((ExprEvalResult *)E)->EvalData.floatVal;
3837}
3838
Michael Kruse7520cf02020-03-25 09:26:14 -05003839const char *clang_EvalResult_getAsStr(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003840 if (!E) {
3841 return nullptr;
3842 }
3843 return ((ExprEvalResult *)E)->EvalData.stringVal;
3844}
3845
Michael Kruse7520cf02020-03-25 09:26:14 -05003846static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003847 Expr::EvalResult ER;
3848 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003849 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003850 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003851
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003852 expr = expr->IgnoreParens();
Emilio Cobos Alvarez74375452019-07-09 14:27:01 +00003853 if (expr->isValueDependent())
3854 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003855 if (!expr->EvaluateAsRValue(ER, ctx))
3856 return nullptr;
3857
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003858 QualType rettype;
3859 CallExpr *callExpr;
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00003860 auto result = std::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003861 result->EvalType = CXEval_UnExposed;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003862 result->IsUnsignedInt = false;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003863
David Blaikiebbc00882016-04-13 18:36:19 +00003864 if (ER.Val.isInt()) {
3865 result->EvalType = CXEval_Int;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003866
Michael Kruse7520cf02020-03-25 09:26:14 -05003867 auto &val = ER.Val.getInt();
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003868 if (val.isUnsigned()) {
3869 result->IsUnsignedInt = true;
3870 result->EvalData.unsignedVal = val.getZExtValue();
3871 } else {
3872 result->EvalData.intVal = val.getExtValue();
3873 }
3874
David Blaikiebbc00882016-04-13 18:36:19 +00003875 return result.release();
3876 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003877
David Blaikiebbc00882016-04-13 18:36:19 +00003878 if (ER.Val.isFloat()) {
3879 llvm::SmallVector<char, 100> Buffer;
3880 ER.Val.getFloat().toString(Buffer);
3881 std::string floatStr(Buffer.data(), Buffer.size());
3882 result->EvalType = CXEval_Float;
3883 bool ignored;
3884 llvm::APFloat apFloat = ER.Val.getFloat();
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003885 apFloat.convert(llvm::APFloat::IEEEdouble(),
David Blaikiebbc00882016-04-13 18:36:19 +00003886 llvm::APFloat::rmNearestTiesToEven, &ignored);
3887 result->EvalData.floatVal = apFloat.convertToDouble();
3888 return result.release();
3889 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003890
David Blaikiebbc00882016-04-13 18:36:19 +00003891 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3892 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3893 auto *subExpr = I->getSubExprAsWritten();
3894 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3895 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003896 const StringLiteral *StrE = nullptr;
3897 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003898 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003899
3900 if (ObjCExpr) {
3901 StrE = ObjCExpr->getString();
3902 result->EvalType = CXEval_ObjCStrLiteral;
3903 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003904 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003905 result->EvalType = CXEval_StrLiteral;
3906 }
3907
3908 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003909 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003910 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3911 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003912 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003913 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003914 }
3915 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3916 expr->getStmtClass() == Stmt::StringLiteralClass) {
3917 const StringLiteral *StrE = nullptr;
3918 const ObjCStringLiteral *ObjCExpr;
3919 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003920
David Blaikiebbc00882016-04-13 18:36:19 +00003921 if (ObjCExpr) {
3922 StrE = ObjCExpr->getString();
3923 result->EvalType = CXEval_ObjCStrLiteral;
3924 } else {
3925 StrE = cast<StringLiteral>(expr);
3926 result->EvalType = CXEval_StrLiteral;
3927 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003928
David Blaikiebbc00882016-04-13 18:36:19 +00003929 std::string strRef(StrE->getString().str());
3930 result->EvalData.stringVal = new char[strRef.size() + 1];
3931 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3932 result->EvalData.stringVal[strRef.size()] = '\0';
3933 return result.release();
3934 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003935
David Blaikiebbc00882016-04-13 18:36:19 +00003936 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3937 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003938
David Blaikiebbc00882016-04-13 18:36:19 +00003939 rettype = CC->getType();
3940 if (rettype.getAsString() == "CFStringRef" &&
3941 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003942
David Blaikiebbc00882016-04-13 18:36:19 +00003943 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3944 StringLiteral *S = getCFSTR_value(callExpr);
3945 if (S) {
3946 std::string strLiteral(S->getString().str());
3947 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003948
David Blaikiebbc00882016-04-13 18:36:19 +00003949 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3950 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3951 strLiteral.size());
3952 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003953 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003954 }
3955 }
3956
David Blaikiebbc00882016-04-13 18:36:19 +00003957 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3958 callExpr = static_cast<CallExpr *>(expr);
3959 rettype = callExpr->getCallReturnType(ctx);
3960
3961 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
3962 return nullptr;
3963
3964 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3965 if (callExpr->getNumArgs() == 1 &&
3966 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
3967 return nullptr;
3968 } else if (rettype.getAsString() == "CFStringRef") {
3969
3970 StringLiteral *S = getCFSTR_value(callExpr);
3971 if (S) {
3972 std::string strLiteral(S->getString().str());
3973 result->EvalType = CXEval_CFStr;
3974 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3975 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3976 strLiteral.size());
3977 result->EvalData.stringVal[strLiteral.size()] = '\0';
3978 return result.release();
3979 }
3980 }
3981 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3982 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3983 ValueDecl *V = D->getDecl();
3984 if (V->getKind() == Decl::Function) {
3985 std::string strName = V->getNameAsString();
3986 result->EvalType = CXEval_Other;
3987 result->EvalData.stringVal = new char[strName.size() + 1];
3988 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
3989 result->EvalData.stringVal[strName.size()] = '\0';
3990 return result.release();
3991 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003992 }
3993
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003994 return nullptr;
3995}
3996
Alex Lorenz65317e12019-01-08 22:32:51 +00003997static const Expr *evaluateDeclExpr(const Decl *D) {
3998 if (!D)
Evgeniy Stepanov9b871492018-07-10 19:48:53 +00003999 return nullptr;
Alex Lorenz65317e12019-01-08 22:32:51 +00004000 if (auto *Var = dyn_cast<VarDecl>(D))
4001 return Var->getInit();
4002 else if (auto *Field = dyn_cast<FieldDecl>(D))
4003 return Field->getInClassInitializer();
4004 return nullptr;
4005}
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004006
Alex Lorenz65317e12019-01-08 22:32:51 +00004007static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4008 assert(CS && "invalid compound statement");
4009 for (auto *bodyIterator : CS->body()) {
4010 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4011 return E;
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004012 }
Alex Lorenzc4cf96e2018-07-09 19:56:45 +00004013 return nullptr;
4014}
4015
Alex Lorenz65317e12019-01-08 22:32:51 +00004016CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
4017 if (const Expr *E =
4018 clang_getCursorKind(C) == CXCursor_CompoundStmt
4019 ? evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)))
4020 : evaluateDeclExpr(getCursorDecl(C)))
4021 return const_cast<CXEvalResult>(
4022 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4023 return nullptr;
4024}
4025
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004026unsigned clang_Cursor_hasAttrs(CXCursor C) {
4027 const Decl *D = getCursorDecl(C);
4028 if (!D) {
4029 return 0;
4030 }
4031
4032 if (D->hasAttrs()) {
4033 return 1;
4034 }
4035
4036 return 0;
4037}
Guy Benyei11169dd2012-12-18 14:30:41 +00004038unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4039 return CXSaveTranslationUnit_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05004040}
Guy Benyei11169dd2012-12-18 14:30:41 +00004041
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004042static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4043 const char *FileName,
4044 unsigned options) {
4045 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4047 setThreadBackgroundPriority();
4048
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004049 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4050 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00004051}
4052
4053int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4054 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004055 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004056
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004057 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004058 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004060 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004061
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004062 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4064 if (!CXXUnit->hasSema())
4065 return CXSaveError_InvalidTU;
4066
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004067 CXSaveError result;
4068 auto SaveTranslationUnitImpl = [=, &result]() {
4069 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4070 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004071
Erik Verbruggen3cc39112017-11-14 09:34:39 +00004072 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004073 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00004074
4075 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4076 PrintLibclangResourceUsage(TU);
4077
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004078 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 }
4080
4081 // We have an AST that has invalid nodes due to compiler errors.
4082 // Use a crash recovery thread for protection.
4083
4084 llvm::CrashRecoveryContext CRC;
4085
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004086 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4088 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4089 fprintf(stderr, " 'options' : %d,\n", options);
4090 fprintf(stderr, "}\n");
4091
4092 return CXSaveError_Unknown;
4093
4094 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4095 PrintLibclangResourceUsage(TU);
4096 }
4097
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004098 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004099}
4100
4101void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4102 if (CTUnit) {
4103 // If the translation unit has been marked as unsafe to free, just discard
4104 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004105 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4106 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 return;
4108
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004109 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00004110 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4112 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00004113 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 delete CTUnit;
4115 }
4116}
4117
Erik Verbruggen346066b2017-05-30 14:25:54 +00004118unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4119 if (CTUnit) {
4120 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4121
4122 if (Unit && Unit->isUnsafeToFree())
4123 return false;
4124
4125 Unit->ResetForParse();
4126 return true;
4127 }
4128
4129 return false;
4130}
4131
Guy Benyei11169dd2012-12-18 14:30:41 +00004132unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4133 return CXReparse_None;
4134}
4135
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004136static CXErrorCode
4137clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4138 ArrayRef<CXUnsavedFile> unsaved_files,
4139 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004140 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004141 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004142 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004143 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004144 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004145
4146 // Reset the associated diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05004147 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00004148 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004149
Dmitri Gribenko183436e2013-01-26 21:49:50 +00004150 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4152 setThreadBackgroundPriority();
4153
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004154 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00004156
4157 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4158 new std::vector<ASTUnit::RemappedFile>());
4159
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05004161 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4162 RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00004163
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004164 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004165 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00004166 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004167 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004169
Adrian Prantlbb165fb2015-06-20 18:53:08 +00004170 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4171 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004172 return CXError_Success;
4173 if (isASTReadError(CXXUnit))
4174 return CXError_ASTReadError;
4175 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00004176}
4177
4178int clang_reparseTranslationUnit(CXTranslationUnit TU,
4179 unsigned num_unsaved_files,
4180 struct CXUnsavedFile *unsaved_files,
4181 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004182 LOG_FUNC_SECTION { *Log << TU; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004183
Alp Toker9d85b182014-07-07 01:23:14 +00004184 if (num_unsaved_files && !unsaved_files)
4185 return CXError_InvalidArguments;
4186
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004187 CXErrorCode result;
4188 auto ReparseTranslationUnitImpl = [=, &result]() {
4189 result = clang_reparseTranslationUnit_Impl(
4190 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
4191 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004192
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 llvm::CrashRecoveryContext CRC;
4194
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004195 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004197 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004198 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4200 PrintLibclangResourceUsage(TU);
4201
Alp Toker5c532982014-07-07 22:42:03 +00004202 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004203}
4204
Guy Benyei11169dd2012-12-18 14:30:41 +00004205CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004206 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004207 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004208 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004209 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004210
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004211 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004212 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004213}
4214
4215CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004216 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004217 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004218 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004219 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004220
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004221 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4223}
4224
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004225CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4226 if (isNotUsableTU(CTUnit)) {
4227 LOG_BAD_TU(CTUnit);
4228 return nullptr;
4229 }
4230
Michael Kruse7520cf02020-03-25 09:26:14 -05004231 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004232 impl->TranslationUnit = CTUnit;
4233 return impl;
4234}
4235
4236CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4237 if (!TargetInfo)
4238 return cxstring::createEmpty();
4239
4240 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4241 assert(!isNotUsableTU(CTUnit) &&
4242 "Unexpected unusable translation unit in TargetInfo");
4243
4244 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4245 std::string Triple =
Michael Kruse7520cf02020-03-25 09:26:14 -05004246 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004247 return cxstring::createDup(Triple);
4248}
4249
4250int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4251 if (!TargetInfo)
4252 return -1;
4253
4254 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4255 assert(!isNotUsableTU(CTUnit) &&
4256 "Unexpected unusable translation unit in TargetInfo");
4257
4258 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4259 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4260}
4261
4262void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4263 if (!TargetInfo)
4264 return;
4265
4266 delete TargetInfo;
4267}
4268
Guy Benyei11169dd2012-12-18 14:30:41 +00004269//===----------------------------------------------------------------------===//
4270// CXFile Operations.
4271//===----------------------------------------------------------------------===//
4272
Guy Benyei11169dd2012-12-18 14:30:41 +00004273CXString clang_getFileName(CXFile SFile) {
4274 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00004275 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00004276
4277 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004279}
4280
4281time_t clang_getFileTime(CXFile SFile) {
4282 if (!SFile)
4283 return 0;
4284
4285 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4286 return FEnt->getModificationTime();
4287}
4288
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004289CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004290 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004291 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00004292 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004293 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004294
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004295 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004296
4297 FileManager &FMgr = CXXUnit->getFileManager();
Harlan Haskins8d323d12019-08-01 21:31:56 +00004298 auto File = FMgr.getFile(file_name);
4299 if (!File)
4300 return nullptr;
4301 return const_cast<FileEntry *>(*File);
Guy Benyei11169dd2012-12-18 14:30:41 +00004302}
4303
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004304const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4305 size_t *size) {
4306 if (isNotUsableTU(TU)) {
4307 LOG_BAD_TU(TU);
4308 return nullptr;
4309 }
4310
4311 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4312 FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
4313 bool Invalid = true;
Nico Weber04347d82019-04-04 21:06:41 +00004314 const llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid);
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004315 if (Invalid) {
4316 if (size)
4317 *size = 0;
4318 return nullptr;
4319 }
4320 if (size)
4321 *size = buf->getBufferSize();
4322 return buf->getBufferStart();
4323}
4324
Michael Kruse7520cf02020-03-25 09:26:14 -05004325unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004326 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004327 LOG_BAD_TU(TU);
4328 return 0;
4329 }
4330
4331 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 return 0;
4333
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004334 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004335 FileEntry *FEnt = static_cast<FileEntry *>(file);
Michael Kruse7520cf02020-03-25 09:26:14 -05004336 return CXXUnit->getPreprocessor()
4337 .getHeaderSearchInfo()
4338 .isFileMultipleIncludeGuarded(FEnt);
Guy Benyei11169dd2012-12-18 14:30:41 +00004339}
4340
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004341int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
4342 if (!file || !outID)
4343 return 1;
4344
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004345 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00004346 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
4347 outID->data[0] = ID.getDevice();
4348 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004349 outID->data[2] = FEnt->getModificationTime();
4350 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004351}
4352
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00004353int clang_File_isEqual(CXFile file1, CXFile file2) {
4354 if (file1 == file2)
4355 return true;
4356
4357 if (!file1 || !file2)
4358 return false;
4359
4360 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
4361 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
4362 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
4363}
4364
Fangrui Songe46ac5f2018-04-07 20:50:35 +00004365CXString clang_File_tryGetRealPathName(CXFile SFile) {
4366 if (!SFile)
4367 return cxstring::createNull();
4368
4369 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4370 return cxstring::createRef(FEnt->tryGetRealPathName());
4371}
4372
Guy Benyei11169dd2012-12-18 14:30:41 +00004373//===----------------------------------------------------------------------===//
4374// CXCursor Operations.
4375//===----------------------------------------------------------------------===//
4376
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004377static const Decl *getDeclFromExpr(const Stmt *E) {
4378 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 return getDeclFromExpr(CE->getSubExpr());
4380
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004381 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004382 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004383 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004385 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004386 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004387 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 if (PRE->isExplicitProperty())
4389 return PRE->getExplicitProperty();
4390 // It could be messaging both getter and setter as in:
4391 // ++myobj.myprop;
4392 // in which case prefer to associate the setter since it is less obvious
4393 // from inspecting the source that the setter is going to get called.
4394 if (PRE->isMessagingSetter())
4395 return PRE->getImplicitPropertySetter();
4396 return PRE->getImplicitPropertyGetter();
4397 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004398 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004400 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 if (Expr *Src = OVE->getSourceExpr())
4402 return getDeclFromExpr(Src);
Michael Kruse7520cf02020-03-25 09:26:14 -05004403
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004404 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004406 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 if (!CE->isElidable())
Michael Kruse7520cf02020-03-25 09:26:14 -05004408 return CE->getConstructor();
Richard Smith5179eb72016-06-28 19:03:57 +00004409 if (const CXXInheritedCtorInitExpr *CE =
4410 dyn_cast<CXXInheritedCtorInitExpr>(E))
4411 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004412 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 return OME->getMethodDecl();
4414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004415 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 return PE->getProtocol();
Michael Kruse7520cf02020-03-25 09:26:14 -05004417 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4418 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004420 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004421 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 isa<ParmVarDecl>(SizeOfPack->getPack()))
4423 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00004424
4425 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004426}
4427
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004428static SourceLocation getLocationFromExpr(const Expr *E) {
4429 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 return getLocationFromExpr(CE->getSubExpr());
4431
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004432 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004433 return /*FIXME:*/ Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004434 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004436 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004437 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004438 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004440 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004442 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 return PropRef->getLocation();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004444
4445 return E->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00004446}
4447
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00004448extern "C" {
4449
Michael Kruse7520cf02020-03-25 09:26:14 -05004450unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 CXClientData client_data) {
4452 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4453 /*VisitPreprocessorLast=*/false);
4454 return CursorVis.VisitChildren(parent);
4455}
4456
4457#ifndef __has_feature
4458#define __has_feature(x) 0
4459#endif
4460#if __has_feature(blocks)
Michael Kruse7520cf02020-03-25 09:26:14 -05004461typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4462 CXCursor parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00004463
4464static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004465 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4467 return block(cursor, parent);
4468}
4469#else
4470// If we are compiled with a compiler that doesn't have native blocks support,
Michael Kruse7520cf02020-03-25 09:26:14 -05004471// define and call the block manually, so the
4472typedef struct _CXChildVisitResult {
4473 void *isa;
4474 int flags;
4475 int reserved;
4476 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
4477 CXCursor);
4478} * CXCursorVisitorBlock;
Guy Benyei11169dd2012-12-18 14:30:41 +00004479
4480static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004481 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4483 return block->invoke(block, cursor, parent);
4484}
4485#endif
4486
Guy Benyei11169dd2012-12-18 14:30:41 +00004487unsigned clang_visitChildrenWithBlock(CXCursor parent,
4488 CXCursorVisitorBlock block) {
4489 return clang_visitChildren(parent, visitWithBlock, block);
4490}
4491
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004492static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004494 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004495
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004496 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004498 if (const ObjCPropertyImplDecl *PropImpl =
4499 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004501 return cxstring::createDup(Property->getIdentifier()->getName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004502
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004503 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004505 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004506
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004507 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004509
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004510 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004511 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004512
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004513 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4515 // and returns different names. NamedDecl returns the class name and
4516 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004517 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004518
4519 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004520 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05004521
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 SmallString<1024> S;
4523 llvm::raw_svector_ostream os(S);
4524 ND->printName(os);
Michael Kruse7520cf02020-03-25 09:26:14 -05004525
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004526 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004527}
4528
4529CXString clang_getCursorSpelling(CXCursor C) {
4530 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004531 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004532
4533 if (clang_isReference(C.kind)) {
4534 switch (C.kind) {
4535 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004536 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004537 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 }
4539 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004540 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004541 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 }
4543 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004544 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 }
4548 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004549 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004550 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 }
4552 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004553 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 assert(Type && "Missing type decl");
4555
Michael Kruse7520cf02020-03-25 09:26:14 -05004556 return cxstring::createDup(
4557 getCursorContext(C).getTypeDeclType(Type).getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 }
4559 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004560 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 assert(Template && "Missing template decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004562
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004563 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004565
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004567 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 assert(NS && "Missing namespace decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004569
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004570 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 }
4572
4573 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004574 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 assert(Field && "Missing member decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004576
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004577 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 }
4579
4580 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004581 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 assert(Label && "Missing label");
Michael Kruse7520cf02020-03-25 09:26:14 -05004583
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 }
4586
4587 case CXCursor_OverloadedDeclRef: {
4588 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004589 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4590 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004591 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004592 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004594 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004595 return cxstring::createDup(E->getName().getAsString());
Michael Kruse7520cf02020-03-25 09:26:14 -05004596 OverloadedTemplateStorage *Ovl =
4597 Storage.get<OverloadedTemplateStorage *>();
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004599 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004600 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004602
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004604 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 assert(Var && "Missing variable decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004606
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004607 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004609
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004611 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 }
4613 }
4614
4615 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004616 const Expr *E = getCursorExpr(C);
4617
4618 if (C.kind == CXCursor_ObjCStringLiteral ||
4619 C.kind == CXCursor_StringLiteral) {
4620 const StringLiteral *SLit;
4621 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4622 SLit = OSL->getString();
4623 } else {
4624 SLit = cast<StringLiteral>(E);
4625 }
4626 SmallString<256> Buf;
4627 llvm::raw_svector_ostream OS(Buf);
4628 SLit->outputString(OS);
4629 return cxstring::createDup(OS.str());
4630 }
4631
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004632 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 if (D)
4634 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004635 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 }
4637
4638 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004639 const Stmt *S = getCursorStmt(C);
4640 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004641 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004642
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004643 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004645
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 if (C.kind == CXCursor_MacroExpansion)
Michael Kruse7520cf02020-03-25 09:26:14 -05004647 return cxstring::createRef(
4648 getCursorMacroExpansion(C).getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004649
4650 if (C.kind == CXCursor_MacroDefinition)
Michael Kruse7520cf02020-03-25 09:26:14 -05004651 return cxstring::createRef(
4652 getCursorMacroDefinition(C)->getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004653
4654 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004655 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004656
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 if (clang_isDeclaration(C.kind))
4658 return getDeclSpelling(getCursorDecl(C));
4659
4660 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004661 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004662 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 }
4664
4665 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004666 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004667 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 }
4669
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004670 if (C.kind == CXCursor_PackedAttr) {
4671 return cxstring::createRef("packed");
4672 }
4673
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004674 if (C.kind == CXCursor_VisibilityAttr) {
4675 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4676 switch (AA->getVisibility()) {
4677 case VisibilityAttr::VisibilityType::Default:
4678 return cxstring::createRef("default");
4679 case VisibilityAttr::VisibilityType::Hidden:
4680 return cxstring::createRef("hidden");
4681 case VisibilityAttr::VisibilityType::Protected:
4682 return cxstring::createRef("protected");
4683 }
4684 llvm_unreachable("unknown visibility type");
4685 }
4686
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004687 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004688}
4689
Michael Kruse7520cf02020-03-25 09:26:14 -05004690CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 unsigned options) {
4692 if (clang_Cursor_isNull(C))
4693 return clang_getNullRange();
4694
4695 ASTContext &Ctx = getCursorContext(C);
4696
4697 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004698 const Stmt *S = getCursorStmt(C);
4699 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 if (pieceIndex > 0)
4701 return clang_getNullRange();
4702 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4703 }
4704
4705 return clang_getNullRange();
4706 }
4707
4708 if (C.kind == CXCursor_ObjCMessageExpr) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004709 if (const ObjCMessageExpr *ME =
4710 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 if (pieceIndex >= ME->getNumSelectorLocs())
4712 return clang_getNullRange();
4713 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4714 }
4715 }
4716
4717 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4718 C.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004719 if (const ObjCMethodDecl *MD =
4720 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 if (pieceIndex >= MD->getNumSelectorLocs())
4722 return clang_getNullRange();
4723 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4724 }
4725 }
4726
4727 if (C.kind == CXCursor_ObjCCategoryDecl ||
4728 C.kind == CXCursor_ObjCCategoryImplDecl) {
4729 if (pieceIndex > 0)
4730 return clang_getNullRange();
Michael Kruse7520cf02020-03-25 09:26:14 -05004731 if (const ObjCCategoryDecl *CD =
4732 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Michael Kruse7520cf02020-03-25 09:26:14 -05004734 if (const ObjCCategoryImplDecl *CID =
4735 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4737 }
4738
4739 if (C.kind == CXCursor_ModuleImportDecl) {
4740 if (pieceIndex > 0)
4741 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004742 if (const ImportDecl *ImportD =
4743 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4745 if (!Locs.empty())
Michael Kruse7520cf02020-03-25 09:26:14 -05004746 return cxloc::translateSourceRange(
4747 Ctx, SourceRange(Locs.front(), Locs.back()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 }
4749 return clang_getNullRange();
4750 }
4751
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004752 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
Kevin Funk4be5d672016-12-20 09:56:56 +00004753 C.kind == CXCursor_ConversionFunction ||
4754 C.kind == CXCursor_FunctionDecl) {
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004755 if (pieceIndex > 0)
4756 return clang_getNullRange();
4757 if (const FunctionDecl *FD =
4758 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4759 DeclarationNameInfo FunctionName = FD->getNameInfo();
4760 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4761 }
4762 return clang_getNullRange();
4763 }
4764
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 // FIXME: A CXCursor_InclusionDirective should give the location of the
4766 // filename, but we don't keep track of this.
4767
4768 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4769 // but we don't keep track of this.
4770
4771 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4772 // but we don't keep track of this.
4773
4774 // Default handling, give the location of the cursor.
4775
4776 if (pieceIndex > 0)
4777 return clang_getNullRange();
4778
4779 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4780 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4781 return cxloc::translateSourceRange(Ctx, Loc);
4782}
4783
Eli Bendersky44a206f2014-07-31 18:04:56 +00004784CXString clang_Cursor_getMangling(CXCursor C) {
4785 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4786 return cxstring::createEmpty();
4787
Eli Bendersky44a206f2014-07-31 18:04:56 +00004788 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004789 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004790 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4791 return cxstring::createEmpty();
4792
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004793 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004794 ASTNameGenerator ASTNameGen(Ctx);
4795 return cxstring::createDup(ASTNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004796}
4797
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004798CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4799 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4800 return nullptr;
4801
4802 const Decl *D = getCursorDecl(C);
4803 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4804 return nullptr;
4805
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004806 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004807 ASTNameGenerator ASTNameGen(Ctx);
4808 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004809 return cxstring::createSet(Manglings);
4810}
4811
Dave Lee1a532c92017-09-22 16:58:57 +00004812CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
4813 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4814 return nullptr;
4815
4816 const Decl *D = getCursorDecl(C);
4817 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
4818 return nullptr;
4819
4820 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004821 ASTNameGenerator ASTNameGen(Ctx);
4822 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Dave Lee1a532c92017-09-22 16:58:57 +00004823 return cxstring::createSet(Manglings);
4824}
4825
Jonathan Coe45ef5032018-01-16 10:19:56 +00004826CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
4827 if (clang_Cursor_isNull(C))
4828 return 0;
4829 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
4830}
4831
4832void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
4833 if (Policy)
4834 delete static_cast<PrintingPolicy *>(Policy);
4835}
4836
4837unsigned
4838clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
4839 enum CXPrintingPolicyProperty Property) {
4840 if (!Policy)
4841 return 0;
4842
4843 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4844 switch (Property) {
4845 case CXPrintingPolicy_Indentation:
4846 return P->Indentation;
4847 case CXPrintingPolicy_SuppressSpecifiers:
4848 return P->SuppressSpecifiers;
4849 case CXPrintingPolicy_SuppressTagKeyword:
4850 return P->SuppressTagKeyword;
4851 case CXPrintingPolicy_IncludeTagDefinition:
4852 return P->IncludeTagDefinition;
4853 case CXPrintingPolicy_SuppressScope:
4854 return P->SuppressScope;
4855 case CXPrintingPolicy_SuppressUnwrittenScope:
4856 return P->SuppressUnwrittenScope;
4857 case CXPrintingPolicy_SuppressInitializers:
4858 return P->SuppressInitializers;
4859 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4860 return P->ConstantArraySizeAsWritten;
4861 case CXPrintingPolicy_AnonymousTagLocations:
4862 return P->AnonymousTagLocations;
4863 case CXPrintingPolicy_SuppressStrongLifetime:
4864 return P->SuppressStrongLifetime;
4865 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4866 return P->SuppressLifetimeQualifiers;
4867 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4868 return P->SuppressTemplateArgsInCXXConstructors;
4869 case CXPrintingPolicy_Bool:
4870 return P->Bool;
4871 case CXPrintingPolicy_Restrict:
4872 return P->Restrict;
4873 case CXPrintingPolicy_Alignof:
4874 return P->Alignof;
4875 case CXPrintingPolicy_UnderscoreAlignof:
4876 return P->UnderscoreAlignof;
4877 case CXPrintingPolicy_UseVoidForZeroParams:
4878 return P->UseVoidForZeroParams;
4879 case CXPrintingPolicy_TerseOutput:
4880 return P->TerseOutput;
4881 case CXPrintingPolicy_PolishForDeclaration:
4882 return P->PolishForDeclaration;
4883 case CXPrintingPolicy_Half:
4884 return P->Half;
4885 case CXPrintingPolicy_MSWChar:
4886 return P->MSWChar;
4887 case CXPrintingPolicy_IncludeNewlines:
4888 return P->IncludeNewlines;
4889 case CXPrintingPolicy_MSVCFormatting:
4890 return P->MSVCFormatting;
4891 case CXPrintingPolicy_ConstantsAsWritten:
4892 return P->ConstantsAsWritten;
4893 case CXPrintingPolicy_SuppressImplicitBase:
4894 return P->SuppressImplicitBase;
4895 case CXPrintingPolicy_FullyQualifiedName:
4896 return P->FullyQualifiedName;
4897 }
4898
4899 assert(false && "Invalid CXPrintingPolicyProperty");
4900 return 0;
4901}
4902
4903void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
4904 enum CXPrintingPolicyProperty Property,
4905 unsigned Value) {
4906 if (!Policy)
4907 return;
4908
4909 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4910 switch (Property) {
4911 case CXPrintingPolicy_Indentation:
4912 P->Indentation = Value;
4913 return;
4914 case CXPrintingPolicy_SuppressSpecifiers:
4915 P->SuppressSpecifiers = Value;
4916 return;
4917 case CXPrintingPolicy_SuppressTagKeyword:
4918 P->SuppressTagKeyword = Value;
4919 return;
4920 case CXPrintingPolicy_IncludeTagDefinition:
4921 P->IncludeTagDefinition = Value;
4922 return;
4923 case CXPrintingPolicy_SuppressScope:
4924 P->SuppressScope = Value;
4925 return;
4926 case CXPrintingPolicy_SuppressUnwrittenScope:
4927 P->SuppressUnwrittenScope = Value;
4928 return;
4929 case CXPrintingPolicy_SuppressInitializers:
4930 P->SuppressInitializers = Value;
4931 return;
4932 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4933 P->ConstantArraySizeAsWritten = Value;
4934 return;
4935 case CXPrintingPolicy_AnonymousTagLocations:
4936 P->AnonymousTagLocations = Value;
4937 return;
4938 case CXPrintingPolicy_SuppressStrongLifetime:
4939 P->SuppressStrongLifetime = Value;
4940 return;
4941 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4942 P->SuppressLifetimeQualifiers = Value;
4943 return;
4944 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4945 P->SuppressTemplateArgsInCXXConstructors = Value;
4946 return;
4947 case CXPrintingPolicy_Bool:
4948 P->Bool = Value;
4949 return;
4950 case CXPrintingPolicy_Restrict:
4951 P->Restrict = Value;
4952 return;
4953 case CXPrintingPolicy_Alignof:
4954 P->Alignof = Value;
4955 return;
4956 case CXPrintingPolicy_UnderscoreAlignof:
4957 P->UnderscoreAlignof = Value;
4958 return;
4959 case CXPrintingPolicy_UseVoidForZeroParams:
4960 P->UseVoidForZeroParams = Value;
4961 return;
4962 case CXPrintingPolicy_TerseOutput:
4963 P->TerseOutput = Value;
4964 return;
4965 case CXPrintingPolicy_PolishForDeclaration:
4966 P->PolishForDeclaration = Value;
4967 return;
4968 case CXPrintingPolicy_Half:
4969 P->Half = Value;
4970 return;
4971 case CXPrintingPolicy_MSWChar:
4972 P->MSWChar = Value;
4973 return;
4974 case CXPrintingPolicy_IncludeNewlines:
4975 P->IncludeNewlines = Value;
4976 return;
4977 case CXPrintingPolicy_MSVCFormatting:
4978 P->MSVCFormatting = Value;
4979 return;
4980 case CXPrintingPolicy_ConstantsAsWritten:
4981 P->ConstantsAsWritten = Value;
4982 return;
4983 case CXPrintingPolicy_SuppressImplicitBase:
4984 P->SuppressImplicitBase = Value;
4985 return;
4986 case CXPrintingPolicy_FullyQualifiedName:
4987 P->FullyQualifiedName = Value;
4988 return;
4989 }
4990
4991 assert(false && "Invalid CXPrintingPolicyProperty");
4992}
4993
4994CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
4995 if (clang_Cursor_isNull(C))
4996 return cxstring::createEmpty();
4997
4998 if (clang_isDeclaration(C.kind)) {
4999 const Decl *D = getCursorDecl(C);
5000 if (!D)
5001 return cxstring::createEmpty();
5002
5003 SmallString<128> Str;
5004 llvm::raw_svector_ostream OS(Str);
5005 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5006 D->print(OS, UserPolicy ? *UserPolicy
5007 : getCursorContext(C).getPrintingPolicy());
5008
5009 return cxstring::createDup(OS.str());
5010 }
5011
5012 return cxstring::createEmpty();
5013}
5014
Guy Benyei11169dd2012-12-18 14:30:41 +00005015CXString clang_getCursorDisplayName(CXCursor C) {
5016 if (!clang_isDeclaration(C.kind))
5017 return clang_getCursorSpelling(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05005018
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005019 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005021 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005022
5023 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005024 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005025 D = FunTmpl->getTemplatedDecl();
Michael Kruse7520cf02020-03-25 09:26:14 -05005026
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005027 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 SmallString<64> Str;
5029 llvm::raw_svector_ostream OS(Str);
5030 OS << *Function;
5031 if (Function->getPrimaryTemplate())
5032 OS << "<>";
5033 OS << "(";
5034 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5035 if (I)
5036 OS << ", ";
5037 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5038 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005039
Guy Benyei11169dd2012-12-18 14:30:41 +00005040 if (Function->isVariadic()) {
5041 if (Function->getNumParams())
5042 OS << ", ";
5043 OS << "...";
5044 }
5045 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005046 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005048
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005049 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 SmallString<64> Str;
5051 llvm::raw_svector_ostream OS(Str);
5052 OS << *ClassTemplate;
5053 OS << "<";
5054 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5055 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5056 if (I)
5057 OS << ", ";
Michael Kruse7520cf02020-03-25 09:26:14 -05005058
Guy Benyei11169dd2012-12-18 14:30:41 +00005059 NamedDecl *Param = Params->getParam(I);
5060 if (Param->getIdentifier()) {
5061 OS << Param->getIdentifier()->getName();
5062 continue;
5063 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005064
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 // There is no parameter name, which makes this tricky. Try to come up
5066 // with something useful that isn't too long.
5067 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
Saar Razff1e0fc2020-01-15 02:48:42 +02005068 if (const auto *TC = TTP->getTypeConstraint()) {
5069 TC->getConceptNameInfo().printName(OS, Policy);
5070 if (TC->hasExplicitTemplateArgs())
5071 OS << "<...>";
5072 } else
Michael Kruse7520cf02020-03-25 09:26:14 -05005073 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5074 else if (NonTypeTemplateParmDecl *NTTP =
5075 dyn_cast<NonTypeTemplateParmDecl>(Param))
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 OS << NTTP->getType().getAsString(Policy);
5077 else
5078 OS << "template<...> class";
5079 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005080
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005082 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005084
5085 if (const ClassTemplateSpecializationDecl *ClassSpec =
5086 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 // If the type was explicitly written, use that.
5088 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005089 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Serge Pavlov03e672c2017-11-28 16:14:14 +00005090
Benjamin Kramer9170e912013-02-22 15:46:01 +00005091 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 llvm::raw_svector_ostream OS(Str);
5093 OS << *ClassSpec;
Serge Pavlov03e672c2017-11-28 16:14:14 +00005094 printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
5095 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005096 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005098
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 return clang_getCursorSpelling(C);
5100}
Michael Kruse7520cf02020-03-25 09:26:14 -05005101
Guy Benyei11169dd2012-12-18 14:30:41 +00005102CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5103 switch (Kind) {
5104 case CXCursor_FunctionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005105 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 case CXCursor_TypedefDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005107 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 case CXCursor_EnumDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005109 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 case CXCursor_EnumConstantDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005111 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 case CXCursor_StructDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005113 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 case CXCursor_UnionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005115 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 case CXCursor_ClassDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005117 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 case CXCursor_FieldDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005119 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 case CXCursor_VarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005121 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 case CXCursor_ParmDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005123 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 case CXCursor_ObjCInterfaceDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005125 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 case CXCursor_ObjCCategoryDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005127 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 case CXCursor_ObjCProtocolDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005129 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 case CXCursor_ObjCPropertyDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005131 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 case CXCursor_ObjCIvarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005133 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 case CXCursor_ObjCInstanceMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005135 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 case CXCursor_ObjCClassMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005137 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 case CXCursor_ObjCImplementationDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005139 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 case CXCursor_ObjCCategoryImplDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005141 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 case CXCursor_CXXMethod:
Michael Kruse7520cf02020-03-25 09:26:14 -05005143 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 case CXCursor_UnexposedDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005145 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005147 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 case CXCursor_ObjCProtocolRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005149 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 case CXCursor_ObjCClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005151 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 case CXCursor_TypeRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005153 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 case CXCursor_TemplateRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005155 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005157 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005159 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005161 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005163 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005165 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 case CXCursor_IntegerLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005167 return cxstring::createRef("IntegerLiteral");
Leonard Chandb01c3a2018-06-20 17:19:40 +00005168 case CXCursor_FixedPointLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005169 return cxstring::createRef("FixedPointLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 case CXCursor_FloatingLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005171 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 case CXCursor_ImaginaryLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005173 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 case CXCursor_StringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005175 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 case CXCursor_CharacterLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005177 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 case CXCursor_ParenExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005179 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 case CXCursor_UnaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005181 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 case CXCursor_ArraySubscriptExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005183 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00005184 case CXCursor_OMPArraySectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005185 return cxstring::createRef("OMPArraySectionExpr");
Alexey Bataev7ac9efb2020-02-05 09:33:05 -05005186 case CXCursor_OMPArrayShapingExpr:
5187 return cxstring::createRef("OMPArrayShapingExpr");
Alexey Bataev13a15042020-04-01 15:06:38 -04005188 case CXCursor_OMPIteratorExpr:
5189 return cxstring::createRef("OMPIteratorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 case CXCursor_BinaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005191 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 case CXCursor_CompoundAssignOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005193 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 case CXCursor_ConditionalOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005195 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 case CXCursor_CStyleCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005197 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 case CXCursor_CompoundLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005199 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 case CXCursor_InitListExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005201 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 case CXCursor_AddrLabelExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005203 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 case CXCursor_StmtExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005205 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 case CXCursor_GenericSelectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005207 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 case CXCursor_GNUNullExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005209 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 case CXCursor_CXXStaticCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005211 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 case CXCursor_CXXDynamicCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005213 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 case CXCursor_CXXReinterpretCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005215 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 case CXCursor_CXXConstCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005217 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 case CXCursor_CXXFunctionalCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005219 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 case CXCursor_CXXTypeidExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005221 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 case CXCursor_CXXBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005223 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 case CXCursor_CXXNullPtrLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005225 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 case CXCursor_CXXThisExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005227 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 case CXCursor_CXXThrowExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005229 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 case CXCursor_CXXNewExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005231 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 case CXCursor_CXXDeleteExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005233 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 case CXCursor_UnaryExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005235 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 case CXCursor_ObjCStringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005237 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 case CXCursor_ObjCBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005239 return cxstring::createRef("ObjCBoolLiteralExpr");
Erik Pilkington29099de2016-07-16 00:35:23 +00005240 case CXCursor_ObjCAvailabilityCheckExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005241 return cxstring::createRef("ObjCAvailabilityCheckExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00005242 case CXCursor_ObjCSelfExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005243 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 case CXCursor_ObjCEncodeExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005245 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 case CXCursor_ObjCSelectorExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005247 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 case CXCursor_ObjCProtocolExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005249 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 case CXCursor_ObjCBridgedCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005251 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 case CXCursor_BlockExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005253 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 case CXCursor_PackExpansionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005255 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 case CXCursor_SizeOfPackExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005257 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005259 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 case CXCursor_UnexposedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005261 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 case CXCursor_DeclRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005263 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 case CXCursor_MemberRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005265 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005267 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 case CXCursor_ObjCMessageExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005269 return cxstring::createRef("ObjCMessageExpr");
Erik Pilkingtoneee944e2019-07-02 18:28:13 +00005270 case CXCursor_BuiltinBitCastExpr:
5271 return cxstring::createRef("BuiltinBitCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 case CXCursor_UnexposedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005273 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 case CXCursor_DeclStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005275 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 case CXCursor_LabelStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005277 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 case CXCursor_CompoundStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005279 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 case CXCursor_CaseStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005281 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 case CXCursor_DefaultStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005283 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 case CXCursor_IfStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005285 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 case CXCursor_SwitchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005287 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 case CXCursor_WhileStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005289 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 case CXCursor_DoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005291 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 case CXCursor_ForStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005293 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 case CXCursor_GotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005295 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 case CXCursor_IndirectGotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005297 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 case CXCursor_ContinueStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005299 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 case CXCursor_BreakStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005301 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 case CXCursor_ReturnStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005303 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 case CXCursor_GCCAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005305 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 case CXCursor_MSAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005307 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 case CXCursor_ObjCAtTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005309 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 case CXCursor_ObjCAtCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005311 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 case CXCursor_ObjCAtFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005313 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 case CXCursor_ObjCAtThrowStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005315 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 case CXCursor_ObjCAtSynchronizedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005317 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 case CXCursor_ObjCAutoreleasePoolStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005319 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 case CXCursor_ObjCForCollectionStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005321 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 case CXCursor_CXXCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005323 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 case CXCursor_CXXTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005325 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 case CXCursor_CXXForRangeStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005327 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 case CXCursor_SEHTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005329 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 case CXCursor_SEHExceptStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005331 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 case CXCursor_SEHFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005333 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00005334 case CXCursor_SEHLeaveStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005335 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 case CXCursor_NullStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005337 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 case CXCursor_InvalidFile:
Michael Kruse7520cf02020-03-25 09:26:14 -05005339 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005341 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 case CXCursor_NoDeclFound:
Michael Kruse7520cf02020-03-25 09:26:14 -05005343 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 case CXCursor_NotImplemented:
Michael Kruse7520cf02020-03-25 09:26:14 -05005345 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 case CXCursor_TranslationUnit:
Michael Kruse7520cf02020-03-25 09:26:14 -05005347 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 case CXCursor_UnexposedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005349 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 case CXCursor_IBActionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005351 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 case CXCursor_IBOutletAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005353 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 case CXCursor_IBOutletCollectionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005355 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 case CXCursor_CXXFinalAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005357 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 case CXCursor_CXXOverrideAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005359 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005361 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005363 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005364 case CXCursor_PackedAttr:
5365 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00005366 case CXCursor_PureAttr:
5367 return cxstring::createRef("attribute(pure)");
5368 case CXCursor_ConstAttr:
5369 return cxstring::createRef("attribute(const)");
5370 case CXCursor_NoDuplicateAttr:
5371 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00005372 case CXCursor_CUDAConstantAttr:
5373 return cxstring::createRef("attribute(constant)");
5374 case CXCursor_CUDADeviceAttr:
5375 return cxstring::createRef("attribute(device)");
5376 case CXCursor_CUDAGlobalAttr:
5377 return cxstring::createRef("attribute(global)");
5378 case CXCursor_CUDAHostAttr:
5379 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00005380 case CXCursor_CUDASharedAttr:
5381 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00005382 case CXCursor_VisibilityAttr:
5383 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00005384 case CXCursor_DLLExport:
5385 return cxstring::createRef("attribute(dllexport)");
5386 case CXCursor_DLLImport:
5387 return cxstring::createRef("attribute(dllimport)");
Michael Wud092d0b2018-08-03 05:03:22 +00005388 case CXCursor_NSReturnsRetained:
5389 return cxstring::createRef("attribute(ns_returns_retained)");
5390 case CXCursor_NSReturnsNotRetained:
5391 return cxstring::createRef("attribute(ns_returns_not_retained)");
5392 case CXCursor_NSReturnsAutoreleased:
5393 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5394 case CXCursor_NSConsumesSelf:
5395 return cxstring::createRef("attribute(ns_consumes_self)");
5396 case CXCursor_NSConsumed:
5397 return cxstring::createRef("attribute(ns_consumed)");
5398 case CXCursor_ObjCException:
5399 return cxstring::createRef("attribute(objc_exception)");
5400 case CXCursor_ObjCNSObject:
5401 return cxstring::createRef("attribute(NSObject)");
5402 case CXCursor_ObjCIndependentClass:
5403 return cxstring::createRef("attribute(objc_independent_class)");
5404 case CXCursor_ObjCPreciseLifetime:
5405 return cxstring::createRef("attribute(objc_precise_lifetime)");
5406 case CXCursor_ObjCReturnsInnerPointer:
5407 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5408 case CXCursor_ObjCRequiresSuper:
5409 return cxstring::createRef("attribute(objc_requires_super)");
5410 case CXCursor_ObjCRootClass:
5411 return cxstring::createRef("attribute(objc_root_class)");
5412 case CXCursor_ObjCSubclassingRestricted:
5413 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5414 case CXCursor_ObjCExplicitProtocolImpl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005415 return cxstring::createRef(
5416 "attribute(objc_protocol_requires_explicit_implementation)");
Michael Wud092d0b2018-08-03 05:03:22 +00005417 case CXCursor_ObjCDesignatedInitializer:
5418 return cxstring::createRef("attribute(objc_designated_initializer)");
5419 case CXCursor_ObjCRuntimeVisible:
5420 return cxstring::createRef("attribute(objc_runtime_visible)");
5421 case CXCursor_ObjCBoxable:
5422 return cxstring::createRef("attribute(objc_boxable)");
Michael Wu58d837d2018-08-03 05:55:40 +00005423 case CXCursor_FlagEnum:
5424 return cxstring::createRef("attribute(flag_enum)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005425 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005426 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005427 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005428 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005430 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005432 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005434 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005436 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005438 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005440 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005442 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005444 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005446 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005448 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005450 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005452 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005454 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005456 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005458 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005460 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005462 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005464 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005466 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005468 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005470 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005472 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005473 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00005474 return cxstring::createRef("OMPParallelDirective");
5475 case CXCursor_OMPSimdDirective:
5476 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00005477 case CXCursor_OMPForDirective:
5478 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00005479 case CXCursor_OMPForSimdDirective:
5480 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00005481 case CXCursor_OMPSectionsDirective:
5482 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00005483 case CXCursor_OMPSectionDirective:
5484 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00005485 case CXCursor_OMPSingleDirective:
5486 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00005487 case CXCursor_OMPMasterDirective:
5488 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00005489 case CXCursor_OMPCriticalDirective:
5490 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00005491 case CXCursor_OMPParallelForDirective:
5492 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00005493 case CXCursor_OMPParallelForSimdDirective:
5494 return cxstring::createRef("OMPParallelForSimdDirective");
cchen47d60942019-12-05 13:43:48 -05005495 case CXCursor_OMPParallelMasterDirective:
5496 return cxstring::createRef("OMPParallelMasterDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00005497 case CXCursor_OMPParallelSectionsDirective:
5498 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00005499 case CXCursor_OMPTaskDirective:
5500 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00005501 case CXCursor_OMPTaskyieldDirective:
5502 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00005503 case CXCursor_OMPBarrierDirective:
5504 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00005505 case CXCursor_OMPTaskwaitDirective:
5506 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00005507 case CXCursor_OMPTaskgroupDirective:
5508 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00005509 case CXCursor_OMPFlushDirective:
5510 return cxstring::createRef("OMPFlushDirective");
Alexey Bataevc112e942020-02-28 09:52:15 -05005511 case CXCursor_OMPDepobjDirective:
5512 return cxstring::createRef("OMPDepobjDirective");
Alexey Bataevfcba7c32020-03-20 07:03:01 -04005513 case CXCursor_OMPScanDirective:
5514 return cxstring::createRef("OMPScanDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00005515 case CXCursor_OMPOrderedDirective:
5516 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00005517 case CXCursor_OMPAtomicDirective:
5518 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00005519 case CXCursor_OMPTargetDirective:
5520 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00005521 case CXCursor_OMPTargetDataDirective:
5522 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00005523 case CXCursor_OMPTargetEnterDataDirective:
5524 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00005525 case CXCursor_OMPTargetExitDataDirective:
5526 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00005527 case CXCursor_OMPTargetParallelDirective:
5528 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00005529 case CXCursor_OMPTargetParallelForDirective:
5530 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00005531 case CXCursor_OMPTargetUpdateDirective:
5532 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00005533 case CXCursor_OMPTeamsDirective:
5534 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00005535 case CXCursor_OMPCancellationPointDirective:
5536 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00005537 case CXCursor_OMPCancelDirective:
5538 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00005539 case CXCursor_OMPTaskLoopDirective:
5540 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005541 case CXCursor_OMPTaskLoopSimdDirective:
5542 return cxstring::createRef("OMPTaskLoopSimdDirective");
Alexey Bataev60e51c42019-10-10 20:13:02 +00005543 case CXCursor_OMPMasterTaskLoopDirective:
5544 return cxstring::createRef("OMPMasterTaskLoopDirective");
Alexey Bataevb8552ab2019-10-18 16:47:35 +00005545 case CXCursor_OMPMasterTaskLoopSimdDirective:
5546 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
Alexey Bataev5bbcead2019-10-14 17:17:41 +00005547 case CXCursor_OMPParallelMasterTaskLoopDirective:
5548 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
Alexey Bataev14a388f2019-10-25 10:27:13 -04005549 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5550 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00005551 case CXCursor_OMPDistributeDirective:
5552 return cxstring::createRef("OMPDistributeDirective");
Carlo Bertolli9925f152016-06-27 14:55:37 +00005553 case CXCursor_OMPDistributeParallelForDirective:
5554 return cxstring::createRef("OMPDistributeParallelForDirective");
Kelvin Li4a39add2016-07-05 05:00:15 +00005555 case CXCursor_OMPDistributeParallelForSimdDirective:
5556 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
Kelvin Li787f3fc2016-07-06 04:45:38 +00005557 case CXCursor_OMPDistributeSimdDirective:
5558 return cxstring::createRef("OMPDistributeSimdDirective");
Kelvin Lia579b912016-07-14 02:54:56 +00005559 case CXCursor_OMPTargetParallelForSimdDirective:
5560 return cxstring::createRef("OMPTargetParallelForSimdDirective");
Kelvin Li986330c2016-07-20 22:57:10 +00005561 case CXCursor_OMPTargetSimdDirective:
5562 return cxstring::createRef("OMPTargetSimdDirective");
Kelvin Li02532872016-08-05 14:37:37 +00005563 case CXCursor_OMPTeamsDistributeDirective:
5564 return cxstring::createRef("OMPTeamsDistributeDirective");
Kelvin Li4e325f72016-10-25 12:50:55 +00005565 case CXCursor_OMPTeamsDistributeSimdDirective:
5566 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
Kelvin Li579e41c2016-11-30 23:51:03 +00005567 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5568 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
Kelvin Li7ade93f2016-12-09 03:24:30 +00005569 case CXCursor_OMPTeamsDistributeParallelForDirective:
5570 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
Kelvin Libf594a52016-12-17 05:48:59 +00005571 case CXCursor_OMPTargetTeamsDirective:
5572 return cxstring::createRef("OMPTargetTeamsDirective");
Kelvin Li83c451e2016-12-25 04:52:54 +00005573 case CXCursor_OMPTargetTeamsDistributeDirective:
5574 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
Kelvin Li80e8f562016-12-29 22:16:30 +00005575 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5576 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
Kelvin Li1851df52017-01-03 05:23:48 +00005577 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5578 return cxstring::createRef(
5579 "OMPTargetTeamsDistributeParallelForSimdDirective");
Kelvin Lida681182017-01-10 18:08:18 +00005580 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5581 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00005582 case CXCursor_OverloadCandidate:
Michael Kruse7520cf02020-03-25 09:26:14 -05005583 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00005584 case CXCursor_TypeAliasTemplateDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005585 return cxstring::createRef("TypeAliasTemplateDecl");
Olivier Goffart81978012016-06-09 16:15:55 +00005586 case CXCursor_StaticAssert:
Michael Kruse7520cf02020-03-25 09:26:14 -05005587 return cxstring::createRef("StaticAssert");
Olivier Goffartd211c642016-11-04 06:29:27 +00005588 case CXCursor_FriendDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005589 return cxstring::createRef("FriendDecl");
Sven van Haastregtdc2c9302019-02-11 11:00:56 +00005590 case CXCursor_ConvergentAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005591 return cxstring::createRef("attribute(convergent)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005592 case CXCursor_WarnUnusedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005593 return cxstring::createRef("attribute(warn_unused)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005594 case CXCursor_WarnUnusedResultAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005595 return cxstring::createRef("attribute(warn_unused_result)");
Emilio Cobos Alvarezcd741272019-03-13 16:16:54 +00005596 case CXCursor_AlignedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005597 return cxstring::createRef("attribute(aligned)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005598 }
5599
5600 llvm_unreachable("Unhandled CXCursorKind");
5601}
5602
5603struct GetCursorData {
5604 SourceLocation TokenBeginLoc;
5605 bool PointsAtMacroArgExpansion;
5606 bool VisitedObjCPropertyImplDecl;
5607 SourceLocation VisitedDeclaratorDeclStartLoc;
5608 CXCursor &BestCursor;
5609
Michael Kruse7520cf02020-03-25 09:26:14 -05005610 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5611 CXCursor &outputCursor)
5612 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005613 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5614 VisitedObjCPropertyImplDecl = false;
5615 }
5616};
5617
Michael Kruse7520cf02020-03-25 09:26:14 -05005618static enum CXChildVisitResult
5619GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005620 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5621 CXCursor *BestCursor = &Data->BestCursor;
5622
5623 // If we point inside a macro argument we should provide info of what the
5624 // token is so use the actual cursor, don't replace it with a macro expansion
5625 // cursor.
5626 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5627 return CXChildVisit_Recurse;
Michael Kruse7520cf02020-03-25 09:26:14 -05005628
Guy Benyei11169dd2012-12-18 14:30:41 +00005629 if (clang_isDeclaration(cursor.kind)) {
5630 // Avoid having the implicit methods override the property decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05005631 if (const ObjCMethodDecl *MD =
5632 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 if (MD->isImplicit())
5634 return CXChildVisit_Break;
5635
Michael Kruse7520cf02020-03-25 09:26:14 -05005636 } else if (const ObjCInterfaceDecl *ID =
5637 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005638 // Check that when we have multiple @class references in the same line,
5639 // that later ones do not override the previous ones.
5640 // If we have:
5641 // @class Foo, Bar;
5642 // source ranges for both start at '@', so 'Bar' will end up overriding
5643 // 'Foo' even though the cursor location was at 'Foo'.
5644 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5645 BestCursor->kind == CXCursor_ObjCClassRef)
Michael Kruse7520cf02020-03-25 09:26:14 -05005646 if (const ObjCInterfaceDecl *PrevID =
5647 dyn_cast_or_null<ObjCInterfaceDecl>(
5648 getCursorDecl(*BestCursor))) {
5649 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5650 !ID->isThisDeclarationADefinition())
5651 return CXChildVisit_Break;
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 }
5653
Michael Kruse7520cf02020-03-25 09:26:14 -05005654 } else if (const DeclaratorDecl *DD =
5655 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005656 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5657 // Check that when we have multiple declarators in the same line,
5658 // that later ones do not override the previous ones.
5659 // If we have:
5660 // int Foo, Bar;
5661 // source ranges for both start at 'int', so 'Bar' will end up overriding
5662 // 'Foo' even though the cursor location was at 'Foo'.
5663 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5664 return CXChildVisit_Break;
5665 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5666
Michael Kruse7520cf02020-03-25 09:26:14 -05005667 } else if (const ObjCPropertyImplDecl *PropImp =
5668 dyn_cast_or_null<ObjCPropertyImplDecl>(
5669 getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005670 (void)PropImp;
5671 // Check that when we have multiple @synthesize in the same line,
5672 // that later ones do not override the previous ones.
5673 // If we have:
5674 // @synthesize Foo, Bar;
5675 // source ranges for both start at '@', so 'Bar' will end up overriding
5676 // 'Foo' even though the cursor location was at 'Foo'.
5677 if (Data->VisitedObjCPropertyImplDecl)
5678 return CXChildVisit_Break;
5679 Data->VisitedObjCPropertyImplDecl = true;
5680 }
5681 }
5682
5683 if (clang_isExpression(cursor.kind) &&
5684 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005685 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005686 // Avoid having the cursor of an expression replace the declaration cursor
5687 // when the expression source range overlaps the declaration range.
5688 // This can happen for C++ constructor expressions whose range generally
5689 // include the variable declaration, e.g.:
Michael Kruse7520cf02020-03-25 09:26:14 -05005690 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5691 // cursor.
Guy Benyei11169dd2012-12-18 14:30:41 +00005692 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5693 D->getLocation() == Data->TokenBeginLoc)
5694 return CXChildVisit_Break;
5695 }
5696 }
5697
Michael Kruse7520cf02020-03-25 09:26:14 -05005698 // If our current best cursor is the construction of a temporary object,
5699 // don't replace that cursor with a type reference, because we want
Guy Benyei11169dd2012-12-18 14:30:41 +00005700 // clang_getCursor() to point at the constructor.
5701 if (clang_isExpression(BestCursor->kind) &&
5702 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5703 cursor.kind == CXCursor_TypeRef) {
5704 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5705 // as having the actual point on the type reference.
5706 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5707 return CXChildVisit_Recurse;
5708 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005709
5710 // If we already have an Objective-C superclass reference, don't
5711 // update it further.
5712 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5713 return CXChildVisit_Break;
5714
Guy Benyei11169dd2012-12-18 14:30:41 +00005715 *BestCursor = cursor;
5716 return CXChildVisit_Recurse;
5717}
5718
5719CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005720 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005721 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005723 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005724
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005725 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005726 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5727
5728 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5729 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5730
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005731 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005732 CXFile SearchFile;
5733 unsigned SearchLine, SearchColumn;
5734 CXFile ResultFile;
5735 unsigned ResultLine, ResultColumn;
5736 CXString SearchFileName, ResultFileName, KindSpelling, USR;
Michael Kruse7520cf02020-03-25 09:26:14 -05005737 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
Guy Benyei11169dd2012-12-18 14:30:41 +00005738 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005739
5740 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5741 nullptr);
Michael Kruse7520cf02020-03-25 09:26:14 -05005742 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5743 nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 SearchFileName = clang_getFileName(SearchFile);
5745 ResultFileName = clang_getFileName(ResultFile);
5746 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5747 USR = clang_getCursorUSR(Result);
Michael Kruse7520cf02020-03-25 09:26:14 -05005748 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5749 SearchLine, SearchColumn,
5750 clang_getCString(KindSpelling))
5751 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5752 ResultLine, ResultColumn, clang_getCString(USR),
5753 IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005754 clang_disposeString(SearchFileName);
5755 clang_disposeString(ResultFileName);
5756 clang_disposeString(KindSpelling);
5757 clang_disposeString(USR);
Michael Kruse7520cf02020-03-25 09:26:14 -05005758
Guy Benyei11169dd2012-12-18 14:30:41 +00005759 CXCursor Definition = clang_getCursorDefinition(Result);
5760 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5761 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
Michael Kruse7520cf02020-03-25 09:26:14 -05005762 CXString DefinitionKindSpelling =
5763 clang_getCursorKindSpelling(Definition.kind);
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 CXFile DefinitionFile;
5765 unsigned DefinitionLine, DefinitionColumn;
Michael Kruse7520cf02020-03-25 09:26:14 -05005766 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5767 &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005768 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005769 *Log << llvm::format(" -> %s(%s:%d:%d)",
Michael Kruse7520cf02020-03-25 09:26:14 -05005770 clang_getCString(DefinitionKindSpelling),
5771 clang_getCString(DefinitionFileName), DefinitionLine,
5772 DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 clang_disposeString(DefinitionFileName);
5774 clang_disposeString(DefinitionKindSpelling);
5775 }
5776 }
5777
5778 return Result;
5779}
5780
5781CXCursor clang_getNullCursor(void) {
5782 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5783}
5784
5785unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005786 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5787 // can't set consistently. For example, when visiting a DeclStmt we will set
5788 // it but we don't set it on the result of clang_getCursorDefinition for
5789 // a reference of the same declaration.
5790 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5791 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5792 // to provide that kind of info.
5793 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005794 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005795 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005796 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005797
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 return X == Y;
5799}
5800
5801unsigned clang_hashCursor(CXCursor C) {
5802 unsigned Index = 0;
5803 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5804 Index = 1;
Michael Kruse7520cf02020-03-25 09:26:14 -05005805
5806 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5807 std::make_pair(C.kind, C.data[Index]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005808}
5809
5810unsigned clang_isInvalid(enum CXCursorKind K) {
5811 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5812}
5813
5814unsigned clang_isDeclaration(enum CXCursorKind K) {
5815 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005816 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5817}
5818
Ivan Donchevskii08ff9102018-01-04 10:59:50 +00005819unsigned clang_isInvalidDeclaration(CXCursor C) {
5820 if (clang_isDeclaration(C.kind)) {
5821 if (const Decl *D = getCursorDecl(C))
5822 return D->isInvalidDecl();
5823 }
5824
5825 return 0;
5826}
5827
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005828unsigned clang_isReference(enum CXCursorKind K) {
5829 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5830}
Guy Benyei11169dd2012-12-18 14:30:41 +00005831
5832unsigned clang_isExpression(enum CXCursorKind K) {
5833 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5834}
5835
5836unsigned clang_isStatement(enum CXCursorKind K) {
5837 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5838}
5839
5840unsigned clang_isAttribute(enum CXCursorKind K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005841 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005842}
5843
5844unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5845 return K == CXCursor_TranslationUnit;
5846}
5847
5848unsigned clang_isPreprocessing(enum CXCursorKind K) {
5849 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5850}
Michael Kruse7520cf02020-03-25 09:26:14 -05005851
Guy Benyei11169dd2012-12-18 14:30:41 +00005852unsigned clang_isUnexposed(enum CXCursorKind K) {
5853 switch (K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005854 case CXCursor_UnexposedDecl:
5855 case CXCursor_UnexposedExpr:
5856 case CXCursor_UnexposedStmt:
5857 case CXCursor_UnexposedAttr:
5858 return true;
5859 default:
5860 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005861 }
5862}
5863
Michael Kruse7520cf02020-03-25 09:26:14 -05005864CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005865
5866CXSourceLocation clang_getCursorLocation(CXCursor C) {
5867 if (clang_isReference(C.kind)) {
5868 switch (C.kind) {
5869 case CXCursor_ObjCSuperClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005870 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5871 getCursorObjCSuperClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005872 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5873 }
5874
5875 case CXCursor_ObjCProtocolRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005876 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5877 getCursorObjCProtocolRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005878 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5879 }
5880
5881 case CXCursor_ObjCClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005882 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5883 getCursorObjCClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005884 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5885 }
5886
5887 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005888 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005889 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5890 }
5891
5892 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005893 std::pair<const TemplateDecl *, SourceLocation> P =
5894 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005895 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5896 }
5897
5898 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005899 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005900 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5901 }
5902
5903 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005904 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005905 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5906 }
5907
5908 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005909 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005910 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5911 }
5912
5913 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005914 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 if (!BaseSpec)
5916 return clang_getNullLocation();
Michael Kruse7520cf02020-03-25 09:26:14 -05005917
Guy Benyei11169dd2012-12-18 14:30:41 +00005918 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
Michael Kruse7520cf02020-03-25 09:26:14 -05005919 return cxloc::translateSourceLocation(
5920 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005921
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005923 BaseSpec->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 }
5925
5926 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005927 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005928 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5929 }
5930
5931 case CXCursor_OverloadedDeclRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005932 return cxloc::translateSourceLocation(
5933 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
Guy Benyei11169dd2012-12-18 14:30:41 +00005934
5935 default:
5936 // FIXME: Need a way to enumerate all non-reference cases.
5937 llvm_unreachable("Missed a reference kind");
5938 }
5939 }
5940
5941 if (clang_isExpression(C.kind))
Michael Kruse7520cf02020-03-25 09:26:14 -05005942 return cxloc::translateSourceLocation(
5943 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
Guy Benyei11169dd2012-12-18 14:30:41 +00005944
5945 if (clang_isStatement(C.kind))
5946 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005947 getCursorStmt(C)->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005948
5949 if (C.kind == CXCursor_PreprocessingDirective) {
5950 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5951 return cxloc::translateSourceLocation(getCursorContext(C), L);
5952 }
5953
5954 if (C.kind == CXCursor_MacroExpansion) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005955 SourceLocation L =
5956 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005957 return cxloc::translateSourceLocation(getCursorContext(C), L);
5958 }
5959
5960 if (C.kind == CXCursor_MacroDefinition) {
5961 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5962 return cxloc::translateSourceLocation(getCursorContext(C), L);
5963 }
5964
5965 if (C.kind == CXCursor_InclusionDirective) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005966 SourceLocation L =
5967 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005968 return cxloc::translateSourceLocation(getCursorContext(C), L);
5969 }
5970
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005971 if (clang_isAttribute(C.kind)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005972 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005973 return cxloc::translateSourceLocation(getCursorContext(C), L);
5974 }
5975
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 if (!clang_isDeclaration(C.kind))
5977 return clang_getNullLocation();
5978
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005979 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005980 if (!D)
5981 return clang_getNullLocation();
5982
5983 SourceLocation Loc = D->getLocation();
5984 // FIXME: Multiple variables declared in a single declaration
5985 // currently lack the information needed to correctly determine their
5986 // ranges when accounting for the type-specifier. We use context
5987 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5988 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005989 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005990 if (!cxcursor::isFirstInDeclGroup(C))
5991 Loc = VD->getLocation();
5992 }
5993
5994 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005995 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005996 Loc = MD->getSelectorStartLoc();
5997
5998 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5999}
6000
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00006001} // end extern "C"
6002
Guy Benyei11169dd2012-12-18 14:30:41 +00006003CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6004 assert(TU);
6005
6006 // Guard against an invalid SourceLocation, or we may assert in one
6007 // of the following calls.
6008 if (SLoc.isInvalid())
6009 return clang_getNullCursor();
6010
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006011 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006012
6013 // Translate the given source location to make it point at the beginning of
6014 // the token under the cursor.
6015 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6016 CXXUnit->getASTContext().getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05006017
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6019 if (SLoc.isValid()) {
6020 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6021 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Michael Kruse7520cf02020-03-25 09:26:14 -05006022 /*VisitPreprocessorLast=*/true,
Guy Benyei11169dd2012-12-18 14:30:41 +00006023 /*VisitIncludedEntities=*/false,
6024 SourceLocation(SLoc));
6025 CursorVis.visitFileRegion();
6026 }
6027
6028 return Result;
6029}
6030
6031static SourceRange getRawCursorExtent(CXCursor C) {
6032 if (clang_isReference(C.kind)) {
6033 switch (C.kind) {
6034 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05006035 return getCursorObjCSuperClassRef(C).second;
Guy Benyei11169dd2012-12-18 14:30:41 +00006036
6037 case CXCursor_ObjCProtocolRef:
6038 return getCursorObjCProtocolRef(C).second;
6039
6040 case CXCursor_ObjCClassRef:
6041 return getCursorObjCClassRef(C).second;
6042
6043 case CXCursor_TypeRef:
6044 return getCursorTypeRef(C).second;
6045
6046 case CXCursor_TemplateRef:
6047 return getCursorTemplateRef(C).second;
6048
6049 case CXCursor_NamespaceRef:
6050 return getCursorNamespaceRef(C).second;
6051
6052 case CXCursor_MemberRef:
6053 return getCursorMemberRef(C).second;
6054
6055 case CXCursor_CXXBaseSpecifier:
6056 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6057
6058 case CXCursor_LabelRef:
6059 return getCursorLabelRef(C).second;
6060
6061 case CXCursor_OverloadedDeclRef:
6062 return getCursorOverloadedDeclRef(C).second;
6063
6064 case CXCursor_VariableRef:
6065 return getCursorVariableRef(C).second;
Michael Kruse7520cf02020-03-25 09:26:14 -05006066
Guy Benyei11169dd2012-12-18 14:30:41 +00006067 default:
6068 // FIXME: Need a way to enumerate all non-reference cases.
6069 llvm_unreachable("Missed a reference kind");
6070 }
6071 }
6072
6073 if (clang_isExpression(C.kind))
6074 return getCursorExpr(C)->getSourceRange();
6075
6076 if (clang_isStatement(C.kind))
6077 return getCursorStmt(C)->getSourceRange();
6078
6079 if (clang_isAttribute(C.kind))
6080 return getCursorAttr(C)->getRange();
6081
6082 if (C.kind == CXCursor_PreprocessingDirective)
6083 return cxcursor::getCursorPreprocessingDirective(C);
6084
6085 if (C.kind == CXCursor_MacroExpansion) {
6086 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006087 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006088 return TU->mapRangeFromPreamble(Range);
6089 }
6090
6091 if (C.kind == CXCursor_MacroDefinition) {
6092 ASTUnit *TU = getCursorASTUnit(C);
6093 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6094 return TU->mapRangeFromPreamble(Range);
6095 }
6096
6097 if (C.kind == CXCursor_InclusionDirective) {
6098 ASTUnit *TU = getCursorASTUnit(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05006099 SourceRange Range =
6100 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006101 return TU->mapRangeFromPreamble(Range);
6102 }
6103
6104 if (C.kind == CXCursor_TranslationUnit) {
6105 ASTUnit *TU = getCursorASTUnit(C);
6106 FileID MainID = TU->getSourceManager().getMainFileID();
6107 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6108 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6109 return SourceRange(Start, End);
6110 }
6111
6112 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006113 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006114 if (!D)
6115 return SourceRange();
6116
6117 SourceRange R = D->getSourceRange();
6118 // FIXME: Multiple variables declared in a single declaration
6119 // currently lack the information needed to correctly determine their
6120 // ranges when accounting for the type-specifier. We use context
6121 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6122 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006123 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006124 if (!cxcursor::isFirstInDeclGroup(C))
6125 R.setBegin(VD->getLocation());
6126 }
6127 return R;
6128 }
6129 return SourceRange();
6130}
6131
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006132/// Retrieves the "raw" cursor extent, which is then extended to include
Guy Benyei11169dd2012-12-18 14:30:41 +00006133/// the decl-specifier-seq for declarations.
6134static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6135 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006136 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006137 if (!D)
6138 return SourceRange();
6139
6140 SourceRange R = D->getSourceRange();
6141
6142 // Adjust the start of the location for declarations preceded by
6143 // declaration specifiers.
6144 SourceLocation StartLoc;
6145 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6146 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006147 StartLoc = TI->getTypeLoc().getBeginLoc();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006148 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006150 StartLoc = TI->getTypeLoc().getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00006151 }
6152
6153 if (StartLoc.isValid() && R.getBegin().isValid() &&
6154 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6155 R.setBegin(StartLoc);
6156
6157 // FIXME: Multiple variables declared in a single declaration
6158 // currently lack the information needed to correctly determine their
6159 // ranges when accounting for the type-specifier. We use context
6160 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6161 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006162 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006163 if (!cxcursor::isFirstInDeclGroup(C))
6164 R.setBegin(VD->getLocation());
6165 }
6166
Michael Kruse7520cf02020-03-25 09:26:14 -05006167 return R;
Guy Benyei11169dd2012-12-18 14:30:41 +00006168 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006169
Guy Benyei11169dd2012-12-18 14:30:41 +00006170 return getRawCursorExtent(C);
6171}
6172
Guy Benyei11169dd2012-12-18 14:30:41 +00006173CXSourceRange clang_getCursorExtent(CXCursor C) {
6174 SourceRange R = getRawCursorExtent(C);
6175 if (R.isInvalid())
6176 return clang_getNullRange();
6177
6178 return cxloc::translateSourceRange(getCursorContext(C), R);
6179}
6180
6181CXCursor clang_getCursorReferenced(CXCursor C) {
6182 if (clang_isInvalid(C.kind))
6183 return clang_getNullCursor();
6184
6185 CXTranslationUnit tu = getCursorTU(C);
6186 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006187 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006188 if (!D)
6189 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006190 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006191 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006192 if (const ObjCPropertyImplDecl *PropImpl =
6193 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006194 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6195 return MakeCXCursor(Property, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006196
Guy Benyei11169dd2012-12-18 14:30:41 +00006197 return C;
6198 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006199
Guy Benyei11169dd2012-12-18 14:30:41 +00006200 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006201 const Expr *E = getCursorExpr(C);
6202 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00006203 if (D) {
6204 CXCursor declCursor = MakeCXCursor(D, tu);
6205 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6206 declCursor);
6207 return declCursor;
6208 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006209
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006210 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00006211 return MakeCursorOverloadedDeclRef(Ovl, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006212
Guy Benyei11169dd2012-12-18 14:30:41 +00006213 return clang_getNullCursor();
6214 }
6215
6216 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006217 const Stmt *S = getCursorStmt(C);
6218 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00006219 if (LabelDecl *label = Goto->getLabel())
6220 if (LabelStmt *labelS = label->getStmt())
Michael Kruse7520cf02020-03-25 09:26:14 -05006221 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006222
6223 return clang_getNullCursor();
6224 }
Richard Smith66a81862015-05-04 02:25:31 +00006225
Guy Benyei11169dd2012-12-18 14:30:41 +00006226 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00006227 if (const MacroDefinitionRecord *Def =
6228 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006229 return MakeMacroDefinitionCursor(Def, tu);
6230 }
6231
6232 if (!clang_isReference(C.kind))
6233 return clang_getNullCursor();
6234
6235 switch (C.kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006236 case CXCursor_ObjCSuperClassRef:
6237 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006238
Michael Kruse7520cf02020-03-25 09:26:14 -05006239 case CXCursor_ObjCProtocolRef: {
6240 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6241 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6242 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006243
Michael Kruse7520cf02020-03-25 09:26:14 -05006244 return MakeCXCursor(Prot, tu);
6245 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006246
Michael Kruse7520cf02020-03-25 09:26:14 -05006247 case CXCursor_ObjCClassRef: {
6248 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6249 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6250 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006251
Michael Kruse7520cf02020-03-25 09:26:14 -05006252 return MakeCXCursor(Class, tu);
6253 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006254
Michael Kruse7520cf02020-03-25 09:26:14 -05006255 case CXCursor_TypeRef:
6256 return MakeCXCursor(getCursorTypeRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006257
Michael Kruse7520cf02020-03-25 09:26:14 -05006258 case CXCursor_TemplateRef:
6259 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006260
Michael Kruse7520cf02020-03-25 09:26:14 -05006261 case CXCursor_NamespaceRef:
6262 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006263
Michael Kruse7520cf02020-03-25 09:26:14 -05006264 case CXCursor_MemberRef:
6265 return MakeCXCursor(getCursorMemberRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006266
Michael Kruse7520cf02020-03-25 09:26:14 -05006267 case CXCursor_CXXBaseSpecifier: {
6268 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6269 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6270 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006271
Michael Kruse7520cf02020-03-25 09:26:14 -05006272 case CXCursor_LabelRef:
6273 // FIXME: We end up faking the "parent" declaration here because we
6274 // don't want to make CXCursor larger.
6275 return MakeCXCursor(
6276 getCursorLabelRef(C).first,
6277 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006278
Michael Kruse7520cf02020-03-25 09:26:14 -05006279 case CXCursor_OverloadedDeclRef:
6280 return C;
Guy Benyei11169dd2012-12-18 14:30:41 +00006281
Michael Kruse7520cf02020-03-25 09:26:14 -05006282 case CXCursor_VariableRef:
6283 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6284
6285 default:
6286 // We would prefer to enumerate all non-reference cursor kinds here.
6287 llvm_unreachable("Unhandled reference cursor kind");
Guy Benyei11169dd2012-12-18 14:30:41 +00006288 }
6289}
6290
6291CXCursor clang_getCursorDefinition(CXCursor C) {
6292 if (clang_isInvalid(C.kind))
6293 return clang_getNullCursor();
6294
6295 CXTranslationUnit TU = getCursorTU(C);
6296
6297 bool WasReference = false;
6298 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6299 C = clang_getCursorReferenced(C);
6300 WasReference = true;
6301 }
6302
6303 if (C.kind == CXCursor_MacroExpansion)
6304 return clang_getCursorReferenced(C);
6305
6306 if (!clang_isDeclaration(C.kind))
6307 return clang_getNullCursor();
6308
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006309 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006310 if (!D)
6311 return clang_getNullCursor();
6312
6313 switch (D->getKind()) {
6314 // Declaration kinds that don't really separate the notions of
6315 // declaration and definition.
6316 case Decl::Namespace:
6317 case Decl::Typedef:
6318 case Decl::TypeAlias:
6319 case Decl::TypeAliasTemplate:
6320 case Decl::TemplateTypeParm:
6321 case Decl::EnumConstant:
6322 case Decl::Field:
Richard Smithbdb84f32016-07-22 23:36:59 +00006323 case Decl::Binding:
John McCall5e77d762013-04-16 07:28:30 +00006324 case Decl::MSProperty:
Richard Smithbab6df82020-04-11 22:15:29 -07006325 case Decl::MSGuid:
Guy Benyei11169dd2012-12-18 14:30:41 +00006326 case Decl::IndirectField:
6327 case Decl::ObjCIvar:
6328 case Decl::ObjCAtDefsField:
6329 case Decl::ImplicitParam:
6330 case Decl::ParmVar:
6331 case Decl::NonTypeTemplateParm:
6332 case Decl::TemplateTemplateParm:
6333 case Decl::ObjCCategoryImpl:
6334 case Decl::ObjCImplementation:
6335 case Decl::AccessSpec:
6336 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006337 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006338 case Decl::ObjCPropertyImpl:
6339 case Decl::FileScopeAsm:
6340 case Decl::StaticAssert:
6341 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006342 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006343 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006344 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006345 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006346 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006347 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006348 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006349 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006350 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006351 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006352 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006353 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006354 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006355 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006356 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006357 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006358 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006359 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006360 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006361 return C;
6362
6363 // Declaration kinds that don't make any sense here, but are
6364 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006365 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006366 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006367 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006368 break;
6369
6370 // Declaration kinds for which the definition is not resolvable.
6371 case Decl::UnresolvedUsingTypename:
6372 case Decl::UnresolvedUsingValue:
6373 break;
6374
6375 case Decl::UsingDirective:
6376 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6377 TU);
6378
6379 case Decl::NamespaceAlias:
6380 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6381
6382 case Decl::Enum:
6383 case Decl::Record:
6384 case Decl::CXXRecord:
6385 case Decl::ClassTemplateSpecialization:
6386 case Decl::ClassTemplatePartialSpecialization:
6387 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6388 return MakeCXCursor(Def, TU);
6389 return clang_getNullCursor();
6390
6391 case Decl::Function:
6392 case Decl::CXXMethod:
6393 case Decl::CXXConstructor:
6394 case Decl::CXXDestructor:
6395 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006396 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006397 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006398 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006399 return clang_getNullCursor();
6400 }
6401
Larisse Voufo39a1e502013-08-06 01:03:05 +00006402 case Decl::Var:
6403 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006404 case Decl::VarTemplatePartialSpecialization:
6405 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006406 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006407 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006408 return MakeCXCursor(Def, TU);
6409 return clang_getNullCursor();
6410 }
6411
6412 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006413 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6415 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6416 return clang_getNullCursor();
6417 }
6418
6419 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006420 if (RecordDecl *Def =
6421 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006422 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6423 TU);
6424 return clang_getNullCursor();
6425 }
6426
Larisse Voufo39a1e502013-08-06 01:03:05 +00006427 case Decl::VarTemplate: {
6428 if (VarDecl *Def =
6429 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6430 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6431 return clang_getNullCursor();
6432 }
6433
Guy Benyei11169dd2012-12-18 14:30:41 +00006434 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006435 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6436 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006437
6438 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006439 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006440 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006441 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006442
6443 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006444 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006445 if (Method->isThisDeclarationADefinition())
6446 return C;
6447
6448 // Dig out the method definition in the associated
6449 // @implementation, if we have it.
6450 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006451 if (const ObjCInterfaceDecl *Class =
6452 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006454 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6455 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006456 if (Def->isThisDeclarationADefinition())
6457 return MakeCXCursor(Def, TU);
6458
6459 return clang_getNullCursor();
6460 }
6461
6462 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006463 if (ObjCCategoryImplDecl *Impl =
6464 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006465 return MakeCXCursor(Impl, TU);
6466 return clang_getNullCursor();
6467
6468 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006469 if (const ObjCProtocolDecl *Def =
6470 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006471 return MakeCXCursor(Def, TU);
6472 return clang_getNullCursor();
6473
6474 case Decl::ObjCInterface: {
6475 // There are two notions of a "definition" for an Objective-C
6476 // class: the interface and its implementation. When we resolved a
6477 // reference to an Objective-C class, produce the @interface as
6478 // the definition; when we were provided with the interface,
6479 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006480 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006481 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006482 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006483 return MakeCXCursor(Def, TU);
6484 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6485 return MakeCXCursor(Impl, TU);
6486 return clang_getNullCursor();
6487 }
6488
6489 case Decl::ObjCProperty:
6490 // FIXME: We don't really know where to find the
6491 // ObjCPropertyImplDecls that implement this property.
6492 return clang_getNullCursor();
6493
6494 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006495 if (const ObjCInterfaceDecl *Class =
6496 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006497 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006498 return MakeCXCursor(Def, TU);
6499
6500 return clang_getNullCursor();
6501
6502 case Decl::Friend:
6503 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6504 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6505 return clang_getNullCursor();
6506
6507 case Decl::FriendTemplate:
6508 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6509 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6510 return clang_getNullCursor();
6511 }
6512
6513 return clang_getNullCursor();
6514}
6515
6516unsigned clang_isCursorDefinition(CXCursor C) {
6517 if (!clang_isDeclaration(C.kind))
6518 return 0;
6519
6520 return clang_getCursorDefinition(C) == C;
6521}
6522
6523CXCursor clang_getCanonicalCursor(CXCursor C) {
6524 if (!clang_isDeclaration(C.kind))
6525 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006526
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006527 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006528 if (const ObjCCategoryImplDecl *CatImplD =
6529 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006530 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6531 return MakeCXCursor(CatD, getCursorTU(C));
6532
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006533 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6534 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 return MakeCXCursor(IFD, getCursorTU(C));
6536
6537 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6538 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006539
Guy Benyei11169dd2012-12-18 14:30:41 +00006540 return C;
6541}
6542
6543int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6544 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6545}
Michael Kruse7520cf02020-03-25 09:26:14 -05006546
Guy Benyei11169dd2012-12-18 14:30:41 +00006547unsigned clang_getNumOverloadedDecls(CXCursor C) {
6548 if (C.kind != CXCursor_OverloadedDeclRef)
6549 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006550
Guy Benyei11169dd2012-12-18 14:30:41 +00006551 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006552 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006553 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006554
6555 if (OverloadedTemplateStorage *S =
6556 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006557 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006558
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006559 const Decl *D = Storage.get<const Decl *>();
6560 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006561 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006562
Guy Benyei11169dd2012-12-18 14:30:41 +00006563 return 0;
6564}
6565
6566CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6567 if (cursor.kind != CXCursor_OverloadedDeclRef)
6568 return clang_getNullCursor();
6569
6570 if (index >= clang_getNumOverloadedDecls(cursor))
6571 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006572
Guy Benyei11169dd2012-12-18 14:30:41 +00006573 CXTranslationUnit TU = getCursorTU(cursor);
6574 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006575 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006576 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006577
6578 if (OverloadedTemplateStorage *S =
6579 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006580 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006581
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006582 const Decl *D = Storage.get<const Decl *>();
6583 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006584 // FIXME: This is, unfortunately, linear time.
6585 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6586 std::advance(Pos, index);
6587 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6588 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006589
Guy Benyei11169dd2012-12-18 14:30:41 +00006590 return clang_getNullCursor();
6591}
Michael Kruse7520cf02020-03-25 09:26:14 -05006592
6593void clang_getDefinitionSpellingAndExtent(
6594 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6595 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006596 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006597 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006598 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6599
6600 SourceManager &SM = FD->getASTContext().getSourceManager();
6601 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6602 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6603 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6604 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6605 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6606 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6607}
6608
Guy Benyei11169dd2012-12-18 14:30:41 +00006609CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6610 unsigned PieceIndex) {
6611 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006612
Guy Benyei11169dd2012-12-18 14:30:41 +00006613 switch (C.kind) {
6614 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006615 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006616 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6617 E->getQualifierLoc().getSourceRange());
6618 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006619
Guy Benyei11169dd2012-12-18 14:30:41 +00006620 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006621 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6622 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6623 Pieces =
6624 buildPieces(NameFlags, false, E->getNameInfo(),
6625 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6626 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006627 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006628
Guy Benyei11169dd2012-12-18 14:30:41 +00006629 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006630 if (const CXXOperatorCallExpr *OCE =
6631 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006632 const Expr *Callee = OCE->getCallee();
6633 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006634 Callee = ICE->getSubExpr();
6635
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006636 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006637 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6638 DRE->getQualifierLoc().getSourceRange());
6639 }
6640 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006641
Guy Benyei11169dd2012-12-18 14:30:41 +00006642 default:
6643 break;
6644 }
6645
6646 if (Pieces.empty()) {
6647 if (PieceIndex == 0)
6648 return clang_getCursorExtent(C);
6649 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006650 SourceRange R = Pieces[PieceIndex];
6651 if (R.isValid())
6652 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006653 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006654
Guy Benyei11169dd2012-12-18 14:30:41 +00006655 return clang_getNullRange();
6656}
6657
6658void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006659 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6660 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006661}
6662
Michael Kruse7520cf02020-03-25 09:26:14 -05006663void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006664 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006665 llvm::llvm_execute_on_thread(fn, user_data,
6666 stack_size == 0
6667 ? clang::DesiredStackSize
6668 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006669}
6670
Guy Benyei11169dd2012-12-18 14:30:41 +00006671//===----------------------------------------------------------------------===//
6672// Token-based Operations.
6673//===----------------------------------------------------------------------===//
6674
6675/* CXToken layout:
6676 * int_data[0]: a CXTokenKind
6677 * int_data[1]: starting token location
6678 * int_data[2]: token length
6679 * int_data[3]: reserved
6680 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6681 * otherwise unused.
6682 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006683CXTokenKind clang_getTokenKind(CXToken CXTok) {
6684 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6685}
6686
6687CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6688 switch (clang_getTokenKind(CXTok)) {
6689 case CXToken_Identifier:
6690 case CXToken_Keyword:
6691 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006692 return cxstring::createRef(
6693 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006694
6695 case CXToken_Literal: {
6696 // We have stashed the starting pointer in the ptr_data field. Use it.
6697 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006698 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006699 }
6700
6701 case CXToken_Punctuation:
6702 case CXToken_Comment:
6703 break;
6704 }
6705
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006706 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006707 LOG_BAD_TU(TU);
6708 return cxstring::createEmpty();
6709 }
6710
Guy Benyei11169dd2012-12-18 14:30:41 +00006711 // We have to find the starting buffer pointer the hard way, by
6712 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006713 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006714 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006715 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006716
6717 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006718 std::pair<FileID, unsigned> LocInfo =
6719 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006720 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006721 StringRef Buffer =
6722 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006723 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006724 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006725
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006726 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006727}
6728
6729CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006730 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006731 LOG_BAD_TU(TU);
6732 return clang_getNullLocation();
6733 }
6734
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006735 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006736 if (!CXXUnit)
6737 return clang_getNullLocation();
6738
Michael Kruse7520cf02020-03-25 09:26:14 -05006739 return cxloc::translateSourceLocation(
6740 CXXUnit->getASTContext(),
6741 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006742}
6743
6744CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006745 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006746 LOG_BAD_TU(TU);
6747 return clang_getNullRange();
6748 }
6749
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006750 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006751 if (!CXXUnit)
6752 return clang_getNullRange();
6753
Michael Kruse7520cf02020-03-25 09:26:14 -05006754 return cxloc::translateSourceRange(
6755 CXXUnit->getASTContext(),
6756 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006757}
6758
6759static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6760 SmallVectorImpl<CXToken> &CXTokens) {
6761 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006762 std::pair<FileID, unsigned> BeginLocInfo =
6763 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6764 std::pair<FileID, unsigned> EndLocInfo =
6765 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006766
6767 // Cannot tokenize across files.
6768 if (BeginLocInfo.first != EndLocInfo.first)
6769 return;
6770
6771 // Create a lexer
6772 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006773 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006774 if (Invalid)
6775 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006776
Guy Benyei11169dd2012-12-18 14:30:41 +00006777 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006778 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6779 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006780 Lex.SetCommentRetentionState(true);
6781
6782 // Lex tokens until we hit the end of the range.
6783 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6784 Token Tok;
6785 bool previousWasAt = false;
6786 do {
6787 // Lex the next token
6788 Lex.LexFromRawLexer(Tok);
6789 if (Tok.is(tok::eof))
6790 break;
6791
6792 // Initialize the CXToken.
6793 CXToken CXTok;
6794
6795 // - Common fields
6796 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6797 CXTok.int_data[2] = Tok.getLength();
6798 CXTok.int_data[3] = 0;
6799
6800 // - Kind-specific fields
6801 if (Tok.isLiteral()) {
6802 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006803 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006804 } else if (Tok.is(tok::raw_identifier)) {
6805 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006806 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006807
6808 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6809 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006810 } else {
6811 CXTok.int_data[0] =
6812 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006813 }
6814 CXTok.ptr_data = II;
6815 } else if (Tok.is(tok::comment)) {
6816 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006817 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006818 } else {
6819 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006820 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006821 }
6822 CXTokens.push_back(CXTok);
6823 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006824 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006825}
6826
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006827CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006828 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006829
6830 if (isNotUsableTU(TU)) {
6831 LOG_BAD_TU(TU);
6832 return NULL;
6833 }
6834
6835 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6836 if (!CXXUnit)
6837 return NULL;
6838
6839 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6840 if (Begin.isInvalid())
6841 return NULL;
6842 SourceManager &SM = CXXUnit->getSourceManager();
6843 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006844 DecomposedEnd.second +=
6845 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006846
Michael Kruse7520cf02020-03-25 09:26:14 -05006847 SourceLocation End =
6848 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006849
6850 SmallVector<CXToken, 32> CXTokens;
6851 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6852
6853 if (CXTokens.empty())
6854 return NULL;
6855
6856 CXTokens.resize(1);
6857 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6858
6859 memmove(Token, CXTokens.data(), sizeof(CXToken));
6860 return Token;
6861}
6862
Michael Kruse7520cf02020-03-25 09:26:14 -05006863void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6864 unsigned *NumTokens) {
6865 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006866
Guy Benyei11169dd2012-12-18 14:30:41 +00006867 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006868 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006869 if (NumTokens)
6870 *NumTokens = 0;
6871
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006872 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006873 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006874 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006875 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006876
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006877 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006878 if (!CXXUnit || !Tokens || !NumTokens)
6879 return;
6880
6881 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006882
Guy Benyei11169dd2012-12-18 14:30:41 +00006883 SourceRange R = cxloc::translateCXSourceRange(Range);
6884 if (R.isInvalid())
6885 return;
6886
6887 SmallVector<CXToken, 32> CXTokens;
6888 getTokens(CXXUnit, R, CXTokens);
6889
6890 if (CXTokens.empty())
6891 return;
6892
Serge Pavlov52525732018-02-21 02:02:39 +00006893 *Tokens = static_cast<CXToken *>(
6894 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006895 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6896 *NumTokens = CXTokens.size();
6897}
6898
Michael Kruse7520cf02020-03-25 09:26:14 -05006899void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6900 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006901 free(Tokens);
6902}
6903
Guy Benyei11169dd2012-12-18 14:30:41 +00006904//===----------------------------------------------------------------------===//
6905// Token annotation APIs.
6906//===----------------------------------------------------------------------===//
6907
Guy Benyei11169dd2012-12-18 14:30:41 +00006908static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6909 CXCursor parent,
6910 CXClientData client_data);
6911static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6912 CXClientData client_data);
6913
6914namespace {
6915class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006916 CXToken *Tokens;
6917 CXCursor *Cursors;
6918 unsigned NumTokens;
6919 unsigned TokIdx;
6920 unsigned PreprocessingTokIdx;
6921 CursorVisitor AnnotateVis;
6922 SourceManager &SrcMgr;
6923 bool HasContextSensitiveKeywords;
6924
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006925 struct PostChildrenAction {
6926 CXCursor cursor;
6927 enum Action { Invalid, Ignore, Postpone } action;
6928 };
6929 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6930
Guy Benyei11169dd2012-12-18 14:30:41 +00006931 struct PostChildrenInfo {
6932 CXCursor Cursor;
6933 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006934 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006935 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006936 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006937 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006938 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006939
6940 CXToken &getTok(unsigned Idx) {
6941 assert(Idx < NumTokens);
6942 return Tokens[Idx];
6943 }
6944 const CXToken &getTok(unsigned Idx) const {
6945 assert(Idx < NumTokens);
6946 return Tokens[Idx];
6947 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006948 bool MoreTokens() const { return TokIdx < NumTokens; }
6949 unsigned NextToken() const { return TokIdx; }
6950 void AdvanceToken() { ++TokIdx; }
6951 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006952 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006953 }
6954 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006955 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006956 }
6957 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006958 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006959 }
6960
6961 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006962 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006963 SourceRange);
6964
6965public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006966 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006967 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05006968 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
6969 PreprocessingTokIdx(0),
6970 AnnotateVis(TU, AnnotateTokensVisitor, this,
6971 /*VisitPreprocessorLast=*/true,
6972 /*VisitIncludedEntities=*/false, RegionOfInterest,
6973 /*VisitDeclsOnly=*/false,
6974 AnnotateTokensPostChildrenVisitor),
6975 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
6976 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00006977
6978 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6979 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006980 bool IsIgnoredChildCursor(CXCursor cursor) const;
6981 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
6982
Guy Benyei11169dd2012-12-18 14:30:41 +00006983 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006984 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
6985 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
6986
Guy Benyei11169dd2012-12-18 14:30:41 +00006987 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05006988
6989 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00006990 /// context-sensitive keywords.
6991 bool hasContextSensitiveKeywords() const {
6992 return HasContextSensitiveKeywords;
6993 }
6994
Michael Kruse7520cf02020-03-25 09:26:14 -05006995 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00006996};
Michael Kruse7520cf02020-03-25 09:26:14 -05006997} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00006998
6999void AnnotateTokensWorker::AnnotateTokens() {
7000 // Walk the AST within the region of interest, annotating tokens
7001 // along the way.
7002 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007003}
Guy Benyei11169dd2012-12-18 14:30:41 +00007004
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007005bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7006 if (PostChildrenInfos.empty())
7007 return false;
7008
7009 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7010 if (ChildAction.cursor == cursor &&
7011 ChildAction.action == PostChildrenAction::Ignore) {
7012 return true;
7013 }
7014 }
7015
7016 return false;
7017}
7018
7019const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7020 if (!clang_isExpression(Cursor.kind))
7021 return nullptr;
7022
7023 const Expr *E = getCursorExpr(Cursor);
7024 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7025 const OverloadedOperatorKind Kind = OCE->getOperator();
7026 if (Kind == OO_Call || Kind == OO_Subscript)
7027 return OCE;
7028 }
7029
7030 return nullptr;
7031}
7032
7033AnnotateTokensWorker::PostChildrenActions
7034AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7035 PostChildrenActions actions;
7036
7037 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7038 // visited before the arguments to the operator call. For the Call and
7039 // Subscript operator the range of this DeclRefExpr includes the whole call
7040 // expression, so that all tokens in that range would be mapped to the
7041 // operator function, including the tokens of the arguments. To avoid that,
7042 // ensure to visit this DeclRefExpr as last node.
7043 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7044 const Expr *Callee = OCE->getCallee();
7045 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7046 const Expr *SubExpr = ICE->getSubExpr();
7047 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007048 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007049 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7050
7051 // Visit the DeclRefExpr as last.
7052 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7053 actions.push_back({cxChild, PostChildrenAction::Postpone});
7054
7055 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7056 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7057 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7058 actions.push_back({cxChild, PostChildrenAction::Ignore});
7059 }
7060 }
7061 }
7062
7063 return actions;
7064}
7065
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007066static inline void updateCursorAnnotation(CXCursor &Cursor,
7067 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007068 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007069 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007070 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007071}
7072
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007073/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007074//// between the cursor location and the source range is the same as
7075/// \arg compResult.
7076///
7077/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7078/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007079void AnnotateTokensWorker::annotateAndAdvanceTokens(
7080 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007081 while (MoreTokens()) {
7082 const unsigned I = NextToken();
7083 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007084 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7085 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007086
7087 SourceLocation TokLoc = GetTokenLoc(I);
7088 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007089 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007090 AdvanceToken();
7091 continue;
7092 }
7093 break;
7094 }
7095}
7096
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007097/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007098/// \returns true if it advanced beyond all macro tokens, false otherwise.
7099bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007100 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007101 assert(MoreTokens());
7102 assert(isFunctionMacroToken(NextToken()) &&
7103 "Should be called only for macro arg tokens");
7104
7105 // This works differently than annotateAndAdvanceTokens; because expanded
7106 // macro arguments can have arbitrary translation-unit source order, we do not
7107 // advance the token index one by one until a token fails the range test.
7108 // We only advance once past all of the macro arg tokens if all of them
7109 // pass the range test. If one of them fails we keep the token index pointing
7110 // at the start of the macro arg tokens so that the failing token will be
7111 // annotated by a subsequent annotation try.
7112
7113 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007114
Guy Benyei11169dd2012-12-18 14:30:41 +00007115 unsigned I = NextToken();
7116 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7117 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7118 if (TokLoc.isFileID())
7119 continue; // not macro arg token, it's parens or comma.
7120 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7121 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7122 Cursors[I] = updateC;
7123 } else
7124 atLeastOneCompFail = true;
7125 }
7126
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007127 if (atLeastOneCompFail)
7128 return false;
7129
7130 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7131 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007132}
7133
Michael Kruse7520cf02020-03-25 09:26:14 -05007134enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7135 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007136 SourceRange cursorRange = getRawCursorExtent(cursor);
7137 if (cursorRange.isInvalid())
7138 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007139
7140 if (IsIgnoredChildCursor(cursor))
7141 return CXChildVisit_Continue;
7142
Guy Benyei11169dd2012-12-18 14:30:41 +00007143 if (!HasContextSensitiveKeywords) {
7144 // Objective-C properties can have context-sensitive keywords.
7145 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007146 if (const ObjCPropertyDecl *Property =
7147 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7148 HasContextSensitiveKeywords =
7149 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007150 }
7151 // Objective-C methods can have context-sensitive keywords.
7152 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7153 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007154 if (const ObjCMethodDecl *Method =
7155 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007156 if (Method->getObjCDeclQualifier())
7157 HasContextSensitiveKeywords = true;
7158 else {
David Majnemer59f77922016-06-24 04:05:48 +00007159 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007160 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007161 HasContextSensitiveKeywords = true;
7162 break;
7163 }
7164 }
7165 }
7166 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007167 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007168 // C++ methods can have context-sensitive keywords.
7169 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007170 if (const CXXMethodDecl *Method =
7171 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007172 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7173 HasContextSensitiveKeywords = true;
7174 }
7175 }
7176 // C++ classes can have context-sensitive keywords.
7177 else if (cursor.kind == CXCursor_StructDecl ||
7178 cursor.kind == CXCursor_ClassDecl ||
7179 cursor.kind == CXCursor_ClassTemplate ||
7180 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007181 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007182 if (D->hasAttr<FinalAttr>())
7183 HasContextSensitiveKeywords = true;
7184 }
7185 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007186
7187 // Don't override a property annotation with its getter/setter method.
7188 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7189 parent.kind == CXCursor_ObjCPropertyDecl)
7190 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007191
7192 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007193 // Items in the preprocessing record are kept separate from items in
7194 // declarations, so we keep a separate token index.
7195 unsigned SavedTokIdx = TokIdx;
7196 TokIdx = PreprocessingTokIdx;
7197
7198 // Skip tokens up until we catch up to the beginning of the preprocessing
7199 // entry.
7200 while (MoreTokens()) {
7201 const unsigned I = NextToken();
7202 SourceLocation TokLoc = GetTokenLoc(I);
7203 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7204 case RangeBefore:
7205 AdvanceToken();
7206 continue;
7207 case RangeAfter:
7208 case RangeOverlap:
7209 break;
7210 }
7211 break;
7212 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007213
Guy Benyei11169dd2012-12-18 14:30:41 +00007214 // Look at all of the tokens within this range.
7215 while (MoreTokens()) {
7216 const unsigned I = NextToken();
7217 SourceLocation TokLoc = GetTokenLoc(I);
7218 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7219 case RangeBefore:
7220 llvm_unreachable("Infeasible");
7221 case RangeAfter:
7222 break;
7223 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007224 // For macro expansions, just note where the beginning of the macro
7225 // expansion occurs.
7226 if (cursor.kind == CXCursor_MacroExpansion) {
7227 if (TokLoc == cursorRange.getBegin())
7228 Cursors[I] = cursor;
7229 AdvanceToken();
7230 break;
7231 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007232 // We may have already annotated macro names inside macro definitions.
7233 if (Cursors[I].kind != CXCursor_MacroExpansion)
7234 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007235 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007236 continue;
7237 }
7238 break;
7239 }
7240
7241 // Save the preprocessing token index; restore the non-preprocessing
7242 // token index.
7243 PreprocessingTokIdx = TokIdx;
7244 TokIdx = SavedTokIdx;
7245 return CXChildVisit_Recurse;
7246 }
7247
7248 if (cursorRange.isInvalid())
7249 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007250
7251 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007252 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007253 const enum CXCursorKind K = clang_getCursorKind(parent);
7254 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007255 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7256 // Attributes are annotated out-of-order, skip tokens until we reach it.
7257 clang_isAttribute(cursor.kind))
7258 ? clang_getNullCursor()
7259 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007260
7261 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7262
7263 // Avoid having the cursor of an expression "overwrite" the annotation of the
7264 // variable declaration that it belongs to.
7265 // This can happen for C++ constructor expressions whose range generally
7266 // include the variable declaration, e.g.:
7267 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007268 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007269 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007270 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007271 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007272 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7273 E->getBeginLoc() == D->getLocation() &&
7274 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007275 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007276 AdvanceToken();
7277 }
7278 }
7279 }
7280
7281 // Before recursing into the children keep some state that we are going
7282 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7283 // extra work after the child nodes are visited.
7284 // Note that we don't call VisitChildren here to avoid traversing statements
7285 // code-recursively which can blow the stack.
7286
7287 PostChildrenInfo Info;
7288 Info.Cursor = cursor;
7289 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007290 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007291 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007292 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007293 PostChildrenInfos.push_back(Info);
7294
7295 return CXChildVisit_Recurse;
7296}
7297
7298bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7299 if (PostChildrenInfos.empty())
7300 return false;
7301 const PostChildrenInfo &Info = PostChildrenInfos.back();
7302 if (!clang_equalCursors(Info.Cursor, cursor))
7303 return false;
7304
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007305 HandlePostPonedChildCursors(Info);
7306
Guy Benyei11169dd2012-12-18 14:30:41 +00007307 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7308 const unsigned AfterChildren = NextToken();
7309 SourceRange cursorRange = Info.CursorRange;
7310
7311 // Scan the tokens that are at the end of the cursor, but are not captured
7312 // but the child cursors.
7313 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7314
7315 // Scan the tokens that are at the beginning of the cursor, but are not
7316 // capture by the child cursors.
7317 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7318 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7319 break;
7320
7321 Cursors[I] = cursor;
7322 }
7323
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007324 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7325 // encountered the attribute cursor.
7326 if (clang_isAttribute(cursor.kind))
7327 TokIdx = Info.BeforeReachingCursorIdx;
7328
Guy Benyei11169dd2012-12-18 14:30:41 +00007329 PostChildrenInfos.pop_back();
7330 return false;
7331}
7332
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007333void AnnotateTokensWorker::HandlePostPonedChildCursors(
7334 const PostChildrenInfo &Info) {
7335 for (const auto &ChildAction : Info.ChildActions) {
7336 if (ChildAction.action == PostChildrenAction::Postpone) {
7337 HandlePostPonedChildCursor(ChildAction.cursor,
7338 Info.BeforeChildrenTokenIdx);
7339 }
7340 }
7341}
7342
7343void AnnotateTokensWorker::HandlePostPonedChildCursor(
7344 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007345 unsigned I = StartTokenIndex;
7346
7347 // The bracket tokens of a Call or Subscript operator are mapped to
7348 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7349 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7350 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007351 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7352 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007353 if (clang_Range_isNull(CXRefNameRange))
7354 break; // All ranges handled.
7355
7356 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7357 while (I < NumTokens) {
7358 const SourceLocation TokenLocation = GetTokenLoc(I);
7359 if (!TokenLocation.isValid())
7360 break;
7361
7362 // Adapt the end range, because LocationCompare() reports
7363 // RangeOverlap even for the not-inclusive end location.
7364 const SourceLocation fixedEnd =
7365 RefNameRange.getEnd().getLocWithOffset(-1);
7366 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7367
7368 const RangeComparisonResult ComparisonResult =
7369 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7370
7371 if (ComparisonResult == RangeOverlap) {
7372 Cursors[I++] = Cursor;
7373 } else if (ComparisonResult == RangeBefore) {
7374 ++I; // Not relevant token, check next one.
7375 } else if (ComparisonResult == RangeAfter) {
7376 break; // All tokens updated for current range, check next.
7377 }
7378 }
7379 }
7380}
7381
Guy Benyei11169dd2012-12-18 14:30:41 +00007382static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7383 CXCursor parent,
7384 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007385 return static_cast<AnnotateTokensWorker *>(client_data)
7386 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007387}
7388
7389static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7390 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007391 return static_cast<AnnotateTokensWorker *>(client_data)
7392 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007393}
7394
7395namespace {
7396
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007397/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007398/// and mark tokens that are macro arguments. This info is used by the
7399/// AnnotateTokensWorker.
7400class MarkMacroArgTokensVisitor {
7401 SourceManager &SM;
7402 CXToken *Tokens;
7403 unsigned NumTokens;
7404 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007405
Guy Benyei11169dd2012-12-18 14:30:41 +00007406public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007407 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7408 unsigned numTokens)
7409 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007410
7411 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7412 if (cursor.kind != CXCursor_MacroExpansion)
7413 return CXChildVisit_Continue;
7414
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007415 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007416 if (macroRange.getBegin() == macroRange.getEnd())
7417 return CXChildVisit_Continue; // it's not a function macro.
7418
7419 for (; CurIdx < NumTokens; ++CurIdx) {
7420 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7421 macroRange.getBegin()))
7422 break;
7423 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007424
Guy Benyei11169dd2012-12-18 14:30:41 +00007425 if (CurIdx == NumTokens)
7426 return CXChildVisit_Break;
7427
7428 for (; CurIdx < NumTokens; ++CurIdx) {
7429 SourceLocation tokLoc = getTokenLoc(CurIdx);
7430 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7431 break;
7432
7433 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7434 }
7435
7436 if (CurIdx == NumTokens)
7437 return CXChildVisit_Break;
7438
7439 return CXChildVisit_Continue;
7440 }
7441
7442private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007443 CXToken &getTok(unsigned Idx) {
7444 assert(Idx < NumTokens);
7445 return Tokens[Idx];
7446 }
7447 const CXToken &getTok(unsigned Idx) const {
7448 assert(Idx < NumTokens);
7449 return Tokens[Idx];
7450 }
7451
Guy Benyei11169dd2012-12-18 14:30:41 +00007452 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007453 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007454 }
7455
7456 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7457 // The third field is reserved and currently not used. Use it here
7458 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007459 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007460 }
7461};
7462
7463} // end anonymous namespace
7464
7465static CXChildVisitResult
7466MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7467 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007468 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7469 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007470}
7471
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007472/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007473/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007474static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7475 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007476 if (NextIdx >= NumTokens)
7477 return true;
7478
7479 ++NextIdx;
7480 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007481 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007482}
7483
Guy Benyei11169dd2012-12-18 14:30:41 +00007484static void annotatePreprocessorTokens(CXTranslationUnit TU,
7485 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007486 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007487 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007488 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007489
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007490 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007491 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007492 std::pair<FileID, unsigned> BeginLocInfo =
7493 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7494 std::pair<FileID, unsigned> EndLocInfo =
7495 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007496
7497 if (BeginLocInfo.first != EndLocInfo.first)
7498 return;
7499
7500 StringRef Buffer;
7501 bool Invalid = false;
7502 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7503 if (Buffer.empty() || Invalid)
7504 return;
7505
7506 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007507 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7508 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007509 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007510
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007511 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007512 // Lex tokens in raw mode until we hit the end of the range, to avoid
7513 // entering #includes or expanding macros.
7514 while (true) {
7515 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007516 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7517 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007518 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007519 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007520 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7521
Guy Benyei11169dd2012-12-18 14:30:41 +00007522 reprocess:
7523 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007524 // We have found a preprocessing directive. Annotate the tokens
7525 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007526 //
7527 // FIXME: Some simple tests here could identify macro definitions and
7528 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007529
7530 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007531 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7532 break;
7533
Craig Topper69186e72014-06-08 08:38:04 +00007534 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007535 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007536 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7537 break;
7538
7539 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007540 IdentifierInfo &II =
7541 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007542 SourceLocation MappedTokLoc =
7543 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7544 MI = getMacroInfo(II, MappedTokLoc, TU);
7545 }
7546 }
7547
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007548 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007549 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007550 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7551 finished = true;
7552 break;
7553 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007554 // If we are in a macro definition, check if the token was ever a
7555 // macro name and annotate it if that's the case.
7556 if (MI) {
7557 SourceLocation SaveLoc = Tok.getLocation();
7558 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007559 MacroDefinitionRecord *MacroDef =
7560 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007561 Tok.setLocation(SaveLoc);
7562 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007563 Cursors[NextIdx - 1] =
7564 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007565 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007566 } while (!Tok.isAtStartOfLine());
7567
Michael Kruse7520cf02020-03-25 09:26:14 -05007568 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007569 assert(TokIdx <= LastIdx);
7570 SourceLocation EndLoc =
7571 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7572 CXCursor Cursor =
7573 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7574
7575 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007576 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007577
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007578 if (finished)
7579 break;
7580 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007581 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007582 }
7583}
7584
7585// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007586static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7587 CXToken *Tokens, unsigned NumTokens,
7588 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007589 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007590 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7591 setThreadBackgroundPriority();
7592
7593 // Determine the region of interest, which contains all of the tokens.
7594 SourceRange RegionOfInterest;
7595 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007596 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7597 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7598 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007599
Guy Benyei11169dd2012-12-18 14:30:41 +00007600 // Relex the tokens within the source range to look for preprocessing
7601 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007602 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007603
7604 // If begin location points inside a macro argument, set it to the expansion
7605 // location so we can have the full context when annotating semantically.
7606 {
7607 SourceManager &SM = CXXUnit->getSourceManager();
7608 SourceLocation Loc =
7609 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7610 if (Loc.isMacroID())
7611 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7612 }
7613
Guy Benyei11169dd2012-12-18 14:30:41 +00007614 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7615 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007616 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7617 NumTokens);
7618 CursorVisitor MacroArgMarker(
7619 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7620 /*VisitPreprocessorLast=*/true,
7621 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007622 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7623 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007624
Guy Benyei11169dd2012-12-18 14:30:41 +00007625 // Annotate all of the source locations in the region of interest that map to
7626 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007627 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007628
Guy Benyei11169dd2012-12-18 14:30:41 +00007629 // FIXME: We use a ridiculous stack size here because the data-recursion
7630 // algorithm uses a large stack frame than the non-data recursive version,
7631 // and AnnotationTokensWorker currently transforms the data-recursion
7632 // algorithm back into a traditional recursion by explicitly calling
7633 // VisitChildren(). We will need to remove this explicit recursive call.
7634 W.AnnotateTokens();
7635
7636 // If we ran into any entities that involve context-sensitive keywords,
7637 // take another pass through the tokens to mark them as such.
7638 if (W.hasContextSensitiveKeywords()) {
7639 for (unsigned I = 0; I != NumTokens; ++I) {
7640 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7641 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007642
Guy Benyei11169dd2012-12-18 14:30:41 +00007643 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7644 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007645 if (const ObjCPropertyDecl *Property =
7646 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007647 if (Property->getPropertyAttributesAsWritten() != 0 &&
7648 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007649 .Case("readonly", true)
7650 .Case("assign", true)
7651 .Case("unsafe_unretained", true)
7652 .Case("readwrite", true)
7653 .Case("retain", true)
7654 .Case("copy", true)
7655 .Case("nonatomic", true)
7656 .Case("atomic", true)
7657 .Case("getter", true)
7658 .Case("setter", true)
7659 .Case("strong", true)
7660 .Case("weak", true)
7661 .Case("class", true)
7662 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007663 Tokens[I].int_data[0] = CXToken_Keyword;
7664 }
7665 continue;
7666 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007667
Guy Benyei11169dd2012-12-18 14:30:41 +00007668 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7669 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7670 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7671 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007672 .Case("in", true)
7673 .Case("out", true)
7674 .Case("inout", true)
7675 .Case("oneway", true)
7676 .Case("bycopy", true)
7677 .Case("byref", true)
7678 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007679 Tokens[I].int_data[0] = CXToken_Keyword;
7680 continue;
7681 }
7682
7683 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7684 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7685 Tokens[I].int_data[0] = CXToken_Keyword;
7686 continue;
7687 }
7688 }
7689 }
7690}
7691
Michael Kruse7520cf02020-03-25 09:26:14 -05007692void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7693 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007694 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007695 LOG_BAD_TU(TU);
7696 return;
7697 }
7698 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007699 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007700 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007701 }
7702
7703 LOG_FUNC_SECTION {
7704 *Log << TU << ' ';
7705 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007706 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007707 *Log << clang_getRange(bloc, eloc);
7708 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007709
7710 // Any token we don't specifically annotate will have a NULL cursor.
7711 CXCursor C = clang_getNullCursor();
7712 for (unsigned I = 0; I != NumTokens; ++I)
7713 Cursors[I] = C;
7714
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007715 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007716 if (!CXXUnit)
7717 return;
7718
7719 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007720
7721 auto AnnotateTokensImpl = [=]() {
7722 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7723 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007724 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007725 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007726 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7727 }
7728}
7729
Guy Benyei11169dd2012-12-18 14:30:41 +00007730//===----------------------------------------------------------------------===//
7731// Operations for querying linkage of a cursor.
7732//===----------------------------------------------------------------------===//
7733
Guy Benyei11169dd2012-12-18 14:30:41 +00007734CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7735 if (!clang_isDeclaration(cursor.kind))
7736 return CXLinkage_Invalid;
7737
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007738 const Decl *D = cxcursor::getCursorDecl(cursor);
7739 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007740 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007741 case NoLinkage:
7742 case VisibleNoLinkage:
7743 return CXLinkage_NoLinkage;
7744 case ModuleInternalLinkage:
7745 case InternalLinkage:
7746 return CXLinkage_Internal;
7747 case UniqueExternalLinkage:
7748 return CXLinkage_UniqueExternal;
7749 case ModuleLinkage:
7750 case ExternalLinkage:
7751 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007752 };
7753
7754 return CXLinkage_Invalid;
7755}
Guy Benyei11169dd2012-12-18 14:30:41 +00007756
7757//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007758// Operations for querying visibility of a cursor.
7759//===----------------------------------------------------------------------===//
7760
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007761CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7762 if (!clang_isDeclaration(cursor.kind))
7763 return CXVisibility_Invalid;
7764
7765 const Decl *D = cxcursor::getCursorDecl(cursor);
7766 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7767 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007768 case HiddenVisibility:
7769 return CXVisibility_Hidden;
7770 case ProtectedVisibility:
7771 return CXVisibility_Protected;
7772 case DefaultVisibility:
7773 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007774 };
7775
7776 return CXVisibility_Invalid;
7777}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007778
7779//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007780// Operations for querying language of a cursor.
7781//===----------------------------------------------------------------------===//
7782
7783static CXLanguageKind getDeclLanguage(const Decl *D) {
7784 if (!D)
7785 return CXLanguage_C;
7786
7787 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007788 default:
7789 break;
7790 case Decl::ImplicitParam:
7791 case Decl::ObjCAtDefsField:
7792 case Decl::ObjCCategory:
7793 case Decl::ObjCCategoryImpl:
7794 case Decl::ObjCCompatibleAlias:
7795 case Decl::ObjCImplementation:
7796 case Decl::ObjCInterface:
7797 case Decl::ObjCIvar:
7798 case Decl::ObjCMethod:
7799 case Decl::ObjCProperty:
7800 case Decl::ObjCPropertyImpl:
7801 case Decl::ObjCProtocol:
7802 case Decl::ObjCTypeParam:
7803 return CXLanguage_ObjC;
7804 case Decl::CXXConstructor:
7805 case Decl::CXXConversion:
7806 case Decl::CXXDestructor:
7807 case Decl::CXXMethod:
7808 case Decl::CXXRecord:
7809 case Decl::ClassTemplate:
7810 case Decl::ClassTemplatePartialSpecialization:
7811 case Decl::ClassTemplateSpecialization:
7812 case Decl::Friend:
7813 case Decl::FriendTemplate:
7814 case Decl::FunctionTemplate:
7815 case Decl::LinkageSpec:
7816 case Decl::Namespace:
7817 case Decl::NamespaceAlias:
7818 case Decl::NonTypeTemplateParm:
7819 case Decl::StaticAssert:
7820 case Decl::TemplateTemplateParm:
7821 case Decl::TemplateTypeParm:
7822 case Decl::UnresolvedUsingTypename:
7823 case Decl::UnresolvedUsingValue:
7824 case Decl::Using:
7825 case Decl::UsingDirective:
7826 case Decl::UsingShadow:
7827 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007828 }
7829
7830 return CXLanguage_C;
7831}
7832
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007833static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7834 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007835 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007836
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007837 switch (D->getAvailability()) {
7838 case AR_Available:
7839 case AR_NotYetIntroduced:
7840 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007841 return getCursorAvailabilityForDecl(
7842 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007843 return CXAvailability_Available;
7844
7845 case AR_Deprecated:
7846 return CXAvailability_Deprecated;
7847
7848 case AR_Unavailable:
7849 return CXAvailability_NotAvailable;
7850 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007851
7852 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007853}
7854
Guy Benyei11169dd2012-12-18 14:30:41 +00007855enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7856 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007857 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7858 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007859
7860 return CXAvailability_Available;
7861}
7862
7863static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007864 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007865 if (In.empty())
7866 return Out;
7867
7868 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007869
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007870 Optional<unsigned> Minor = In.getMinor();
7871 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007872 Out.Minor = *Minor;
7873 else
7874 return Out;
7875
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007876 Optional<unsigned> Subminor = In.getSubminor();
7877 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007878 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007879
Guy Benyei11169dd2012-12-18 14:30:41 +00007880 return Out;
7881}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007882
Alex Lorenz1345ea22017-06-12 19:06:30 +00007883static void getCursorPlatformAvailabilityForDecl(
7884 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7885 int *always_unavailable, CXString *unavailable_message,
7886 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007887 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007888 for (auto A : D->attrs()) {
7889 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007890 HadAvailAttr = true;
7891 if (always_deprecated)
7892 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007893 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007894 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007895 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007896 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007897 continue;
7898 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007899
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007900 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007901 HadAvailAttr = true;
7902 if (always_unavailable)
7903 *always_unavailable = 1;
7904 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007905 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007906 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7907 }
7908 continue;
7909 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007910
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007911 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007912 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007913 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007914 }
7915 }
7916
7917 if (!HadAvailAttr)
7918 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7919 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007920 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7921 deprecated_message, always_unavailable, unavailable_message,
7922 AvailabilityAttrs);
7923
7924 if (AvailabilityAttrs.empty())
7925 return;
7926
Michael Kruse7520cf02020-03-25 09:26:14 -05007927 llvm::sort(
7928 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7929 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7930 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007931 ASTContext &Ctx = D->getASTContext();
7932 auto It = std::unique(
7933 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7934 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7935 if (LHS->getPlatform() != RHS->getPlatform())
7936 return false;
7937
7938 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7939 LHS->getDeprecated() == RHS->getDeprecated() &&
7940 LHS->getObsoleted() == RHS->getObsoleted() &&
7941 LHS->getMessage() == RHS->getMessage() &&
7942 LHS->getReplacement() == RHS->getReplacement())
7943 return true;
7944
7945 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
7946 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
7947 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
7948 return false;
7949
7950 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
7951 LHS->setIntroduced(Ctx, RHS->getIntroduced());
7952
7953 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
7954 LHS->setDeprecated(Ctx, RHS->getDeprecated());
7955 if (LHS->getMessage().empty())
7956 LHS->setMessage(Ctx, RHS->getMessage());
7957 if (LHS->getReplacement().empty())
7958 LHS->setReplacement(Ctx, RHS->getReplacement());
7959 }
7960
7961 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
7962 LHS->setObsoleted(Ctx, RHS->getObsoleted());
7963 if (LHS->getMessage().empty())
7964 LHS->setMessage(Ctx, RHS->getMessage());
7965 if (LHS->getReplacement().empty())
7966 LHS->setReplacement(Ctx, RHS->getReplacement());
7967 }
7968
7969 return true;
7970 });
7971 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007972}
7973
Alex Lorenz1345ea22017-06-12 19:06:30 +00007974int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00007975 CXString *deprecated_message,
7976 int *always_unavailable,
7977 CXString *unavailable_message,
7978 CXPlatformAvailability *availability,
7979 int availability_size) {
7980 if (always_deprecated)
7981 *always_deprecated = 0;
7982 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007983 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007984 if (always_unavailable)
7985 *always_unavailable = 0;
7986 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007987 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007988
Guy Benyei11169dd2012-12-18 14:30:41 +00007989 if (!clang_isDeclaration(cursor.kind))
7990 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007991
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007992 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007993 if (!D)
7994 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007995
Alex Lorenz1345ea22017-06-12 19:06:30 +00007996 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
7997 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
7998 always_unavailable, unavailable_message,
7999 AvailabilityAttrs);
8000 for (const auto &Avail :
8001 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8002 .take_front(availability_size))) {
8003 availability[Avail.index()].Platform =
8004 cxstring::createDup(Avail.value()->getPlatform()->getName());
8005 availability[Avail.index()].Introduced =
8006 convertVersion(Avail.value()->getIntroduced());
8007 availability[Avail.index()].Deprecated =
8008 convertVersion(Avail.value()->getDeprecated());
8009 availability[Avail.index()].Obsoleted =
8010 convertVersion(Avail.value()->getObsoleted());
8011 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8012 availability[Avail.index()].Message =
8013 cxstring::createDup(Avail.value()->getMessage());
8014 }
8015
8016 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008017}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008018
Guy Benyei11169dd2012-12-18 14:30:41 +00008019void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8020 clang_disposeString(availability->Platform);
8021 clang_disposeString(availability->Message);
8022}
8023
8024CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8025 if (clang_isDeclaration(cursor.kind))
8026 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8027
8028 return CXLanguage_Invalid;
8029}
8030
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008031CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8032 const Decl *D = cxcursor::getCursorDecl(cursor);
8033 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8034 switch (VD->getTLSKind()) {
8035 case VarDecl::TLS_None:
8036 return CXTLS_None;
8037 case VarDecl::TLS_Dynamic:
8038 return CXTLS_Dynamic;
8039 case VarDecl::TLS_Static:
8040 return CXTLS_Static;
8041 }
8042 }
8043
8044 return CXTLS_None;
8045}
8046
Michael Kruse7520cf02020-03-25 09:26:14 -05008047/// If the given cursor is the "templated" declaration
8048/// describing a class or function template, return the class or
8049/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008050static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008051 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008052 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008053
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008054 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008055 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8056 return FunTmpl;
8057
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008058 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008059 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8060 return ClassTmpl;
8061
8062 return D;
8063}
8064
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008065enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8066 StorageClass sc = SC_None;
8067 const Decl *D = getCursorDecl(C);
8068 if (D) {
8069 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8070 sc = FD->getStorageClass();
8071 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8072 sc = VD->getStorageClass();
8073 } else {
8074 return CX_SC_Invalid;
8075 }
8076 } else {
8077 return CX_SC_Invalid;
8078 }
8079 switch (sc) {
8080 case SC_None:
8081 return CX_SC_None;
8082 case SC_Extern:
8083 return CX_SC_Extern;
8084 case SC_Static:
8085 return CX_SC_Static;
8086 case SC_PrivateExtern:
8087 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008088 case SC_Auto:
8089 return CX_SC_Auto;
8090 case SC_Register:
8091 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008092 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008093 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008094}
8095
Guy Benyei11169dd2012-12-18 14:30:41 +00008096CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8097 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008098 if (const Decl *D = getCursorDecl(cursor)) {
8099 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008100 if (!DC)
8101 return clang_getNullCursor();
8102
Michael Kruse7520cf02020-03-25 09:26:14 -05008103 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008104 getCursorTU(cursor));
8105 }
8106 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008107
Guy Benyei11169dd2012-12-18 14:30:41 +00008108 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008109 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008110 return MakeCXCursor(D, getCursorTU(cursor));
8111 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008112
Guy Benyei11169dd2012-12-18 14:30:41 +00008113 return clang_getNullCursor();
8114}
8115
8116CXCursor clang_getCursorLexicalParent(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->getLexicalDeclContext();
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 }
8127
Michael Kruse7520cf02020-03-25 09:26:14 -05008128 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008129 // statement or expression, so we return nothing.
8130 return clang_getNullCursor();
8131}
8132
8133CXFile clang_getIncludedFile(CXCursor cursor) {
8134 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008135 return nullptr;
8136
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008137 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008138 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008139}
8140
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008141unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8142 if (C.kind != CXCursor_ObjCPropertyDecl)
8143 return CXObjCPropertyAttr_noattr;
8144
8145 unsigned Result = CXObjCPropertyAttr_noattr;
8146 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8147 ObjCPropertyDecl::PropertyAttributeKind Attr =
8148 PD->getPropertyAttributesAsWritten();
8149
Michael Kruse7520cf02020-03-25 09:26:14 -05008150#define SET_CXOBJCPROP_ATTR(A) \
8151 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
8152 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008153 SET_CXOBJCPROP_ATTR(readonly);
8154 SET_CXOBJCPROP_ATTR(getter);
8155 SET_CXOBJCPROP_ATTR(assign);
8156 SET_CXOBJCPROP_ATTR(readwrite);
8157 SET_CXOBJCPROP_ATTR(retain);
8158 SET_CXOBJCPROP_ATTR(copy);
8159 SET_CXOBJCPROP_ATTR(nonatomic);
8160 SET_CXOBJCPROP_ATTR(setter);
8161 SET_CXOBJCPROP_ATTR(atomic);
8162 SET_CXOBJCPROP_ATTR(weak);
8163 SET_CXOBJCPROP_ATTR(strong);
8164 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008165 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008166#undef SET_CXOBJCPROP_ATTR
8167
8168 return Result;
8169}
8170
Michael Wu6e88f532018-08-03 05:38:29 +00008171CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8172 if (C.kind != CXCursor_ObjCPropertyDecl)
8173 return cxstring::createNull();
8174
8175 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8176 Selector sel = PD->getGetterName();
8177 if (sel.isNull())
8178 return cxstring::createNull();
8179
8180 return cxstring::createDup(sel.getAsString());
8181}
8182
8183CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8184 if (C.kind != CXCursor_ObjCPropertyDecl)
8185 return cxstring::createNull();
8186
8187 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8188 Selector sel = PD->getSetterName();
8189 if (sel.isNull())
8190 return cxstring::createNull();
8191
8192 return cxstring::createDup(sel.getAsString());
8193}
8194
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008195unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8196 if (!clang_isDeclaration(C.kind))
8197 return CXObjCDeclQualifier_None;
8198
8199 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8200 const Decl *D = getCursorDecl(C);
8201 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8202 QT = MD->getObjCDeclQualifier();
8203 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8204 QT = PD->getObjCDeclQualifier();
8205 if (QT == Decl::OBJC_TQ_None)
8206 return CXObjCDeclQualifier_None;
8207
8208 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008209 if (QT & Decl::OBJC_TQ_In)
8210 Result |= CXObjCDeclQualifier_In;
8211 if (QT & Decl::OBJC_TQ_Inout)
8212 Result |= CXObjCDeclQualifier_Inout;
8213 if (QT & Decl::OBJC_TQ_Out)
8214 Result |= CXObjCDeclQualifier_Out;
8215 if (QT & Decl::OBJC_TQ_Bycopy)
8216 Result |= CXObjCDeclQualifier_Bycopy;
8217 if (QT & Decl::OBJC_TQ_Byref)
8218 Result |= CXObjCDeclQualifier_Byref;
8219 if (QT & Decl::OBJC_TQ_Oneway)
8220 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008221
8222 return Result;
8223}
8224
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008225unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8226 if (!clang_isDeclaration(C.kind))
8227 return 0;
8228
8229 const Decl *D = getCursorDecl(C);
8230 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8231 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8232 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8233 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8234
8235 return 0;
8236}
8237
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008238unsigned clang_Cursor_isVariadic(CXCursor C) {
8239 if (!clang_isDeclaration(C.kind))
8240 return 0;
8241
8242 const Decl *D = getCursorDecl(C);
8243 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8244 return FD->isVariadic();
8245 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8246 return MD->isVariadic();
8247
8248 return 0;
8249}
8250
Michael Kruse7520cf02020-03-25 09:26:14 -05008251unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8252 CXString *definedIn,
8253 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008254 if (!clang_isDeclaration(C.kind))
8255 return 0;
8256
8257 const Decl *D = getCursorDecl(C);
8258
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008259 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008260 if (language)
8261 *language = cxstring::createDup(attr->getLanguage());
8262 if (definedIn)
8263 *definedIn = cxstring::createDup(attr->getDefinedIn());
8264 if (isGenerated)
8265 *isGenerated = attr->getGeneratedDeclaration();
8266 return 1;
8267 }
8268 return 0;
8269}
8270
Guy Benyei11169dd2012-12-18 14:30:41 +00008271CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8272 if (!clang_isDeclaration(C.kind))
8273 return clang_getNullRange();
8274
8275 const Decl *D = getCursorDecl(C);
8276 ASTContext &Context = getCursorContext(C);
8277 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8278 if (!RC)
8279 return clang_getNullRange();
8280
8281 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8282}
8283
8284CXString clang_Cursor_getRawCommentText(CXCursor C) {
8285 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008286 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008287
8288 const Decl *D = getCursorDecl(C);
8289 ASTContext &Context = getCursorContext(C);
8290 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008291 StringRef RawText =
8292 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008293
8294 // Don't duplicate the string because RawText points directly into source
8295 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008296 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008297}
8298
8299CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8300 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008301 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008302
8303 const Decl *D = getCursorDecl(C);
8304 const ASTContext &Context = getCursorContext(C);
8305 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8306
8307 if (RC) {
8308 StringRef BriefText = RC->getBriefText(Context);
8309
8310 // Don't duplicate the string because RawComment ensures that this memory
8311 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008312 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008313 }
8314
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008315 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008316}
8317
Guy Benyei11169dd2012-12-18 14:30:41 +00008318CXModule clang_Cursor_getModule(CXCursor C) {
8319 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008320 if (const ImportDecl *ImportD =
8321 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008322 return ImportD->getImportedModule();
8323 }
8324
Craig Topper69186e72014-06-08 08:38:04 +00008325 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008326}
8327
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008328CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8329 if (isNotUsableTU(TU)) {
8330 LOG_BAD_TU(TU);
8331 return nullptr;
8332 }
8333 if (!File)
8334 return nullptr;
8335 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008336
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008337 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8338 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8339 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008340
Richard Smithfeb54b62014-10-23 02:01:19 +00008341 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008342}
8343
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008344CXFile clang_Module_getASTFile(CXModule CXMod) {
8345 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008346 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008347 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008348 return const_cast<FileEntry *>(Mod->getASTFile());
8349}
8350
Guy Benyei11169dd2012-12-18 14:30:41 +00008351CXModule clang_Module_getParent(CXModule CXMod) {
8352 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008353 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008354 Module *Mod = static_cast<Module *>(CXMod);
Guy Benyei11169dd2012-12-18 14:30:41 +00008355 return Mod->Parent;
8356}
8357
8358CXString clang_Module_getName(CXModule CXMod) {
8359 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008360 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008361 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008362 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008363}
8364
8365CXString clang_Module_getFullName(CXModule CXMod) {
8366 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008367 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008368 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008369 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008370}
8371
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008372int clang_Module_isSystem(CXModule CXMod) {
8373 if (!CXMod)
8374 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008375 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008376 return Mod->IsSystem;
8377}
8378
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008379unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8380 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008381 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008382 LOG_BAD_TU(TU);
8383 return 0;
8384 }
8385 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008386 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008387 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008388 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8389 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8390 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008391}
8392
Michael Kruse7520cf02020-03-25 09:26:14 -05008393CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8394 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008395 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008396 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008397 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008398 }
8399 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008400 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008401 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008402 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008403
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008404 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8405 if (Index < TopHeaders.size())
8406 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008407
Craig Topper69186e72014-06-08 08:38:04 +00008408 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008409}
8410
Guy Benyei11169dd2012-12-18 14:30:41 +00008411//===----------------------------------------------------------------------===//
8412// C++ AST instrospection.
8413//===----------------------------------------------------------------------===//
8414
Jonathan Coe29565352016-04-27 12:48:25 +00008415unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8416 if (!clang_isDeclaration(C.kind))
8417 return 0;
8418
8419 const Decl *D = cxcursor::getCursorDecl(C);
8420 const CXXConstructorDecl *Constructor =
8421 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8422 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8423}
8424
8425unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8426 if (!clang_isDeclaration(C.kind))
8427 return 0;
8428
8429 const Decl *D = cxcursor::getCursorDecl(C);
8430 const CXXConstructorDecl *Constructor =
8431 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8432 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8433}
8434
8435unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8436 if (!clang_isDeclaration(C.kind))
8437 return 0;
8438
8439 const Decl *D = cxcursor::getCursorDecl(C);
8440 const CXXConstructorDecl *Constructor =
8441 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8442 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8443}
8444
8445unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8446 if (!clang_isDeclaration(C.kind))
8447 return 0;
8448
8449 const Decl *D = cxcursor::getCursorDecl(C);
8450 const CXXConstructorDecl *Constructor =
8451 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8452 // Passing 'false' excludes constructors marked 'explicit'.
8453 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8454}
8455
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008456unsigned clang_CXXField_isMutable(CXCursor C) {
8457 if (!clang_isDeclaration(C.kind))
8458 return 0;
8459
8460 if (const auto D = cxcursor::getCursorDecl(C))
8461 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8462 return FD->isMutable() ? 1 : 0;
8463 return 0;
8464}
8465
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008466unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8467 if (!clang_isDeclaration(C.kind))
8468 return 0;
8469
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008470 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008471 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008472 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008473 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8474}
8475
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008476unsigned clang_CXXMethod_isConst(CXCursor C) {
8477 if (!clang_isDeclaration(C.kind))
8478 return 0;
8479
8480 const Decl *D = cxcursor::getCursorDecl(C);
8481 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008482 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008483 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008484}
8485
Jonathan Coe29565352016-04-27 12:48:25 +00008486unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8487 if (!clang_isDeclaration(C.kind))
8488 return 0;
8489
8490 const Decl *D = cxcursor::getCursorDecl(C);
8491 const CXXMethodDecl *Method =
8492 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8493 return (Method && Method->isDefaulted()) ? 1 : 0;
8494}
8495
Guy Benyei11169dd2012-12-18 14:30:41 +00008496unsigned clang_CXXMethod_isStatic(CXCursor C) {
8497 if (!clang_isDeclaration(C.kind))
8498 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008499
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008500 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008501 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008502 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008503 return (Method && Method->isStatic()) ? 1 : 0;
8504}
8505
8506unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8507 if (!clang_isDeclaration(C.kind))
8508 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008509
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008510 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008511 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008512 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008513 return (Method && Method->isVirtual()) ? 1 : 0;
8514}
Guy Benyei11169dd2012-12-18 14:30:41 +00008515
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008516unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8517 if (!clang_isDeclaration(C.kind))
8518 return 0;
8519
8520 const auto *D = cxcursor::getCursorDecl(C);
8521 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8522 if (RD)
8523 RD = RD->getDefinition();
8524 return (RD && RD->isAbstract()) ? 1 : 0;
8525}
8526
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008527unsigned clang_EnumDecl_isScoped(CXCursor C) {
8528 if (!clang_isDeclaration(C.kind))
8529 return 0;
8530
8531 const Decl *D = cxcursor::getCursorDecl(C);
8532 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8533 return (Enum && Enum->isScoped()) ? 1 : 0;
8534}
8535
Guy Benyei11169dd2012-12-18 14:30:41 +00008536//===----------------------------------------------------------------------===//
8537// Attribute introspection.
8538//===----------------------------------------------------------------------===//
8539
Guy Benyei11169dd2012-12-18 14:30:41 +00008540CXType clang_getIBOutletCollectionType(CXCursor C) {
8541 if (C.kind != CXCursor_IBOutletCollectionAttr)
8542 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008543
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008544 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008545 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8546
8547 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008548}
Guy Benyei11169dd2012-12-18 14:30:41 +00008549
8550//===----------------------------------------------------------------------===//
8551// Inspecting memory usage.
8552//===----------------------------------------------------------------------===//
8553
8554typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8555
8556static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008557 enum CXTUResourceUsageKind k,
8558 unsigned long amount) {
8559 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008560 entries.push_back(entry);
8561}
8562
Guy Benyei11169dd2012-12-18 14:30:41 +00008563const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8564 const char *str = "";
8565 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008566 case CXTUResourceUsage_AST:
8567 str = "ASTContext: expressions, declarations, and types";
8568 break;
8569 case CXTUResourceUsage_Identifiers:
8570 str = "ASTContext: identifiers";
8571 break;
8572 case CXTUResourceUsage_Selectors:
8573 str = "ASTContext: selectors";
8574 break;
8575 case CXTUResourceUsage_GlobalCompletionResults:
8576 str = "Code completion: cached global results";
8577 break;
8578 case CXTUResourceUsage_SourceManagerContentCache:
8579 str = "SourceManager: content cache allocator";
8580 break;
8581 case CXTUResourceUsage_AST_SideTables:
8582 str = "ASTContext: side tables";
8583 break;
8584 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8585 str = "SourceManager: malloc'ed memory buffers";
8586 break;
8587 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8588 str = "SourceManager: mmap'ed memory buffers";
8589 break;
8590 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8591 str = "ExternalASTSource: malloc'ed memory buffers";
8592 break;
8593 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8594 str = "ExternalASTSource: mmap'ed memory buffers";
8595 break;
8596 case CXTUResourceUsage_Preprocessor:
8597 str = "Preprocessor: malloc'ed memory";
8598 break;
8599 case CXTUResourceUsage_PreprocessingRecord:
8600 str = "Preprocessor: PreprocessingRecord";
8601 break;
8602 case CXTUResourceUsage_SourceManager_DataStructures:
8603 str = "SourceManager: data structures and tables";
8604 break;
8605 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8606 str = "Preprocessor: header search tables";
8607 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008608 }
8609 return str;
8610}
8611
8612CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008613 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008614 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008615 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008616 return usage;
8617 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008618
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008619 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008620 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008621 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008622
Guy Benyei11169dd2012-12-18 14:30:41 +00008623 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008624 createCXTUResourceUsageEntry(
8625 *entries, CXTUResourceUsage_AST,
8626 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008627
8628 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008629 createCXTUResourceUsageEntry(
8630 *entries, CXTUResourceUsage_Identifiers,
8631 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008632
8633 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008634 createCXTUResourceUsageEntry(
8635 *entries, CXTUResourceUsage_Selectors,
8636 (unsigned long)astContext.Selectors.getTotalMemory());
8637
Guy Benyei11169dd2012-12-18 14:30:41 +00008638 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008639 createCXTUResourceUsageEntry(
8640 *entries, CXTUResourceUsage_AST_SideTables,
8641 (unsigned long)astContext.getSideTableAllocatedMemory());
8642
Guy Benyei11169dd2012-12-18 14:30:41 +00008643 // How much memory is used for caching global code completion results?
8644 unsigned long completionBytes = 0;
8645 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008646 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008647 completionBytes = completionAllocator->getTotalMemory();
8648 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008649 createCXTUResourceUsageEntry(
8650 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8651
Guy Benyei11169dd2012-12-18 14:30:41 +00008652 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008653 createCXTUResourceUsageEntry(
8654 *entries, CXTUResourceUsage_SourceManagerContentCache,
8655 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8656
Guy Benyei11169dd2012-12-18 14:30:41 +00008657 // How much memory is being used by the MemoryBuffer's in SourceManager?
8658 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008659 astUnit->getSourceManager().getMemoryBufferSizes();
8660
Guy Benyei11169dd2012-12-18 14:30:41 +00008661 createCXTUResourceUsageEntry(*entries,
8662 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008663 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008664 createCXTUResourceUsageEntry(*entries,
8665 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008666 (unsigned long)srcBufs.mmap_bytes);
8667 createCXTUResourceUsageEntry(
8668 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8669 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8670
Guy Benyei11169dd2012-12-18 14:30:41 +00008671 // How much memory is being used by the ExternalASTSource?
8672 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8673 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008674 esrc->getMemoryBufferSizes();
8675
8676 createCXTUResourceUsageEntry(
8677 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8678 (unsigned long)sizes.malloc_bytes);
8679 createCXTUResourceUsageEntry(
8680 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8681 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008682 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008683
Guy Benyei11169dd2012-12-18 14:30:41 +00008684 // How much memory is being used by the Preprocessor?
8685 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008686 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008687 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008688
Guy Benyei11169dd2012-12-18 14:30:41 +00008689 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8690 createCXTUResourceUsageEntry(*entries,
8691 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008692 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008693 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008694
Guy Benyei11169dd2012-12-18 14:30:41 +00008695 createCXTUResourceUsageEntry(*entries,
8696 CXTUResourceUsage_Preprocessor_HeaderSearch,
8697 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008698
Michael Kruse7520cf02020-03-25 09:26:14 -05008699 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8700 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008701 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008702 return usage;
8703}
8704
8705void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8706 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008707 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008708}
8709
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008710CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8711 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008712 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008713 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008714
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008715 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008716 LOG_BAD_TU(TU);
8717 return skipped;
8718 }
8719
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008720 if (!file)
8721 return skipped;
8722
8723 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008724 PreprocessingRecord *ppRec =
8725 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008726 if (!ppRec)
8727 return skipped;
8728
8729 ASTContext &Ctx = astUnit->getASTContext();
8730 SourceManager &sm = Ctx.getSourceManager();
8731 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8732 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008733 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008734
8735 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8736 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008737 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8738 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008739 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008740 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8741 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008742 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008743 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8744 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008745 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008746 }
8747
8748 skipped->count = wantedRanges.size();
8749 skipped->ranges = new CXSourceRange[skipped->count];
8750 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8751 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8752
8753 return skipped;
8754}
8755
Cameron Desrochersd8091282016-08-18 15:43:55 +00008756CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8757 CXSourceRangeList *skipped = new CXSourceRangeList;
8758 skipped->count = 0;
8759 skipped->ranges = nullptr;
8760
8761 if (isNotUsableTU(TU)) {
8762 LOG_BAD_TU(TU);
8763 return skipped;
8764 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008765
Cameron Desrochersd8091282016-08-18 15:43:55 +00008766 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008767 PreprocessingRecord *ppRec =
8768 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008769 if (!ppRec)
8770 return skipped;
8771
8772 ASTContext &Ctx = astUnit->getASTContext();
8773
8774 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8775
8776 skipped->count = SkippedRanges.size();
8777 skipped->ranges = new CXSourceRange[skipped->count];
8778 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8779 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8780
8781 return skipped;
8782}
8783
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008784void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8785 if (ranges) {
8786 delete[] ranges->ranges;
8787 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008788 }
8789}
8790
Guy Benyei11169dd2012-12-18 14:30:41 +00008791void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8792 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8793 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008794 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008795 clang_getTUResourceUsageName(Usage.entries[I].kind),
8796 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008797
Guy Benyei11169dd2012-12-18 14:30:41 +00008798 clang_disposeCXTUResourceUsage(Usage);
8799}
8800
8801//===----------------------------------------------------------------------===//
8802// Misc. utility functions.
8803//===----------------------------------------------------------------------===//
8804
Richard Smith0a7b2972018-07-03 21:34:13 +00008805/// Default to using our desired 8 MB stack size on "safety" threads.
8806static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008807
8808namespace clang {
8809
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008810bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008811 unsigned Size) {
8812 if (!Size)
8813 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008814 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008815 return CRC.RunSafelyOnThread(Fn, Size);
8816 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008817}
8818
Michael Kruse7520cf02020-03-25 09:26:14 -05008819unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008820
Michael Kruse7520cf02020-03-25 09:26:14 -05008821void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008822
Michael Kruse7520cf02020-03-25 09:26:14 -05008823} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008824
8825void clang::setThreadBackgroundPriority() {
8826 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8827 return;
8828
Nico Weber18cfd9f2019-04-21 19:18:41 +00008829#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008830 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008831#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008832}
8833
8834void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8835 if (!Unit)
8836 return;
8837
Michael Kruse7520cf02020-03-25 09:26:14 -05008838 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8839 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008840 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008841 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008842 CXString Msg =
8843 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008844 fprintf(stderr, "%s\n", clang_getCString(Msg));
8845 clang_disposeString(Msg);
8846 }
Nico Weber1865df42018-04-27 19:11:14 +00008847#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008848 // On Windows, force a flush, since there may be multiple copies of
8849 // stderr and stdout in the file system, all with different buffers
8850 // but writing to the same device.
8851 fflush(stderr);
8852#endif
8853}
8854
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008855MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8856 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008857 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008858 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008859 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008860 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008861 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008862
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008863 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008864 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008865 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008866 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008867 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8868 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008869 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8870 return Def.getMacroInfo();
8871 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008872 }
8873
Craig Topper69186e72014-06-08 08:38:04 +00008874 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008875}
8876
Richard Smith66a81862015-05-04 02:25:31 +00008877const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008878 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008879 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008880 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008881 const IdentifierInfo *II = MacroDef->getName();
8882 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008883 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008884
8885 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8886}
8887
Richard Smith66a81862015-05-04 02:25:31 +00008888MacroDefinitionRecord *
8889cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8890 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008891 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008892 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008893 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008894 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008895
8896 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008897 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008898 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8899 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008900 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008901
8902 // Check that the token is inside the definition and not its argument list.
8903 SourceManager &SM = Unit->getSourceManager();
8904 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008905 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008906 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00008907 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008908
8909 Preprocessor &PP = Unit->getPreprocessor();
8910 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
8911 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00008912 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008913
Alp Toker2d57cea2014-05-17 04:53:25 +00008914 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008915 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008916 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008917
8918 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00008919 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00008920 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008921
Richard Smith20e883e2015-04-29 23:20:19 +00008922 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00008923 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00008924 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008925
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008926 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008927}
8928
Richard Smith66a81862015-05-04 02:25:31 +00008929MacroDefinitionRecord *
8930cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
8931 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008932 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008933 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008934
8935 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008936 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008937 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008938 Preprocessor &PP = Unit->getPreprocessor();
8939 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00008940 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008941 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
8942 Token Tok;
8943 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00008944 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008945
8946 return checkForMacroInMacroDefinition(MI, Tok, TU);
8947}
8948
Guy Benyei11169dd2012-12-18 14:30:41 +00008949CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008950 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00008951}
8952
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008953Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
8954 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008955 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008956 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00008957 if (Unit->isMainFileAST())
8958 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008959 return *this;
8960 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00008961 } else {
8962 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008963 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008964 return *this;
8965}
8966
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00008967Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
8968 *this << FE->getName();
8969 return *this;
8970}
8971
8972Logger &cxindex::Logger::operator<<(CXCursor cursor) {
8973 CXString cursorName = clang_getCursorDisplayName(cursor);
8974 *this << cursorName << "@" << clang_getCursorLocation(cursor);
8975 clang_disposeString(cursorName);
8976 return *this;
8977}
8978
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008979Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
8980 CXFile File;
8981 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00008982 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008983 CXString FileName = clang_getFileName(File);
8984 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
8985 clang_disposeString(FileName);
8986 return *this;
8987}
8988
8989Logger &cxindex::Logger::operator<<(CXSourceRange range) {
8990 CXSourceLocation BLoc = clang_getRangeStart(range);
8991 CXSourceLocation ELoc = clang_getRangeEnd(range);
8992
8993 CXFile BFile;
8994 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00008995 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008996
8997 CXFile EFile;
8998 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00008999 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009000
9001 CXString BFileName = clang_getFileName(BFile);
9002 if (BFile == EFile) {
9003 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05009004 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009005 } else {
9006 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009007 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9008 BColumn)
9009 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9010 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009011 clang_disposeString(EFileName);
9012 }
9013 clang_disposeString(BFileName);
9014 return *this;
9015}
9016
9017Logger &cxindex::Logger::operator<<(CXString Str) {
9018 *this << clang_getCString(Str);
9019 return *this;
9020}
9021
9022Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9023 LogOS << Fmt;
9024 return *this;
9025}
9026
Benjamin Kramer762bc332019-08-07 14:44:40 +00009027static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009028
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009029cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009030 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009031
9032 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9033
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009034 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009035 OS << "[libclang:" << Name << ':';
9036
Alp Toker1a86ad22014-07-06 06:24:00 +00009037#ifdef USE_DARWIN_THREADS
9038 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009039 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9040 OS << tid << ':';
9041#endif
9042
9043 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9044 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009045 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009046
9047 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009048 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009049 OS << "--------------------------------------------------\n";
9050 }
9051}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009052
9053#ifdef CLANG_TOOL_EXTRA_BUILD
9054// This anchor is used to force the linker to link the clang-tidy plugin.
9055extern volatile int ClangTidyPluginAnchorSource;
9056static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9057 ClangTidyPluginAnchorSource;
9058
9059// This anchor is used to force the linker to link the clang-include-fixer
9060// plugin.
9061extern volatile int ClangIncludeFixerPluginAnchorSource;
9062static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9063 ClangIncludeFixerPluginAnchorSource;
9064#endif