blob: 50c0886065383a9b826b84ec892b042bd3c71f8d [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:
Guy Benyei11169dd2012-12-18 14:30:41 +00006325 case Decl::IndirectField:
6326 case Decl::ObjCIvar:
6327 case Decl::ObjCAtDefsField:
6328 case Decl::ImplicitParam:
6329 case Decl::ParmVar:
6330 case Decl::NonTypeTemplateParm:
6331 case Decl::TemplateTemplateParm:
6332 case Decl::ObjCCategoryImpl:
6333 case Decl::ObjCImplementation:
6334 case Decl::AccessSpec:
6335 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006336 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006337 case Decl::ObjCPropertyImpl:
6338 case Decl::FileScopeAsm:
6339 case Decl::StaticAssert:
6340 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006341 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006342 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006343 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006344 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006345 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006346 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006347 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006348 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006349 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006350 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006351 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006352 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006353 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006354 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006355 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006356 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006357 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006358 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006359 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006360 return C;
6361
6362 // Declaration kinds that don't make any sense here, but are
6363 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006364 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006366 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006367 break;
6368
6369 // Declaration kinds for which the definition is not resolvable.
6370 case Decl::UnresolvedUsingTypename:
6371 case Decl::UnresolvedUsingValue:
6372 break;
6373
6374 case Decl::UsingDirective:
6375 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6376 TU);
6377
6378 case Decl::NamespaceAlias:
6379 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6380
6381 case Decl::Enum:
6382 case Decl::Record:
6383 case Decl::CXXRecord:
6384 case Decl::ClassTemplateSpecialization:
6385 case Decl::ClassTemplatePartialSpecialization:
6386 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6387 return MakeCXCursor(Def, TU);
6388 return clang_getNullCursor();
6389
6390 case Decl::Function:
6391 case Decl::CXXMethod:
6392 case Decl::CXXConstructor:
6393 case Decl::CXXDestructor:
6394 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006395 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006396 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006397 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006398 return clang_getNullCursor();
6399 }
6400
Larisse Voufo39a1e502013-08-06 01:03:05 +00006401 case Decl::Var:
6402 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006403 case Decl::VarTemplatePartialSpecialization:
6404 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006405 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006406 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006407 return MakeCXCursor(Def, TU);
6408 return clang_getNullCursor();
6409 }
6410
6411 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006412 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006413 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6414 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6415 return clang_getNullCursor();
6416 }
6417
6418 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006419 if (RecordDecl *Def =
6420 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6422 TU);
6423 return clang_getNullCursor();
6424 }
6425
Larisse Voufo39a1e502013-08-06 01:03:05 +00006426 case Decl::VarTemplate: {
6427 if (VarDecl *Def =
6428 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6429 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6430 return clang_getNullCursor();
6431 }
6432
Guy Benyei11169dd2012-12-18 14:30:41 +00006433 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006434 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6435 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006436
6437 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006438 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006439 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006440 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006441
6442 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006443 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006444 if (Method->isThisDeclarationADefinition())
6445 return C;
6446
6447 // Dig out the method definition in the associated
6448 // @implementation, if we have it.
6449 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006450 if (const ObjCInterfaceDecl *Class =
6451 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006452 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006453 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6454 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006455 if (Def->isThisDeclarationADefinition())
6456 return MakeCXCursor(Def, TU);
6457
6458 return clang_getNullCursor();
6459 }
6460
6461 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006462 if (ObjCCategoryImplDecl *Impl =
6463 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006464 return MakeCXCursor(Impl, TU);
6465 return clang_getNullCursor();
6466
6467 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006468 if (const ObjCProtocolDecl *Def =
6469 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006470 return MakeCXCursor(Def, TU);
6471 return clang_getNullCursor();
6472
6473 case Decl::ObjCInterface: {
6474 // There are two notions of a "definition" for an Objective-C
6475 // class: the interface and its implementation. When we resolved a
6476 // reference to an Objective-C class, produce the @interface as
6477 // the definition; when we were provided with the interface,
6478 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006479 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006480 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006481 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006482 return MakeCXCursor(Def, TU);
6483 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6484 return MakeCXCursor(Impl, TU);
6485 return clang_getNullCursor();
6486 }
6487
6488 case Decl::ObjCProperty:
6489 // FIXME: We don't really know where to find the
6490 // ObjCPropertyImplDecls that implement this property.
6491 return clang_getNullCursor();
6492
6493 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006494 if (const ObjCInterfaceDecl *Class =
6495 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006496 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006497 return MakeCXCursor(Def, TU);
6498
6499 return clang_getNullCursor();
6500
6501 case Decl::Friend:
6502 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6503 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6504 return clang_getNullCursor();
6505
6506 case Decl::FriendTemplate:
6507 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6508 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6509 return clang_getNullCursor();
6510 }
6511
6512 return clang_getNullCursor();
6513}
6514
6515unsigned clang_isCursorDefinition(CXCursor C) {
6516 if (!clang_isDeclaration(C.kind))
6517 return 0;
6518
6519 return clang_getCursorDefinition(C) == C;
6520}
6521
6522CXCursor clang_getCanonicalCursor(CXCursor C) {
6523 if (!clang_isDeclaration(C.kind))
6524 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006525
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006526 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006527 if (const ObjCCategoryImplDecl *CatImplD =
6528 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006529 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6530 return MakeCXCursor(CatD, getCursorTU(C));
6531
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006532 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6533 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006534 return MakeCXCursor(IFD, getCursorTU(C));
6535
6536 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6537 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006538
Guy Benyei11169dd2012-12-18 14:30:41 +00006539 return C;
6540}
6541
6542int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6543 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6544}
Michael Kruse7520cf02020-03-25 09:26:14 -05006545
Guy Benyei11169dd2012-12-18 14:30:41 +00006546unsigned clang_getNumOverloadedDecls(CXCursor C) {
6547 if (C.kind != CXCursor_OverloadedDeclRef)
6548 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006549
Guy Benyei11169dd2012-12-18 14:30:41 +00006550 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006551 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006552 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006553
6554 if (OverloadedTemplateStorage *S =
6555 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006556 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006557
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006558 const Decl *D = Storage.get<const Decl *>();
6559 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006560 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006561
Guy Benyei11169dd2012-12-18 14:30:41 +00006562 return 0;
6563}
6564
6565CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6566 if (cursor.kind != CXCursor_OverloadedDeclRef)
6567 return clang_getNullCursor();
6568
6569 if (index >= clang_getNumOverloadedDecls(cursor))
6570 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006571
Guy Benyei11169dd2012-12-18 14:30:41 +00006572 CXTranslationUnit TU = getCursorTU(cursor);
6573 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006574 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006575 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006576
6577 if (OverloadedTemplateStorage *S =
6578 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006579 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006580
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006581 const Decl *D = Storage.get<const Decl *>();
6582 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006583 // FIXME: This is, unfortunately, linear time.
6584 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6585 std::advance(Pos, index);
6586 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6587 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006588
Guy Benyei11169dd2012-12-18 14:30:41 +00006589 return clang_getNullCursor();
6590}
Michael Kruse7520cf02020-03-25 09:26:14 -05006591
6592void clang_getDefinitionSpellingAndExtent(
6593 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6594 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006595 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006596 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006597 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6598
6599 SourceManager &SM = FD->getASTContext().getSourceManager();
6600 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6601 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6602 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6603 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6604 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6605 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6606}
6607
Guy Benyei11169dd2012-12-18 14:30:41 +00006608CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6609 unsigned PieceIndex) {
6610 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006611
Guy Benyei11169dd2012-12-18 14:30:41 +00006612 switch (C.kind) {
6613 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006614 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006615 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6616 E->getQualifierLoc().getSourceRange());
6617 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006618
Guy Benyei11169dd2012-12-18 14:30:41 +00006619 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006620 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6621 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6622 Pieces =
6623 buildPieces(NameFlags, false, E->getNameInfo(),
6624 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6625 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006626 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006627
Guy Benyei11169dd2012-12-18 14:30:41 +00006628 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006629 if (const CXXOperatorCallExpr *OCE =
6630 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006631 const Expr *Callee = OCE->getCallee();
6632 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006633 Callee = ICE->getSubExpr();
6634
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006635 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006636 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6637 DRE->getQualifierLoc().getSourceRange());
6638 }
6639 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006640
Guy Benyei11169dd2012-12-18 14:30:41 +00006641 default:
6642 break;
6643 }
6644
6645 if (Pieces.empty()) {
6646 if (PieceIndex == 0)
6647 return clang_getCursorExtent(C);
6648 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006649 SourceRange R = Pieces[PieceIndex];
6650 if (R.isValid())
6651 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006652 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006653
Guy Benyei11169dd2012-12-18 14:30:41 +00006654 return clang_getNullRange();
6655}
6656
6657void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006658 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6659 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006660}
6661
Michael Kruse7520cf02020-03-25 09:26:14 -05006662void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006663 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006664 llvm::llvm_execute_on_thread(fn, user_data,
6665 stack_size == 0
6666 ? clang::DesiredStackSize
6667 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006668}
6669
Guy Benyei11169dd2012-12-18 14:30:41 +00006670//===----------------------------------------------------------------------===//
6671// Token-based Operations.
6672//===----------------------------------------------------------------------===//
6673
6674/* CXToken layout:
6675 * int_data[0]: a CXTokenKind
6676 * int_data[1]: starting token location
6677 * int_data[2]: token length
6678 * int_data[3]: reserved
6679 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6680 * otherwise unused.
6681 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006682CXTokenKind clang_getTokenKind(CXToken CXTok) {
6683 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6684}
6685
6686CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6687 switch (clang_getTokenKind(CXTok)) {
6688 case CXToken_Identifier:
6689 case CXToken_Keyword:
6690 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006691 return cxstring::createRef(
6692 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006693
6694 case CXToken_Literal: {
6695 // We have stashed the starting pointer in the ptr_data field. Use it.
6696 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006697 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006698 }
6699
6700 case CXToken_Punctuation:
6701 case CXToken_Comment:
6702 break;
6703 }
6704
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006705 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006706 LOG_BAD_TU(TU);
6707 return cxstring::createEmpty();
6708 }
6709
Guy Benyei11169dd2012-12-18 14:30:41 +00006710 // We have to find the starting buffer pointer the hard way, by
6711 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006712 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006713 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006714 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006715
6716 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006717 std::pair<FileID, unsigned> LocInfo =
6718 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006719 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006720 StringRef Buffer =
6721 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006722 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006723 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006724
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006725 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006726}
6727
6728CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006729 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006730 LOG_BAD_TU(TU);
6731 return clang_getNullLocation();
6732 }
6733
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006734 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006735 if (!CXXUnit)
6736 return clang_getNullLocation();
6737
Michael Kruse7520cf02020-03-25 09:26:14 -05006738 return cxloc::translateSourceLocation(
6739 CXXUnit->getASTContext(),
6740 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006741}
6742
6743CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006744 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006745 LOG_BAD_TU(TU);
6746 return clang_getNullRange();
6747 }
6748
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006749 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006750 if (!CXXUnit)
6751 return clang_getNullRange();
6752
Michael Kruse7520cf02020-03-25 09:26:14 -05006753 return cxloc::translateSourceRange(
6754 CXXUnit->getASTContext(),
6755 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006756}
6757
6758static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6759 SmallVectorImpl<CXToken> &CXTokens) {
6760 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006761 std::pair<FileID, unsigned> BeginLocInfo =
6762 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6763 std::pair<FileID, unsigned> EndLocInfo =
6764 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006765
6766 // Cannot tokenize across files.
6767 if (BeginLocInfo.first != EndLocInfo.first)
6768 return;
6769
6770 // Create a lexer
6771 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006772 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006773 if (Invalid)
6774 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006775
Guy Benyei11169dd2012-12-18 14:30:41 +00006776 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006777 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6778 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006779 Lex.SetCommentRetentionState(true);
6780
6781 // Lex tokens until we hit the end of the range.
6782 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6783 Token Tok;
6784 bool previousWasAt = false;
6785 do {
6786 // Lex the next token
6787 Lex.LexFromRawLexer(Tok);
6788 if (Tok.is(tok::eof))
6789 break;
6790
6791 // Initialize the CXToken.
6792 CXToken CXTok;
6793
6794 // - Common fields
6795 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6796 CXTok.int_data[2] = Tok.getLength();
6797 CXTok.int_data[3] = 0;
6798
6799 // - Kind-specific fields
6800 if (Tok.isLiteral()) {
6801 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006802 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006803 } else if (Tok.is(tok::raw_identifier)) {
6804 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006805 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006806
6807 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6808 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006809 } else {
6810 CXTok.int_data[0] =
6811 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006812 }
6813 CXTok.ptr_data = II;
6814 } else if (Tok.is(tok::comment)) {
6815 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006816 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006817 } else {
6818 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006819 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006820 }
6821 CXTokens.push_back(CXTok);
6822 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006823 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006824}
6825
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006826CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006827 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006828
6829 if (isNotUsableTU(TU)) {
6830 LOG_BAD_TU(TU);
6831 return NULL;
6832 }
6833
6834 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6835 if (!CXXUnit)
6836 return NULL;
6837
6838 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6839 if (Begin.isInvalid())
6840 return NULL;
6841 SourceManager &SM = CXXUnit->getSourceManager();
6842 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006843 DecomposedEnd.second +=
6844 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006845
Michael Kruse7520cf02020-03-25 09:26:14 -05006846 SourceLocation End =
6847 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006848
6849 SmallVector<CXToken, 32> CXTokens;
6850 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6851
6852 if (CXTokens.empty())
6853 return NULL;
6854
6855 CXTokens.resize(1);
6856 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6857
6858 memmove(Token, CXTokens.data(), sizeof(CXToken));
6859 return Token;
6860}
6861
Michael Kruse7520cf02020-03-25 09:26:14 -05006862void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6863 unsigned *NumTokens) {
6864 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006865
Guy Benyei11169dd2012-12-18 14:30:41 +00006866 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006867 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006868 if (NumTokens)
6869 *NumTokens = 0;
6870
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006871 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006872 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006873 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006874 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006875
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006876 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006877 if (!CXXUnit || !Tokens || !NumTokens)
6878 return;
6879
6880 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006881
Guy Benyei11169dd2012-12-18 14:30:41 +00006882 SourceRange R = cxloc::translateCXSourceRange(Range);
6883 if (R.isInvalid())
6884 return;
6885
6886 SmallVector<CXToken, 32> CXTokens;
6887 getTokens(CXXUnit, R, CXTokens);
6888
6889 if (CXTokens.empty())
6890 return;
6891
Serge Pavlov52525732018-02-21 02:02:39 +00006892 *Tokens = static_cast<CXToken *>(
6893 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006894 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6895 *NumTokens = CXTokens.size();
6896}
6897
Michael Kruse7520cf02020-03-25 09:26:14 -05006898void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6899 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006900 free(Tokens);
6901}
6902
Guy Benyei11169dd2012-12-18 14:30:41 +00006903//===----------------------------------------------------------------------===//
6904// Token annotation APIs.
6905//===----------------------------------------------------------------------===//
6906
Guy Benyei11169dd2012-12-18 14:30:41 +00006907static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6908 CXCursor parent,
6909 CXClientData client_data);
6910static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6911 CXClientData client_data);
6912
6913namespace {
6914class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006915 CXToken *Tokens;
6916 CXCursor *Cursors;
6917 unsigned NumTokens;
6918 unsigned TokIdx;
6919 unsigned PreprocessingTokIdx;
6920 CursorVisitor AnnotateVis;
6921 SourceManager &SrcMgr;
6922 bool HasContextSensitiveKeywords;
6923
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006924 struct PostChildrenAction {
6925 CXCursor cursor;
6926 enum Action { Invalid, Ignore, Postpone } action;
6927 };
6928 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6929
Guy Benyei11169dd2012-12-18 14:30:41 +00006930 struct PostChildrenInfo {
6931 CXCursor Cursor;
6932 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006933 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006934 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006935 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006936 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006937 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006938
6939 CXToken &getTok(unsigned Idx) {
6940 assert(Idx < NumTokens);
6941 return Tokens[Idx];
6942 }
6943 const CXToken &getTok(unsigned Idx) const {
6944 assert(Idx < NumTokens);
6945 return Tokens[Idx];
6946 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006947 bool MoreTokens() const { return TokIdx < NumTokens; }
6948 unsigned NextToken() const { return TokIdx; }
6949 void AdvanceToken() { ++TokIdx; }
6950 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006951 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006952 }
6953 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006954 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006955 }
6956 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006957 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006958 }
6959
6960 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006961 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006962 SourceRange);
6963
6964public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006965 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006966 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05006967 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
6968 PreprocessingTokIdx(0),
6969 AnnotateVis(TU, AnnotateTokensVisitor, this,
6970 /*VisitPreprocessorLast=*/true,
6971 /*VisitIncludedEntities=*/false, RegionOfInterest,
6972 /*VisitDeclsOnly=*/false,
6973 AnnotateTokensPostChildrenVisitor),
6974 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
6975 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00006976
6977 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6978 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006979 bool IsIgnoredChildCursor(CXCursor cursor) const;
6980 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
6981
Guy Benyei11169dd2012-12-18 14:30:41 +00006982 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006983 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
6984 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
6985
Guy Benyei11169dd2012-12-18 14:30:41 +00006986 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05006987
6988 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00006989 /// context-sensitive keywords.
6990 bool hasContextSensitiveKeywords() const {
6991 return HasContextSensitiveKeywords;
6992 }
6993
Michael Kruse7520cf02020-03-25 09:26:14 -05006994 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00006995};
Michael Kruse7520cf02020-03-25 09:26:14 -05006996} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00006997
6998void AnnotateTokensWorker::AnnotateTokens() {
6999 // Walk the AST within the region of interest, annotating tokens
7000 // along the way.
7001 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007002}
Guy Benyei11169dd2012-12-18 14:30:41 +00007003
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007004bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7005 if (PostChildrenInfos.empty())
7006 return false;
7007
7008 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7009 if (ChildAction.cursor == cursor &&
7010 ChildAction.action == PostChildrenAction::Ignore) {
7011 return true;
7012 }
7013 }
7014
7015 return false;
7016}
7017
7018const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7019 if (!clang_isExpression(Cursor.kind))
7020 return nullptr;
7021
7022 const Expr *E = getCursorExpr(Cursor);
7023 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7024 const OverloadedOperatorKind Kind = OCE->getOperator();
7025 if (Kind == OO_Call || Kind == OO_Subscript)
7026 return OCE;
7027 }
7028
7029 return nullptr;
7030}
7031
7032AnnotateTokensWorker::PostChildrenActions
7033AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7034 PostChildrenActions actions;
7035
7036 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7037 // visited before the arguments to the operator call. For the Call and
7038 // Subscript operator the range of this DeclRefExpr includes the whole call
7039 // expression, so that all tokens in that range would be mapped to the
7040 // operator function, including the tokens of the arguments. To avoid that,
7041 // ensure to visit this DeclRefExpr as last node.
7042 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7043 const Expr *Callee = OCE->getCallee();
7044 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7045 const Expr *SubExpr = ICE->getSubExpr();
7046 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007047 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007048 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7049
7050 // Visit the DeclRefExpr as last.
7051 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7052 actions.push_back({cxChild, PostChildrenAction::Postpone});
7053
7054 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7055 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7056 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7057 actions.push_back({cxChild, PostChildrenAction::Ignore});
7058 }
7059 }
7060 }
7061
7062 return actions;
7063}
7064
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007065static inline void updateCursorAnnotation(CXCursor &Cursor,
7066 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007067 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007068 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007069 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007070}
7071
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007072/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007073//// between the cursor location and the source range is the same as
7074/// \arg compResult.
7075///
7076/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7077/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007078void AnnotateTokensWorker::annotateAndAdvanceTokens(
7079 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007080 while (MoreTokens()) {
7081 const unsigned I = NextToken();
7082 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007083 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7084 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007085
7086 SourceLocation TokLoc = GetTokenLoc(I);
7087 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007088 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007089 AdvanceToken();
7090 continue;
7091 }
7092 break;
7093 }
7094}
7095
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007096/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007097/// \returns true if it advanced beyond all macro tokens, false otherwise.
7098bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007099 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007100 assert(MoreTokens());
7101 assert(isFunctionMacroToken(NextToken()) &&
7102 "Should be called only for macro arg tokens");
7103
7104 // This works differently than annotateAndAdvanceTokens; because expanded
7105 // macro arguments can have arbitrary translation-unit source order, we do not
7106 // advance the token index one by one until a token fails the range test.
7107 // We only advance once past all of the macro arg tokens if all of them
7108 // pass the range test. If one of them fails we keep the token index pointing
7109 // at the start of the macro arg tokens so that the failing token will be
7110 // annotated by a subsequent annotation try.
7111
7112 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007113
Guy Benyei11169dd2012-12-18 14:30:41 +00007114 unsigned I = NextToken();
7115 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7116 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7117 if (TokLoc.isFileID())
7118 continue; // not macro arg token, it's parens or comma.
7119 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7120 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7121 Cursors[I] = updateC;
7122 } else
7123 atLeastOneCompFail = true;
7124 }
7125
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007126 if (atLeastOneCompFail)
7127 return false;
7128
7129 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7130 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007131}
7132
Michael Kruse7520cf02020-03-25 09:26:14 -05007133enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7134 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007135 SourceRange cursorRange = getRawCursorExtent(cursor);
7136 if (cursorRange.isInvalid())
7137 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007138
7139 if (IsIgnoredChildCursor(cursor))
7140 return CXChildVisit_Continue;
7141
Guy Benyei11169dd2012-12-18 14:30:41 +00007142 if (!HasContextSensitiveKeywords) {
7143 // Objective-C properties can have context-sensitive keywords.
7144 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007145 if (const ObjCPropertyDecl *Property =
7146 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7147 HasContextSensitiveKeywords =
7148 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007149 }
7150 // Objective-C methods can have context-sensitive keywords.
7151 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7152 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007153 if (const ObjCMethodDecl *Method =
7154 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007155 if (Method->getObjCDeclQualifier())
7156 HasContextSensitiveKeywords = true;
7157 else {
David Majnemer59f77922016-06-24 04:05:48 +00007158 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007159 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007160 HasContextSensitiveKeywords = true;
7161 break;
7162 }
7163 }
7164 }
7165 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007166 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007167 // C++ methods can have context-sensitive keywords.
7168 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007169 if (const CXXMethodDecl *Method =
7170 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007171 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7172 HasContextSensitiveKeywords = true;
7173 }
7174 }
7175 // C++ classes can have context-sensitive keywords.
7176 else if (cursor.kind == CXCursor_StructDecl ||
7177 cursor.kind == CXCursor_ClassDecl ||
7178 cursor.kind == CXCursor_ClassTemplate ||
7179 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007180 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007181 if (D->hasAttr<FinalAttr>())
7182 HasContextSensitiveKeywords = true;
7183 }
7184 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007185
7186 // Don't override a property annotation with its getter/setter method.
7187 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7188 parent.kind == CXCursor_ObjCPropertyDecl)
7189 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007190
7191 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007192 // Items in the preprocessing record are kept separate from items in
7193 // declarations, so we keep a separate token index.
7194 unsigned SavedTokIdx = TokIdx;
7195 TokIdx = PreprocessingTokIdx;
7196
7197 // Skip tokens up until we catch up to the beginning of the preprocessing
7198 // entry.
7199 while (MoreTokens()) {
7200 const unsigned I = NextToken();
7201 SourceLocation TokLoc = GetTokenLoc(I);
7202 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7203 case RangeBefore:
7204 AdvanceToken();
7205 continue;
7206 case RangeAfter:
7207 case RangeOverlap:
7208 break;
7209 }
7210 break;
7211 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007212
Guy Benyei11169dd2012-12-18 14:30:41 +00007213 // Look at all of the tokens within this range.
7214 while (MoreTokens()) {
7215 const unsigned I = NextToken();
7216 SourceLocation TokLoc = GetTokenLoc(I);
7217 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7218 case RangeBefore:
7219 llvm_unreachable("Infeasible");
7220 case RangeAfter:
7221 break;
7222 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007223 // For macro expansions, just note where the beginning of the macro
7224 // expansion occurs.
7225 if (cursor.kind == CXCursor_MacroExpansion) {
7226 if (TokLoc == cursorRange.getBegin())
7227 Cursors[I] = cursor;
7228 AdvanceToken();
7229 break;
7230 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007231 // We may have already annotated macro names inside macro definitions.
7232 if (Cursors[I].kind != CXCursor_MacroExpansion)
7233 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007234 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007235 continue;
7236 }
7237 break;
7238 }
7239
7240 // Save the preprocessing token index; restore the non-preprocessing
7241 // token index.
7242 PreprocessingTokIdx = TokIdx;
7243 TokIdx = SavedTokIdx;
7244 return CXChildVisit_Recurse;
7245 }
7246
7247 if (cursorRange.isInvalid())
7248 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007249
7250 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007251 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007252 const enum CXCursorKind K = clang_getCursorKind(parent);
7253 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007254 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7255 // Attributes are annotated out-of-order, skip tokens until we reach it.
7256 clang_isAttribute(cursor.kind))
7257 ? clang_getNullCursor()
7258 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007259
7260 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7261
7262 // Avoid having the cursor of an expression "overwrite" the annotation of the
7263 // variable declaration that it belongs to.
7264 // This can happen for C++ constructor expressions whose range generally
7265 // include the variable declaration, e.g.:
7266 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007267 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007268 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007269 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007270 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007271 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7272 E->getBeginLoc() == D->getLocation() &&
7273 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007274 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007275 AdvanceToken();
7276 }
7277 }
7278 }
7279
7280 // Before recursing into the children keep some state that we are going
7281 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7282 // extra work after the child nodes are visited.
7283 // Note that we don't call VisitChildren here to avoid traversing statements
7284 // code-recursively which can blow the stack.
7285
7286 PostChildrenInfo Info;
7287 Info.Cursor = cursor;
7288 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007289 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007290 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007291 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007292 PostChildrenInfos.push_back(Info);
7293
7294 return CXChildVisit_Recurse;
7295}
7296
7297bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7298 if (PostChildrenInfos.empty())
7299 return false;
7300 const PostChildrenInfo &Info = PostChildrenInfos.back();
7301 if (!clang_equalCursors(Info.Cursor, cursor))
7302 return false;
7303
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007304 HandlePostPonedChildCursors(Info);
7305
Guy Benyei11169dd2012-12-18 14:30:41 +00007306 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7307 const unsigned AfterChildren = NextToken();
7308 SourceRange cursorRange = Info.CursorRange;
7309
7310 // Scan the tokens that are at the end of the cursor, but are not captured
7311 // but the child cursors.
7312 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7313
7314 // Scan the tokens that are at the beginning of the cursor, but are not
7315 // capture by the child cursors.
7316 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7317 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7318 break;
7319
7320 Cursors[I] = cursor;
7321 }
7322
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007323 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7324 // encountered the attribute cursor.
7325 if (clang_isAttribute(cursor.kind))
7326 TokIdx = Info.BeforeReachingCursorIdx;
7327
Guy Benyei11169dd2012-12-18 14:30:41 +00007328 PostChildrenInfos.pop_back();
7329 return false;
7330}
7331
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007332void AnnotateTokensWorker::HandlePostPonedChildCursors(
7333 const PostChildrenInfo &Info) {
7334 for (const auto &ChildAction : Info.ChildActions) {
7335 if (ChildAction.action == PostChildrenAction::Postpone) {
7336 HandlePostPonedChildCursor(ChildAction.cursor,
7337 Info.BeforeChildrenTokenIdx);
7338 }
7339 }
7340}
7341
7342void AnnotateTokensWorker::HandlePostPonedChildCursor(
7343 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007344 unsigned I = StartTokenIndex;
7345
7346 // The bracket tokens of a Call or Subscript operator are mapped to
7347 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7348 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7349 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007350 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7351 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007352 if (clang_Range_isNull(CXRefNameRange))
7353 break; // All ranges handled.
7354
7355 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7356 while (I < NumTokens) {
7357 const SourceLocation TokenLocation = GetTokenLoc(I);
7358 if (!TokenLocation.isValid())
7359 break;
7360
7361 // Adapt the end range, because LocationCompare() reports
7362 // RangeOverlap even for the not-inclusive end location.
7363 const SourceLocation fixedEnd =
7364 RefNameRange.getEnd().getLocWithOffset(-1);
7365 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7366
7367 const RangeComparisonResult ComparisonResult =
7368 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7369
7370 if (ComparisonResult == RangeOverlap) {
7371 Cursors[I++] = Cursor;
7372 } else if (ComparisonResult == RangeBefore) {
7373 ++I; // Not relevant token, check next one.
7374 } else if (ComparisonResult == RangeAfter) {
7375 break; // All tokens updated for current range, check next.
7376 }
7377 }
7378 }
7379}
7380
Guy Benyei11169dd2012-12-18 14:30:41 +00007381static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7382 CXCursor parent,
7383 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007384 return static_cast<AnnotateTokensWorker *>(client_data)
7385 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007386}
7387
7388static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7389 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007390 return static_cast<AnnotateTokensWorker *>(client_data)
7391 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007392}
7393
7394namespace {
7395
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007396/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007397/// and mark tokens that are macro arguments. This info is used by the
7398/// AnnotateTokensWorker.
7399class MarkMacroArgTokensVisitor {
7400 SourceManager &SM;
7401 CXToken *Tokens;
7402 unsigned NumTokens;
7403 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007404
Guy Benyei11169dd2012-12-18 14:30:41 +00007405public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007406 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7407 unsigned numTokens)
7408 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007409
7410 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7411 if (cursor.kind != CXCursor_MacroExpansion)
7412 return CXChildVisit_Continue;
7413
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007414 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007415 if (macroRange.getBegin() == macroRange.getEnd())
7416 return CXChildVisit_Continue; // it's not a function macro.
7417
7418 for (; CurIdx < NumTokens; ++CurIdx) {
7419 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7420 macroRange.getBegin()))
7421 break;
7422 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007423
Guy Benyei11169dd2012-12-18 14:30:41 +00007424 if (CurIdx == NumTokens)
7425 return CXChildVisit_Break;
7426
7427 for (; CurIdx < NumTokens; ++CurIdx) {
7428 SourceLocation tokLoc = getTokenLoc(CurIdx);
7429 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7430 break;
7431
7432 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7433 }
7434
7435 if (CurIdx == NumTokens)
7436 return CXChildVisit_Break;
7437
7438 return CXChildVisit_Continue;
7439 }
7440
7441private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007442 CXToken &getTok(unsigned Idx) {
7443 assert(Idx < NumTokens);
7444 return Tokens[Idx];
7445 }
7446 const CXToken &getTok(unsigned Idx) const {
7447 assert(Idx < NumTokens);
7448 return Tokens[Idx];
7449 }
7450
Guy Benyei11169dd2012-12-18 14:30:41 +00007451 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007452 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007453 }
7454
7455 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7456 // The third field is reserved and currently not used. Use it here
7457 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007458 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007459 }
7460};
7461
7462} // end anonymous namespace
7463
7464static CXChildVisitResult
7465MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7466 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007467 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7468 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007469}
7470
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007471/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007472/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007473static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7474 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007475 if (NextIdx >= NumTokens)
7476 return true;
7477
7478 ++NextIdx;
7479 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007480 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007481}
7482
Guy Benyei11169dd2012-12-18 14:30:41 +00007483static void annotatePreprocessorTokens(CXTranslationUnit TU,
7484 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007485 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007486 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007487 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007488
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007489 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007490 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007491 std::pair<FileID, unsigned> BeginLocInfo =
7492 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7493 std::pair<FileID, unsigned> EndLocInfo =
7494 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007495
7496 if (BeginLocInfo.first != EndLocInfo.first)
7497 return;
7498
7499 StringRef Buffer;
7500 bool Invalid = false;
7501 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7502 if (Buffer.empty() || Invalid)
7503 return;
7504
7505 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007506 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7507 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007508 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007509
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007510 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007511 // Lex tokens in raw mode until we hit the end of the range, to avoid
7512 // entering #includes or expanding macros.
7513 while (true) {
7514 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007515 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7516 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007517 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007518 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007519 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7520
Guy Benyei11169dd2012-12-18 14:30:41 +00007521 reprocess:
7522 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007523 // We have found a preprocessing directive. Annotate the tokens
7524 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007525 //
7526 // FIXME: Some simple tests here could identify macro definitions and
7527 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007528
7529 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007530 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7531 break;
7532
Craig Topper69186e72014-06-08 08:38:04 +00007533 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007534 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007535 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7536 break;
7537
7538 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007539 IdentifierInfo &II =
7540 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007541 SourceLocation MappedTokLoc =
7542 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7543 MI = getMacroInfo(II, MappedTokLoc, TU);
7544 }
7545 }
7546
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007547 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007548 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007549 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7550 finished = true;
7551 break;
7552 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007553 // If we are in a macro definition, check if the token was ever a
7554 // macro name and annotate it if that's the case.
7555 if (MI) {
7556 SourceLocation SaveLoc = Tok.getLocation();
7557 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007558 MacroDefinitionRecord *MacroDef =
7559 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007560 Tok.setLocation(SaveLoc);
7561 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007562 Cursors[NextIdx - 1] =
7563 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007564 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007565 } while (!Tok.isAtStartOfLine());
7566
Michael Kruse7520cf02020-03-25 09:26:14 -05007567 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007568 assert(TokIdx <= LastIdx);
7569 SourceLocation EndLoc =
7570 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7571 CXCursor Cursor =
7572 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7573
7574 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007575 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007576
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007577 if (finished)
7578 break;
7579 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007580 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007581 }
7582}
7583
7584// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007585static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7586 CXToken *Tokens, unsigned NumTokens,
7587 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007588 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007589 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7590 setThreadBackgroundPriority();
7591
7592 // Determine the region of interest, which contains all of the tokens.
7593 SourceRange RegionOfInterest;
7594 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007595 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7596 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7597 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007598
Guy Benyei11169dd2012-12-18 14:30:41 +00007599 // Relex the tokens within the source range to look for preprocessing
7600 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007601 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007602
7603 // If begin location points inside a macro argument, set it to the expansion
7604 // location so we can have the full context when annotating semantically.
7605 {
7606 SourceManager &SM = CXXUnit->getSourceManager();
7607 SourceLocation Loc =
7608 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7609 if (Loc.isMacroID())
7610 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7611 }
7612
Guy Benyei11169dd2012-12-18 14:30:41 +00007613 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7614 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007615 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7616 NumTokens);
7617 CursorVisitor MacroArgMarker(
7618 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7619 /*VisitPreprocessorLast=*/true,
7620 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007621 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7622 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007623
Guy Benyei11169dd2012-12-18 14:30:41 +00007624 // Annotate all of the source locations in the region of interest that map to
7625 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007626 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007627
Guy Benyei11169dd2012-12-18 14:30:41 +00007628 // FIXME: We use a ridiculous stack size here because the data-recursion
7629 // algorithm uses a large stack frame than the non-data recursive version,
7630 // and AnnotationTokensWorker currently transforms the data-recursion
7631 // algorithm back into a traditional recursion by explicitly calling
7632 // VisitChildren(). We will need to remove this explicit recursive call.
7633 W.AnnotateTokens();
7634
7635 // If we ran into any entities that involve context-sensitive keywords,
7636 // take another pass through the tokens to mark them as such.
7637 if (W.hasContextSensitiveKeywords()) {
7638 for (unsigned I = 0; I != NumTokens; ++I) {
7639 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7640 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007641
Guy Benyei11169dd2012-12-18 14:30:41 +00007642 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7643 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007644 if (const ObjCPropertyDecl *Property =
7645 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007646 if (Property->getPropertyAttributesAsWritten() != 0 &&
7647 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007648 .Case("readonly", true)
7649 .Case("assign", true)
7650 .Case("unsafe_unretained", true)
7651 .Case("readwrite", true)
7652 .Case("retain", true)
7653 .Case("copy", true)
7654 .Case("nonatomic", true)
7655 .Case("atomic", true)
7656 .Case("getter", true)
7657 .Case("setter", true)
7658 .Case("strong", true)
7659 .Case("weak", true)
7660 .Case("class", true)
7661 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007662 Tokens[I].int_data[0] = CXToken_Keyword;
7663 }
7664 continue;
7665 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007666
Guy Benyei11169dd2012-12-18 14:30:41 +00007667 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7668 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7669 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7670 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007671 .Case("in", true)
7672 .Case("out", true)
7673 .Case("inout", true)
7674 .Case("oneway", true)
7675 .Case("bycopy", true)
7676 .Case("byref", true)
7677 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007678 Tokens[I].int_data[0] = CXToken_Keyword;
7679 continue;
7680 }
7681
7682 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7683 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7684 Tokens[I].int_data[0] = CXToken_Keyword;
7685 continue;
7686 }
7687 }
7688 }
7689}
7690
Michael Kruse7520cf02020-03-25 09:26:14 -05007691void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7692 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007693 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007694 LOG_BAD_TU(TU);
7695 return;
7696 }
7697 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007698 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007699 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007700 }
7701
7702 LOG_FUNC_SECTION {
7703 *Log << TU << ' ';
7704 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007705 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007706 *Log << clang_getRange(bloc, eloc);
7707 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007708
7709 // Any token we don't specifically annotate will have a NULL cursor.
7710 CXCursor C = clang_getNullCursor();
7711 for (unsigned I = 0; I != NumTokens; ++I)
7712 Cursors[I] = C;
7713
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007714 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007715 if (!CXXUnit)
7716 return;
7717
7718 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007719
7720 auto AnnotateTokensImpl = [=]() {
7721 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7722 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007723 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007724 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007725 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7726 }
7727}
7728
Guy Benyei11169dd2012-12-18 14:30:41 +00007729//===----------------------------------------------------------------------===//
7730// Operations for querying linkage of a cursor.
7731//===----------------------------------------------------------------------===//
7732
Guy Benyei11169dd2012-12-18 14:30:41 +00007733CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7734 if (!clang_isDeclaration(cursor.kind))
7735 return CXLinkage_Invalid;
7736
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007737 const Decl *D = cxcursor::getCursorDecl(cursor);
7738 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007739 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007740 case NoLinkage:
7741 case VisibleNoLinkage:
7742 return CXLinkage_NoLinkage;
7743 case ModuleInternalLinkage:
7744 case InternalLinkage:
7745 return CXLinkage_Internal;
7746 case UniqueExternalLinkage:
7747 return CXLinkage_UniqueExternal;
7748 case ModuleLinkage:
7749 case ExternalLinkage:
7750 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007751 };
7752
7753 return CXLinkage_Invalid;
7754}
Guy Benyei11169dd2012-12-18 14:30:41 +00007755
7756//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007757// Operations for querying visibility of a cursor.
7758//===----------------------------------------------------------------------===//
7759
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007760CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7761 if (!clang_isDeclaration(cursor.kind))
7762 return CXVisibility_Invalid;
7763
7764 const Decl *D = cxcursor::getCursorDecl(cursor);
7765 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7766 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007767 case HiddenVisibility:
7768 return CXVisibility_Hidden;
7769 case ProtectedVisibility:
7770 return CXVisibility_Protected;
7771 case DefaultVisibility:
7772 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007773 };
7774
7775 return CXVisibility_Invalid;
7776}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007777
7778//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007779// Operations for querying language of a cursor.
7780//===----------------------------------------------------------------------===//
7781
7782static CXLanguageKind getDeclLanguage(const Decl *D) {
7783 if (!D)
7784 return CXLanguage_C;
7785
7786 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007787 default:
7788 break;
7789 case Decl::ImplicitParam:
7790 case Decl::ObjCAtDefsField:
7791 case Decl::ObjCCategory:
7792 case Decl::ObjCCategoryImpl:
7793 case Decl::ObjCCompatibleAlias:
7794 case Decl::ObjCImplementation:
7795 case Decl::ObjCInterface:
7796 case Decl::ObjCIvar:
7797 case Decl::ObjCMethod:
7798 case Decl::ObjCProperty:
7799 case Decl::ObjCPropertyImpl:
7800 case Decl::ObjCProtocol:
7801 case Decl::ObjCTypeParam:
7802 return CXLanguage_ObjC;
7803 case Decl::CXXConstructor:
7804 case Decl::CXXConversion:
7805 case Decl::CXXDestructor:
7806 case Decl::CXXMethod:
7807 case Decl::CXXRecord:
7808 case Decl::ClassTemplate:
7809 case Decl::ClassTemplatePartialSpecialization:
7810 case Decl::ClassTemplateSpecialization:
7811 case Decl::Friend:
7812 case Decl::FriendTemplate:
7813 case Decl::FunctionTemplate:
7814 case Decl::LinkageSpec:
7815 case Decl::Namespace:
7816 case Decl::NamespaceAlias:
7817 case Decl::NonTypeTemplateParm:
7818 case Decl::StaticAssert:
7819 case Decl::TemplateTemplateParm:
7820 case Decl::TemplateTypeParm:
7821 case Decl::UnresolvedUsingTypename:
7822 case Decl::UnresolvedUsingValue:
7823 case Decl::Using:
7824 case Decl::UsingDirective:
7825 case Decl::UsingShadow:
7826 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007827 }
7828
7829 return CXLanguage_C;
7830}
7831
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007832static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7833 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007834 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007835
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007836 switch (D->getAvailability()) {
7837 case AR_Available:
7838 case AR_NotYetIntroduced:
7839 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007840 return getCursorAvailabilityForDecl(
7841 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007842 return CXAvailability_Available;
7843
7844 case AR_Deprecated:
7845 return CXAvailability_Deprecated;
7846
7847 case AR_Unavailable:
7848 return CXAvailability_NotAvailable;
7849 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007850
7851 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007852}
7853
Guy Benyei11169dd2012-12-18 14:30:41 +00007854enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7855 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007856 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7857 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007858
7859 return CXAvailability_Available;
7860}
7861
7862static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007863 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007864 if (In.empty())
7865 return Out;
7866
7867 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007868
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007869 Optional<unsigned> Minor = In.getMinor();
7870 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007871 Out.Minor = *Minor;
7872 else
7873 return Out;
7874
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007875 Optional<unsigned> Subminor = In.getSubminor();
7876 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007877 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007878
Guy Benyei11169dd2012-12-18 14:30:41 +00007879 return Out;
7880}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007881
Alex Lorenz1345ea22017-06-12 19:06:30 +00007882static void getCursorPlatformAvailabilityForDecl(
7883 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7884 int *always_unavailable, CXString *unavailable_message,
7885 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007886 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007887 for (auto A : D->attrs()) {
7888 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007889 HadAvailAttr = true;
7890 if (always_deprecated)
7891 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007892 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007893 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007894 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007895 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007896 continue;
7897 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007898
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007899 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007900 HadAvailAttr = true;
7901 if (always_unavailable)
7902 *always_unavailable = 1;
7903 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007904 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007905 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7906 }
7907 continue;
7908 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007909
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007910 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007911 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007912 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007913 }
7914 }
7915
7916 if (!HadAvailAttr)
7917 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7918 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007919 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7920 deprecated_message, always_unavailable, unavailable_message,
7921 AvailabilityAttrs);
7922
7923 if (AvailabilityAttrs.empty())
7924 return;
7925
Michael Kruse7520cf02020-03-25 09:26:14 -05007926 llvm::sort(
7927 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7928 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7929 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007930 ASTContext &Ctx = D->getASTContext();
7931 auto It = std::unique(
7932 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7933 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7934 if (LHS->getPlatform() != RHS->getPlatform())
7935 return false;
7936
7937 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7938 LHS->getDeprecated() == RHS->getDeprecated() &&
7939 LHS->getObsoleted() == RHS->getObsoleted() &&
7940 LHS->getMessage() == RHS->getMessage() &&
7941 LHS->getReplacement() == RHS->getReplacement())
7942 return true;
7943
7944 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
7945 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
7946 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
7947 return false;
7948
7949 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
7950 LHS->setIntroduced(Ctx, RHS->getIntroduced());
7951
7952 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
7953 LHS->setDeprecated(Ctx, RHS->getDeprecated());
7954 if (LHS->getMessage().empty())
7955 LHS->setMessage(Ctx, RHS->getMessage());
7956 if (LHS->getReplacement().empty())
7957 LHS->setReplacement(Ctx, RHS->getReplacement());
7958 }
7959
7960 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
7961 LHS->setObsoleted(Ctx, RHS->getObsoleted());
7962 if (LHS->getMessage().empty())
7963 LHS->setMessage(Ctx, RHS->getMessage());
7964 if (LHS->getReplacement().empty())
7965 LHS->setReplacement(Ctx, RHS->getReplacement());
7966 }
7967
7968 return true;
7969 });
7970 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007971}
7972
Alex Lorenz1345ea22017-06-12 19:06:30 +00007973int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00007974 CXString *deprecated_message,
7975 int *always_unavailable,
7976 CXString *unavailable_message,
7977 CXPlatformAvailability *availability,
7978 int availability_size) {
7979 if (always_deprecated)
7980 *always_deprecated = 0;
7981 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007982 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007983 if (always_unavailable)
7984 *always_unavailable = 0;
7985 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007986 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007987
Guy Benyei11169dd2012-12-18 14:30:41 +00007988 if (!clang_isDeclaration(cursor.kind))
7989 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007990
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007991 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007992 if (!D)
7993 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007994
Alex Lorenz1345ea22017-06-12 19:06:30 +00007995 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
7996 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
7997 always_unavailable, unavailable_message,
7998 AvailabilityAttrs);
7999 for (const auto &Avail :
8000 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8001 .take_front(availability_size))) {
8002 availability[Avail.index()].Platform =
8003 cxstring::createDup(Avail.value()->getPlatform()->getName());
8004 availability[Avail.index()].Introduced =
8005 convertVersion(Avail.value()->getIntroduced());
8006 availability[Avail.index()].Deprecated =
8007 convertVersion(Avail.value()->getDeprecated());
8008 availability[Avail.index()].Obsoleted =
8009 convertVersion(Avail.value()->getObsoleted());
8010 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8011 availability[Avail.index()].Message =
8012 cxstring::createDup(Avail.value()->getMessage());
8013 }
8014
8015 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008016}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008017
Guy Benyei11169dd2012-12-18 14:30:41 +00008018void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8019 clang_disposeString(availability->Platform);
8020 clang_disposeString(availability->Message);
8021}
8022
8023CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8024 if (clang_isDeclaration(cursor.kind))
8025 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8026
8027 return CXLanguage_Invalid;
8028}
8029
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008030CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8031 const Decl *D = cxcursor::getCursorDecl(cursor);
8032 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8033 switch (VD->getTLSKind()) {
8034 case VarDecl::TLS_None:
8035 return CXTLS_None;
8036 case VarDecl::TLS_Dynamic:
8037 return CXTLS_Dynamic;
8038 case VarDecl::TLS_Static:
8039 return CXTLS_Static;
8040 }
8041 }
8042
8043 return CXTLS_None;
8044}
8045
Michael Kruse7520cf02020-03-25 09:26:14 -05008046/// If the given cursor is the "templated" declaration
8047/// describing a class or function template, return the class or
8048/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008049static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008050 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008051 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008052
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008053 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008054 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8055 return FunTmpl;
8056
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008057 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008058 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8059 return ClassTmpl;
8060
8061 return D;
8062}
8063
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008064enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8065 StorageClass sc = SC_None;
8066 const Decl *D = getCursorDecl(C);
8067 if (D) {
8068 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8069 sc = FD->getStorageClass();
8070 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8071 sc = VD->getStorageClass();
8072 } else {
8073 return CX_SC_Invalid;
8074 }
8075 } else {
8076 return CX_SC_Invalid;
8077 }
8078 switch (sc) {
8079 case SC_None:
8080 return CX_SC_None;
8081 case SC_Extern:
8082 return CX_SC_Extern;
8083 case SC_Static:
8084 return CX_SC_Static;
8085 case SC_PrivateExtern:
8086 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008087 case SC_Auto:
8088 return CX_SC_Auto;
8089 case SC_Register:
8090 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008091 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008092 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008093}
8094
Guy Benyei11169dd2012-12-18 14:30:41 +00008095CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8096 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008097 if (const Decl *D = getCursorDecl(cursor)) {
8098 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008099 if (!DC)
8100 return clang_getNullCursor();
8101
Michael Kruse7520cf02020-03-25 09:26:14 -05008102 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008103 getCursorTU(cursor));
8104 }
8105 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008106
Guy Benyei11169dd2012-12-18 14:30:41 +00008107 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008108 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008109 return MakeCXCursor(D, getCursorTU(cursor));
8110 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008111
Guy Benyei11169dd2012-12-18 14:30:41 +00008112 return clang_getNullCursor();
8113}
8114
8115CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8116 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008117 if (const Decl *D = getCursorDecl(cursor)) {
8118 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008119 if (!DC)
8120 return clang_getNullCursor();
8121
Michael Kruse7520cf02020-03-25 09:26:14 -05008122 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008123 getCursorTU(cursor));
8124 }
8125 }
8126
Michael Kruse7520cf02020-03-25 09:26:14 -05008127 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008128 // statement or expression, so we return nothing.
8129 return clang_getNullCursor();
8130}
8131
8132CXFile clang_getIncludedFile(CXCursor cursor) {
8133 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008134 return nullptr;
8135
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008136 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008137 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008138}
8139
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008140unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8141 if (C.kind != CXCursor_ObjCPropertyDecl)
8142 return CXObjCPropertyAttr_noattr;
8143
8144 unsigned Result = CXObjCPropertyAttr_noattr;
8145 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8146 ObjCPropertyDecl::PropertyAttributeKind Attr =
8147 PD->getPropertyAttributesAsWritten();
8148
Michael Kruse7520cf02020-03-25 09:26:14 -05008149#define SET_CXOBJCPROP_ATTR(A) \
8150 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
8151 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008152 SET_CXOBJCPROP_ATTR(readonly);
8153 SET_CXOBJCPROP_ATTR(getter);
8154 SET_CXOBJCPROP_ATTR(assign);
8155 SET_CXOBJCPROP_ATTR(readwrite);
8156 SET_CXOBJCPROP_ATTR(retain);
8157 SET_CXOBJCPROP_ATTR(copy);
8158 SET_CXOBJCPROP_ATTR(nonatomic);
8159 SET_CXOBJCPROP_ATTR(setter);
8160 SET_CXOBJCPROP_ATTR(atomic);
8161 SET_CXOBJCPROP_ATTR(weak);
8162 SET_CXOBJCPROP_ATTR(strong);
8163 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008164 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008165#undef SET_CXOBJCPROP_ATTR
8166
8167 return Result;
8168}
8169
Michael Wu6e88f532018-08-03 05:38:29 +00008170CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8171 if (C.kind != CXCursor_ObjCPropertyDecl)
8172 return cxstring::createNull();
8173
8174 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8175 Selector sel = PD->getGetterName();
8176 if (sel.isNull())
8177 return cxstring::createNull();
8178
8179 return cxstring::createDup(sel.getAsString());
8180}
8181
8182CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8183 if (C.kind != CXCursor_ObjCPropertyDecl)
8184 return cxstring::createNull();
8185
8186 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8187 Selector sel = PD->getSetterName();
8188 if (sel.isNull())
8189 return cxstring::createNull();
8190
8191 return cxstring::createDup(sel.getAsString());
8192}
8193
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008194unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8195 if (!clang_isDeclaration(C.kind))
8196 return CXObjCDeclQualifier_None;
8197
8198 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8199 const Decl *D = getCursorDecl(C);
8200 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8201 QT = MD->getObjCDeclQualifier();
8202 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8203 QT = PD->getObjCDeclQualifier();
8204 if (QT == Decl::OBJC_TQ_None)
8205 return CXObjCDeclQualifier_None;
8206
8207 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008208 if (QT & Decl::OBJC_TQ_In)
8209 Result |= CXObjCDeclQualifier_In;
8210 if (QT & Decl::OBJC_TQ_Inout)
8211 Result |= CXObjCDeclQualifier_Inout;
8212 if (QT & Decl::OBJC_TQ_Out)
8213 Result |= CXObjCDeclQualifier_Out;
8214 if (QT & Decl::OBJC_TQ_Bycopy)
8215 Result |= CXObjCDeclQualifier_Bycopy;
8216 if (QT & Decl::OBJC_TQ_Byref)
8217 Result |= CXObjCDeclQualifier_Byref;
8218 if (QT & Decl::OBJC_TQ_Oneway)
8219 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008220
8221 return Result;
8222}
8223
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008224unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8225 if (!clang_isDeclaration(C.kind))
8226 return 0;
8227
8228 const Decl *D = getCursorDecl(C);
8229 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8230 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8231 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8232 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8233
8234 return 0;
8235}
8236
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008237unsigned clang_Cursor_isVariadic(CXCursor C) {
8238 if (!clang_isDeclaration(C.kind))
8239 return 0;
8240
8241 const Decl *D = getCursorDecl(C);
8242 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8243 return FD->isVariadic();
8244 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8245 return MD->isVariadic();
8246
8247 return 0;
8248}
8249
Michael Kruse7520cf02020-03-25 09:26:14 -05008250unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8251 CXString *definedIn,
8252 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008253 if (!clang_isDeclaration(C.kind))
8254 return 0;
8255
8256 const Decl *D = getCursorDecl(C);
8257
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008258 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008259 if (language)
8260 *language = cxstring::createDup(attr->getLanguage());
8261 if (definedIn)
8262 *definedIn = cxstring::createDup(attr->getDefinedIn());
8263 if (isGenerated)
8264 *isGenerated = attr->getGeneratedDeclaration();
8265 return 1;
8266 }
8267 return 0;
8268}
8269
Guy Benyei11169dd2012-12-18 14:30:41 +00008270CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8271 if (!clang_isDeclaration(C.kind))
8272 return clang_getNullRange();
8273
8274 const Decl *D = getCursorDecl(C);
8275 ASTContext &Context = getCursorContext(C);
8276 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8277 if (!RC)
8278 return clang_getNullRange();
8279
8280 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8281}
8282
8283CXString clang_Cursor_getRawCommentText(CXCursor C) {
8284 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008285 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008286
8287 const Decl *D = getCursorDecl(C);
8288 ASTContext &Context = getCursorContext(C);
8289 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008290 StringRef RawText =
8291 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008292
8293 // Don't duplicate the string because RawText points directly into source
8294 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008295 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008296}
8297
8298CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8299 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008300 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008301
8302 const Decl *D = getCursorDecl(C);
8303 const ASTContext &Context = getCursorContext(C);
8304 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8305
8306 if (RC) {
8307 StringRef BriefText = RC->getBriefText(Context);
8308
8309 // Don't duplicate the string because RawComment ensures that this memory
8310 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008311 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008312 }
8313
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008314 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008315}
8316
Guy Benyei11169dd2012-12-18 14:30:41 +00008317CXModule clang_Cursor_getModule(CXCursor C) {
8318 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008319 if (const ImportDecl *ImportD =
8320 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008321 return ImportD->getImportedModule();
8322 }
8323
Craig Topper69186e72014-06-08 08:38:04 +00008324 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008325}
8326
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008327CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8328 if (isNotUsableTU(TU)) {
8329 LOG_BAD_TU(TU);
8330 return nullptr;
8331 }
8332 if (!File)
8333 return nullptr;
8334 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008335
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008336 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8337 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8338 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008339
Richard Smithfeb54b62014-10-23 02:01:19 +00008340 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008341}
8342
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008343CXFile clang_Module_getASTFile(CXModule CXMod) {
8344 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008345 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008346 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008347 return const_cast<FileEntry *>(Mod->getASTFile());
8348}
8349
Guy Benyei11169dd2012-12-18 14:30:41 +00008350CXModule clang_Module_getParent(CXModule CXMod) {
8351 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008352 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008353 Module *Mod = static_cast<Module *>(CXMod);
Guy Benyei11169dd2012-12-18 14:30:41 +00008354 return Mod->Parent;
8355}
8356
8357CXString clang_Module_getName(CXModule CXMod) {
8358 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008359 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008360 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008361 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008362}
8363
8364CXString clang_Module_getFullName(CXModule CXMod) {
8365 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008366 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008367 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008368 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008369}
8370
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008371int clang_Module_isSystem(CXModule CXMod) {
8372 if (!CXMod)
8373 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008374 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008375 return Mod->IsSystem;
8376}
8377
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008378unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8379 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008380 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008381 LOG_BAD_TU(TU);
8382 return 0;
8383 }
8384 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008385 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008386 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008387 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8388 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8389 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008390}
8391
Michael Kruse7520cf02020-03-25 09:26:14 -05008392CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8393 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008394 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008395 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008396 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008397 }
8398 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008399 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008400 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008401 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008402
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008403 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8404 if (Index < TopHeaders.size())
8405 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008406
Craig Topper69186e72014-06-08 08:38:04 +00008407 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008408}
8409
Guy Benyei11169dd2012-12-18 14:30:41 +00008410//===----------------------------------------------------------------------===//
8411// C++ AST instrospection.
8412//===----------------------------------------------------------------------===//
8413
Jonathan Coe29565352016-04-27 12:48:25 +00008414unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8415 if (!clang_isDeclaration(C.kind))
8416 return 0;
8417
8418 const Decl *D = cxcursor::getCursorDecl(C);
8419 const CXXConstructorDecl *Constructor =
8420 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8421 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8422}
8423
8424unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8425 if (!clang_isDeclaration(C.kind))
8426 return 0;
8427
8428 const Decl *D = cxcursor::getCursorDecl(C);
8429 const CXXConstructorDecl *Constructor =
8430 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8431 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8432}
8433
8434unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8435 if (!clang_isDeclaration(C.kind))
8436 return 0;
8437
8438 const Decl *D = cxcursor::getCursorDecl(C);
8439 const CXXConstructorDecl *Constructor =
8440 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8441 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8442}
8443
8444unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8445 if (!clang_isDeclaration(C.kind))
8446 return 0;
8447
8448 const Decl *D = cxcursor::getCursorDecl(C);
8449 const CXXConstructorDecl *Constructor =
8450 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8451 // Passing 'false' excludes constructors marked 'explicit'.
8452 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8453}
8454
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008455unsigned clang_CXXField_isMutable(CXCursor C) {
8456 if (!clang_isDeclaration(C.kind))
8457 return 0;
8458
8459 if (const auto D = cxcursor::getCursorDecl(C))
8460 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8461 return FD->isMutable() ? 1 : 0;
8462 return 0;
8463}
8464
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008465unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8466 if (!clang_isDeclaration(C.kind))
8467 return 0;
8468
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008469 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008470 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008471 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008472 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8473}
8474
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008475unsigned clang_CXXMethod_isConst(CXCursor C) {
8476 if (!clang_isDeclaration(C.kind))
8477 return 0;
8478
8479 const Decl *D = cxcursor::getCursorDecl(C);
8480 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008481 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008482 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008483}
8484
Jonathan Coe29565352016-04-27 12:48:25 +00008485unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8486 if (!clang_isDeclaration(C.kind))
8487 return 0;
8488
8489 const Decl *D = cxcursor::getCursorDecl(C);
8490 const CXXMethodDecl *Method =
8491 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8492 return (Method && Method->isDefaulted()) ? 1 : 0;
8493}
8494
Guy Benyei11169dd2012-12-18 14:30:41 +00008495unsigned clang_CXXMethod_isStatic(CXCursor C) {
8496 if (!clang_isDeclaration(C.kind))
8497 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008498
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008499 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008500 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008501 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008502 return (Method && Method->isStatic()) ? 1 : 0;
8503}
8504
8505unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8506 if (!clang_isDeclaration(C.kind))
8507 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008508
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008509 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008510 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008511 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008512 return (Method && Method->isVirtual()) ? 1 : 0;
8513}
Guy Benyei11169dd2012-12-18 14:30:41 +00008514
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008515unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8516 if (!clang_isDeclaration(C.kind))
8517 return 0;
8518
8519 const auto *D = cxcursor::getCursorDecl(C);
8520 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8521 if (RD)
8522 RD = RD->getDefinition();
8523 return (RD && RD->isAbstract()) ? 1 : 0;
8524}
8525
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008526unsigned clang_EnumDecl_isScoped(CXCursor C) {
8527 if (!clang_isDeclaration(C.kind))
8528 return 0;
8529
8530 const Decl *D = cxcursor::getCursorDecl(C);
8531 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8532 return (Enum && Enum->isScoped()) ? 1 : 0;
8533}
8534
Guy Benyei11169dd2012-12-18 14:30:41 +00008535//===----------------------------------------------------------------------===//
8536// Attribute introspection.
8537//===----------------------------------------------------------------------===//
8538
Guy Benyei11169dd2012-12-18 14:30:41 +00008539CXType clang_getIBOutletCollectionType(CXCursor C) {
8540 if (C.kind != CXCursor_IBOutletCollectionAttr)
8541 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008542
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008543 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008544 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8545
8546 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008547}
Guy Benyei11169dd2012-12-18 14:30:41 +00008548
8549//===----------------------------------------------------------------------===//
8550// Inspecting memory usage.
8551//===----------------------------------------------------------------------===//
8552
8553typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8554
8555static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008556 enum CXTUResourceUsageKind k,
8557 unsigned long amount) {
8558 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008559 entries.push_back(entry);
8560}
8561
Guy Benyei11169dd2012-12-18 14:30:41 +00008562const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8563 const char *str = "";
8564 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008565 case CXTUResourceUsage_AST:
8566 str = "ASTContext: expressions, declarations, and types";
8567 break;
8568 case CXTUResourceUsage_Identifiers:
8569 str = "ASTContext: identifiers";
8570 break;
8571 case CXTUResourceUsage_Selectors:
8572 str = "ASTContext: selectors";
8573 break;
8574 case CXTUResourceUsage_GlobalCompletionResults:
8575 str = "Code completion: cached global results";
8576 break;
8577 case CXTUResourceUsage_SourceManagerContentCache:
8578 str = "SourceManager: content cache allocator";
8579 break;
8580 case CXTUResourceUsage_AST_SideTables:
8581 str = "ASTContext: side tables";
8582 break;
8583 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8584 str = "SourceManager: malloc'ed memory buffers";
8585 break;
8586 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8587 str = "SourceManager: mmap'ed memory buffers";
8588 break;
8589 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8590 str = "ExternalASTSource: malloc'ed memory buffers";
8591 break;
8592 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8593 str = "ExternalASTSource: mmap'ed memory buffers";
8594 break;
8595 case CXTUResourceUsage_Preprocessor:
8596 str = "Preprocessor: malloc'ed memory";
8597 break;
8598 case CXTUResourceUsage_PreprocessingRecord:
8599 str = "Preprocessor: PreprocessingRecord";
8600 break;
8601 case CXTUResourceUsage_SourceManager_DataStructures:
8602 str = "SourceManager: data structures and tables";
8603 break;
8604 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8605 str = "Preprocessor: header search tables";
8606 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008607 }
8608 return str;
8609}
8610
8611CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008612 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008613 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008614 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008615 return usage;
8616 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008617
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008618 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008619 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008620 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008621
Guy Benyei11169dd2012-12-18 14:30:41 +00008622 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008623 createCXTUResourceUsageEntry(
8624 *entries, CXTUResourceUsage_AST,
8625 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008626
8627 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008628 createCXTUResourceUsageEntry(
8629 *entries, CXTUResourceUsage_Identifiers,
8630 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008631
8632 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008633 createCXTUResourceUsageEntry(
8634 *entries, CXTUResourceUsage_Selectors,
8635 (unsigned long)astContext.Selectors.getTotalMemory());
8636
Guy Benyei11169dd2012-12-18 14:30:41 +00008637 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008638 createCXTUResourceUsageEntry(
8639 *entries, CXTUResourceUsage_AST_SideTables,
8640 (unsigned long)astContext.getSideTableAllocatedMemory());
8641
Guy Benyei11169dd2012-12-18 14:30:41 +00008642 // How much memory is used for caching global code completion results?
8643 unsigned long completionBytes = 0;
8644 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008645 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008646 completionBytes = completionAllocator->getTotalMemory();
8647 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008648 createCXTUResourceUsageEntry(
8649 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8650
Guy Benyei11169dd2012-12-18 14:30:41 +00008651 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008652 createCXTUResourceUsageEntry(
8653 *entries, CXTUResourceUsage_SourceManagerContentCache,
8654 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8655
Guy Benyei11169dd2012-12-18 14:30:41 +00008656 // How much memory is being used by the MemoryBuffer's in SourceManager?
8657 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008658 astUnit->getSourceManager().getMemoryBufferSizes();
8659
Guy Benyei11169dd2012-12-18 14:30:41 +00008660 createCXTUResourceUsageEntry(*entries,
8661 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008662 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008663 createCXTUResourceUsageEntry(*entries,
8664 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008665 (unsigned long)srcBufs.mmap_bytes);
8666 createCXTUResourceUsageEntry(
8667 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8668 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8669
Guy Benyei11169dd2012-12-18 14:30:41 +00008670 // How much memory is being used by the ExternalASTSource?
8671 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8672 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008673 esrc->getMemoryBufferSizes();
8674
8675 createCXTUResourceUsageEntry(
8676 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8677 (unsigned long)sizes.malloc_bytes);
8678 createCXTUResourceUsageEntry(
8679 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8680 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008681 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008682
Guy Benyei11169dd2012-12-18 14:30:41 +00008683 // How much memory is being used by the Preprocessor?
8684 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008685 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008686 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008687
Guy Benyei11169dd2012-12-18 14:30:41 +00008688 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8689 createCXTUResourceUsageEntry(*entries,
8690 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008691 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008692 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008693
Guy Benyei11169dd2012-12-18 14:30:41 +00008694 createCXTUResourceUsageEntry(*entries,
8695 CXTUResourceUsage_Preprocessor_HeaderSearch,
8696 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008697
Michael Kruse7520cf02020-03-25 09:26:14 -05008698 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8699 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008700 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008701 return usage;
8702}
8703
8704void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8705 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008706 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008707}
8708
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008709CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8710 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008711 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008712 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008713
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008714 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008715 LOG_BAD_TU(TU);
8716 return skipped;
8717 }
8718
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008719 if (!file)
8720 return skipped;
8721
8722 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008723 PreprocessingRecord *ppRec =
8724 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008725 if (!ppRec)
8726 return skipped;
8727
8728 ASTContext &Ctx = astUnit->getASTContext();
8729 SourceManager &sm = Ctx.getSourceManager();
8730 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8731 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008732 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008733
8734 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8735 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008736 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8737 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008738 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008739 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8740 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008741 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008742 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8743 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008744 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008745 }
8746
8747 skipped->count = wantedRanges.size();
8748 skipped->ranges = new CXSourceRange[skipped->count];
8749 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8750 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8751
8752 return skipped;
8753}
8754
Cameron Desrochersd8091282016-08-18 15:43:55 +00008755CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8756 CXSourceRangeList *skipped = new CXSourceRangeList;
8757 skipped->count = 0;
8758 skipped->ranges = nullptr;
8759
8760 if (isNotUsableTU(TU)) {
8761 LOG_BAD_TU(TU);
8762 return skipped;
8763 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008764
Cameron Desrochersd8091282016-08-18 15:43:55 +00008765 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008766 PreprocessingRecord *ppRec =
8767 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008768 if (!ppRec)
8769 return skipped;
8770
8771 ASTContext &Ctx = astUnit->getASTContext();
8772
8773 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8774
8775 skipped->count = SkippedRanges.size();
8776 skipped->ranges = new CXSourceRange[skipped->count];
8777 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8778 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8779
8780 return skipped;
8781}
8782
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008783void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8784 if (ranges) {
8785 delete[] ranges->ranges;
8786 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008787 }
8788}
8789
Guy Benyei11169dd2012-12-18 14:30:41 +00008790void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8791 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8792 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008793 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008794 clang_getTUResourceUsageName(Usage.entries[I].kind),
8795 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008796
Guy Benyei11169dd2012-12-18 14:30:41 +00008797 clang_disposeCXTUResourceUsage(Usage);
8798}
8799
8800//===----------------------------------------------------------------------===//
8801// Misc. utility functions.
8802//===----------------------------------------------------------------------===//
8803
Richard Smith0a7b2972018-07-03 21:34:13 +00008804/// Default to using our desired 8 MB stack size on "safety" threads.
8805static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008806
8807namespace clang {
8808
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008809bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008810 unsigned Size) {
8811 if (!Size)
8812 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008813 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008814 return CRC.RunSafelyOnThread(Fn, Size);
8815 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008816}
8817
Michael Kruse7520cf02020-03-25 09:26:14 -05008818unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008819
Michael Kruse7520cf02020-03-25 09:26:14 -05008820void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008821
Michael Kruse7520cf02020-03-25 09:26:14 -05008822} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008823
8824void clang::setThreadBackgroundPriority() {
8825 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8826 return;
8827
Nico Weber18cfd9f2019-04-21 19:18:41 +00008828#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008829 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008830#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008831}
8832
8833void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8834 if (!Unit)
8835 return;
8836
Michael Kruse7520cf02020-03-25 09:26:14 -05008837 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8838 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008839 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008840 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008841 CXString Msg =
8842 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008843 fprintf(stderr, "%s\n", clang_getCString(Msg));
8844 clang_disposeString(Msg);
8845 }
Nico Weber1865df42018-04-27 19:11:14 +00008846#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008847 // On Windows, force a flush, since there may be multiple copies of
8848 // stderr and stdout in the file system, all with different buffers
8849 // but writing to the same device.
8850 fflush(stderr);
8851#endif
8852}
8853
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008854MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8855 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008856 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008857 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008858 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008859 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008860 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008861
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008862 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008863 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008864 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008865 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008866 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8867 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008868 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8869 return Def.getMacroInfo();
8870 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008871 }
8872
Craig Topper69186e72014-06-08 08:38:04 +00008873 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008874}
8875
Richard Smith66a81862015-05-04 02:25:31 +00008876const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008877 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008878 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008879 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008880 const IdentifierInfo *II = MacroDef->getName();
8881 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008882 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008883
8884 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8885}
8886
Richard Smith66a81862015-05-04 02:25:31 +00008887MacroDefinitionRecord *
8888cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8889 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008890 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008891 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008892 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008893 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008894
8895 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008896 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008897 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8898 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008899 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008900
8901 // Check that the token is inside the definition and not its argument list.
8902 SourceManager &SM = Unit->getSourceManager();
8903 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008904 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008905 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00008906 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008907
8908 Preprocessor &PP = Unit->getPreprocessor();
8909 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
8910 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00008911 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008912
Alp Toker2d57cea2014-05-17 04:53:25 +00008913 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008914 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008915 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008916
8917 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00008918 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00008919 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008920
Richard Smith20e883e2015-04-29 23:20:19 +00008921 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00008922 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00008923 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008924
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008925 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008926}
8927
Richard Smith66a81862015-05-04 02:25:31 +00008928MacroDefinitionRecord *
8929cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
8930 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008931 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008932 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008933
8934 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008935 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008936 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008937 Preprocessor &PP = Unit->getPreprocessor();
8938 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00008939 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008940 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
8941 Token Tok;
8942 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00008943 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008944
8945 return checkForMacroInMacroDefinition(MI, Tok, TU);
8946}
8947
Guy Benyei11169dd2012-12-18 14:30:41 +00008948CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008949 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00008950}
8951
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008952Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
8953 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008954 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008955 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00008956 if (Unit->isMainFileAST())
8957 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008958 return *this;
8959 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00008960 } else {
8961 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008962 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008963 return *this;
8964}
8965
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00008966Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
8967 *this << FE->getName();
8968 return *this;
8969}
8970
8971Logger &cxindex::Logger::operator<<(CXCursor cursor) {
8972 CXString cursorName = clang_getCursorDisplayName(cursor);
8973 *this << cursorName << "@" << clang_getCursorLocation(cursor);
8974 clang_disposeString(cursorName);
8975 return *this;
8976}
8977
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008978Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
8979 CXFile File;
8980 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00008981 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008982 CXString FileName = clang_getFileName(File);
8983 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
8984 clang_disposeString(FileName);
8985 return *this;
8986}
8987
8988Logger &cxindex::Logger::operator<<(CXSourceRange range) {
8989 CXSourceLocation BLoc = clang_getRangeStart(range);
8990 CXSourceLocation ELoc = clang_getRangeEnd(range);
8991
8992 CXFile BFile;
8993 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00008994 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008995
8996 CXFile EFile;
8997 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00008998 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008999
9000 CXString BFileName = clang_getFileName(BFile);
9001 if (BFile == EFile) {
9002 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05009003 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009004 } else {
9005 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009006 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9007 BColumn)
9008 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9009 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009010 clang_disposeString(EFileName);
9011 }
9012 clang_disposeString(BFileName);
9013 return *this;
9014}
9015
9016Logger &cxindex::Logger::operator<<(CXString Str) {
9017 *this << clang_getCString(Str);
9018 return *this;
9019}
9020
9021Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9022 LogOS << Fmt;
9023 return *this;
9024}
9025
Benjamin Kramer762bc332019-08-07 14:44:40 +00009026static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009027
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009028cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009029 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009030
9031 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9032
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009033 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009034 OS << "[libclang:" << Name << ':';
9035
Alp Toker1a86ad22014-07-06 06:24:00 +00009036#ifdef USE_DARWIN_THREADS
9037 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009038 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9039 OS << tid << ':';
9040#endif
9041
9042 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9043 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009044 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009045
9046 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009047 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009048 OS << "--------------------------------------------------\n";
9049 }
9050}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009051
9052#ifdef CLANG_TOOL_EXTRA_BUILD
9053// This anchor is used to force the linker to link the clang-tidy plugin.
9054extern volatile int ClangTidyPluginAnchorSource;
9055static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9056 ClangTidyPluginAnchorSource;
9057
9058// This anchor is used to force the linker to link the clang-include-fixer
9059// plugin.
9060extern volatile int ClangIncludeFixerPluginAnchorSource;
9061static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9062 ClangIncludeFixerPluginAnchorSource;
9063#endif