blob: 1267b9b50fd3ac2a03874325a90ef3d3acf3e6b7 [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 Doerfertc18d5592020-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");
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 case CXCursor_BinaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005189 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 case CXCursor_CompoundAssignOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005191 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 case CXCursor_ConditionalOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005193 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 case CXCursor_CStyleCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005195 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 case CXCursor_CompoundLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005197 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 case CXCursor_InitListExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005199 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 case CXCursor_AddrLabelExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005201 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 case CXCursor_StmtExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005203 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 case CXCursor_GenericSelectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005205 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 case CXCursor_GNUNullExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005207 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 case CXCursor_CXXStaticCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005209 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 case CXCursor_CXXDynamicCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005211 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 case CXCursor_CXXReinterpretCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005213 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 case CXCursor_CXXConstCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005215 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 case CXCursor_CXXFunctionalCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005217 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 case CXCursor_CXXTypeidExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005219 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 case CXCursor_CXXBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005221 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 case CXCursor_CXXNullPtrLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005223 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 case CXCursor_CXXThisExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005225 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 case CXCursor_CXXThrowExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005227 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 case CXCursor_CXXNewExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005229 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 case CXCursor_CXXDeleteExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005231 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 case CXCursor_UnaryExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005233 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 case CXCursor_ObjCStringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005235 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 case CXCursor_ObjCBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005237 return cxstring::createRef("ObjCBoolLiteralExpr");
Erik Pilkington29099de2016-07-16 00:35:23 +00005238 case CXCursor_ObjCAvailabilityCheckExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005239 return cxstring::createRef("ObjCAvailabilityCheckExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00005240 case CXCursor_ObjCSelfExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005241 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 case CXCursor_ObjCEncodeExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005243 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 case CXCursor_ObjCSelectorExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005245 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 case CXCursor_ObjCProtocolExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005247 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 case CXCursor_ObjCBridgedCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005249 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 case CXCursor_BlockExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005251 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 case CXCursor_PackExpansionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005253 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 case CXCursor_SizeOfPackExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005255 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005257 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 case CXCursor_UnexposedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005259 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 case CXCursor_DeclRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005261 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 case CXCursor_MemberRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005263 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005265 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 case CXCursor_ObjCMessageExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005267 return cxstring::createRef("ObjCMessageExpr");
Erik Pilkingtoneee944e2019-07-02 18:28:13 +00005268 case CXCursor_BuiltinBitCastExpr:
5269 return cxstring::createRef("BuiltinBitCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 case CXCursor_UnexposedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005271 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 case CXCursor_DeclStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005273 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 case CXCursor_LabelStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005275 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 case CXCursor_CompoundStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005277 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 case CXCursor_CaseStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005279 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 case CXCursor_DefaultStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005281 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 case CXCursor_IfStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005283 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 case CXCursor_SwitchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005285 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 case CXCursor_WhileStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005287 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 case CXCursor_DoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005289 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 case CXCursor_ForStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005291 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 case CXCursor_GotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005293 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 case CXCursor_IndirectGotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005295 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 case CXCursor_ContinueStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005297 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 case CXCursor_BreakStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005299 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 case CXCursor_ReturnStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005301 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 case CXCursor_GCCAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005303 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 case CXCursor_MSAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005305 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 case CXCursor_ObjCAtTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005307 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 case CXCursor_ObjCAtCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005309 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 case CXCursor_ObjCAtFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005311 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 case CXCursor_ObjCAtThrowStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005313 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 case CXCursor_ObjCAtSynchronizedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005315 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 case CXCursor_ObjCAutoreleasePoolStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005317 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 case CXCursor_ObjCForCollectionStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005319 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 case CXCursor_CXXCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005321 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 case CXCursor_CXXTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005323 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 case CXCursor_CXXForRangeStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005325 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 case CXCursor_SEHTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005327 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 case CXCursor_SEHExceptStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005329 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 case CXCursor_SEHFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005331 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00005332 case CXCursor_SEHLeaveStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005333 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 case CXCursor_NullStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005335 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 case CXCursor_InvalidFile:
Michael Kruse7520cf02020-03-25 09:26:14 -05005337 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005339 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 case CXCursor_NoDeclFound:
Michael Kruse7520cf02020-03-25 09:26:14 -05005341 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 case CXCursor_NotImplemented:
Michael Kruse7520cf02020-03-25 09:26:14 -05005343 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 case CXCursor_TranslationUnit:
Michael Kruse7520cf02020-03-25 09:26:14 -05005345 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 case CXCursor_UnexposedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005347 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 case CXCursor_IBActionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005349 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 case CXCursor_IBOutletAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005351 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 case CXCursor_IBOutletCollectionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005353 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 case CXCursor_CXXFinalAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005355 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 case CXCursor_CXXOverrideAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005357 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005359 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005361 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005362 case CXCursor_PackedAttr:
5363 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00005364 case CXCursor_PureAttr:
5365 return cxstring::createRef("attribute(pure)");
5366 case CXCursor_ConstAttr:
5367 return cxstring::createRef("attribute(const)");
5368 case CXCursor_NoDuplicateAttr:
5369 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00005370 case CXCursor_CUDAConstantAttr:
5371 return cxstring::createRef("attribute(constant)");
5372 case CXCursor_CUDADeviceAttr:
5373 return cxstring::createRef("attribute(device)");
5374 case CXCursor_CUDAGlobalAttr:
5375 return cxstring::createRef("attribute(global)");
5376 case CXCursor_CUDAHostAttr:
5377 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00005378 case CXCursor_CUDASharedAttr:
5379 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00005380 case CXCursor_VisibilityAttr:
5381 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00005382 case CXCursor_DLLExport:
5383 return cxstring::createRef("attribute(dllexport)");
5384 case CXCursor_DLLImport:
5385 return cxstring::createRef("attribute(dllimport)");
Michael Wud092d0b2018-08-03 05:03:22 +00005386 case CXCursor_NSReturnsRetained:
5387 return cxstring::createRef("attribute(ns_returns_retained)");
5388 case CXCursor_NSReturnsNotRetained:
5389 return cxstring::createRef("attribute(ns_returns_not_retained)");
5390 case CXCursor_NSReturnsAutoreleased:
5391 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5392 case CXCursor_NSConsumesSelf:
5393 return cxstring::createRef("attribute(ns_consumes_self)");
5394 case CXCursor_NSConsumed:
5395 return cxstring::createRef("attribute(ns_consumed)");
5396 case CXCursor_ObjCException:
5397 return cxstring::createRef("attribute(objc_exception)");
5398 case CXCursor_ObjCNSObject:
5399 return cxstring::createRef("attribute(NSObject)");
5400 case CXCursor_ObjCIndependentClass:
5401 return cxstring::createRef("attribute(objc_independent_class)");
5402 case CXCursor_ObjCPreciseLifetime:
5403 return cxstring::createRef("attribute(objc_precise_lifetime)");
5404 case CXCursor_ObjCReturnsInnerPointer:
5405 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5406 case CXCursor_ObjCRequiresSuper:
5407 return cxstring::createRef("attribute(objc_requires_super)");
5408 case CXCursor_ObjCRootClass:
5409 return cxstring::createRef("attribute(objc_root_class)");
5410 case CXCursor_ObjCSubclassingRestricted:
5411 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5412 case CXCursor_ObjCExplicitProtocolImpl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005413 return cxstring::createRef(
5414 "attribute(objc_protocol_requires_explicit_implementation)");
Michael Wud092d0b2018-08-03 05:03:22 +00005415 case CXCursor_ObjCDesignatedInitializer:
5416 return cxstring::createRef("attribute(objc_designated_initializer)");
5417 case CXCursor_ObjCRuntimeVisible:
5418 return cxstring::createRef("attribute(objc_runtime_visible)");
5419 case CXCursor_ObjCBoxable:
5420 return cxstring::createRef("attribute(objc_boxable)");
Michael Wu58d837d2018-08-03 05:55:40 +00005421 case CXCursor_FlagEnum:
5422 return cxstring::createRef("attribute(flag_enum)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005424 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005425 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005426 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00005427 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005428 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005430 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005432 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005434 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005436 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005438 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005440 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005442 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005444 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005446 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005448 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005450 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005452 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005454 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005456 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005458 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005460 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005462 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005464 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005466 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005468 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005470 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005471 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00005472 return cxstring::createRef("OMPParallelDirective");
5473 case CXCursor_OMPSimdDirective:
5474 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00005475 case CXCursor_OMPForDirective:
5476 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00005477 case CXCursor_OMPForSimdDirective:
5478 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00005479 case CXCursor_OMPSectionsDirective:
5480 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00005481 case CXCursor_OMPSectionDirective:
5482 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00005483 case CXCursor_OMPSingleDirective:
5484 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00005485 case CXCursor_OMPMasterDirective:
5486 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00005487 case CXCursor_OMPCriticalDirective:
5488 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00005489 case CXCursor_OMPParallelForDirective:
5490 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00005491 case CXCursor_OMPParallelForSimdDirective:
5492 return cxstring::createRef("OMPParallelForSimdDirective");
cchen47d60942019-12-05 13:43:48 -05005493 case CXCursor_OMPParallelMasterDirective:
5494 return cxstring::createRef("OMPParallelMasterDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00005495 case CXCursor_OMPParallelSectionsDirective:
5496 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00005497 case CXCursor_OMPTaskDirective:
5498 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00005499 case CXCursor_OMPTaskyieldDirective:
5500 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00005501 case CXCursor_OMPBarrierDirective:
5502 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00005503 case CXCursor_OMPTaskwaitDirective:
5504 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00005505 case CXCursor_OMPTaskgroupDirective:
5506 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00005507 case CXCursor_OMPFlushDirective:
5508 return cxstring::createRef("OMPFlushDirective");
Alexey Bataevc112e942020-02-28 09:52:15 -05005509 case CXCursor_OMPDepobjDirective:
5510 return cxstring::createRef("OMPDepobjDirective");
Alexey Bataevfcba7c32020-03-20 07:03:01 -04005511 case CXCursor_OMPScanDirective:
5512 return cxstring::createRef("OMPScanDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00005513 case CXCursor_OMPOrderedDirective:
5514 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00005515 case CXCursor_OMPAtomicDirective:
5516 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00005517 case CXCursor_OMPTargetDirective:
5518 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00005519 case CXCursor_OMPTargetDataDirective:
5520 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00005521 case CXCursor_OMPTargetEnterDataDirective:
5522 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00005523 case CXCursor_OMPTargetExitDataDirective:
5524 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00005525 case CXCursor_OMPTargetParallelDirective:
5526 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00005527 case CXCursor_OMPTargetParallelForDirective:
5528 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00005529 case CXCursor_OMPTargetUpdateDirective:
5530 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00005531 case CXCursor_OMPTeamsDirective:
5532 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00005533 case CXCursor_OMPCancellationPointDirective:
5534 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00005535 case CXCursor_OMPCancelDirective:
5536 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00005537 case CXCursor_OMPTaskLoopDirective:
5538 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005539 case CXCursor_OMPTaskLoopSimdDirective:
5540 return cxstring::createRef("OMPTaskLoopSimdDirective");
Alexey Bataev60e51c42019-10-10 20:13:02 +00005541 case CXCursor_OMPMasterTaskLoopDirective:
5542 return cxstring::createRef("OMPMasterTaskLoopDirective");
Alexey Bataevb8552ab2019-10-18 16:47:35 +00005543 case CXCursor_OMPMasterTaskLoopSimdDirective:
5544 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
Alexey Bataev5bbcead2019-10-14 17:17:41 +00005545 case CXCursor_OMPParallelMasterTaskLoopDirective:
5546 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
Alexey Bataev14a388f2019-10-25 10:27:13 -04005547 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5548 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00005549 case CXCursor_OMPDistributeDirective:
5550 return cxstring::createRef("OMPDistributeDirective");
Carlo Bertolli9925f152016-06-27 14:55:37 +00005551 case CXCursor_OMPDistributeParallelForDirective:
5552 return cxstring::createRef("OMPDistributeParallelForDirective");
Kelvin Li4a39add2016-07-05 05:00:15 +00005553 case CXCursor_OMPDistributeParallelForSimdDirective:
5554 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
Kelvin Li787f3fc2016-07-06 04:45:38 +00005555 case CXCursor_OMPDistributeSimdDirective:
5556 return cxstring::createRef("OMPDistributeSimdDirective");
Kelvin Lia579b912016-07-14 02:54:56 +00005557 case CXCursor_OMPTargetParallelForSimdDirective:
5558 return cxstring::createRef("OMPTargetParallelForSimdDirective");
Kelvin Li986330c2016-07-20 22:57:10 +00005559 case CXCursor_OMPTargetSimdDirective:
5560 return cxstring::createRef("OMPTargetSimdDirective");
Kelvin Li02532872016-08-05 14:37:37 +00005561 case CXCursor_OMPTeamsDistributeDirective:
5562 return cxstring::createRef("OMPTeamsDistributeDirective");
Kelvin Li4e325f72016-10-25 12:50:55 +00005563 case CXCursor_OMPTeamsDistributeSimdDirective:
5564 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
Kelvin Li579e41c2016-11-30 23:51:03 +00005565 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5566 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
Kelvin Li7ade93f2016-12-09 03:24:30 +00005567 case CXCursor_OMPTeamsDistributeParallelForDirective:
5568 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
Kelvin Libf594a52016-12-17 05:48:59 +00005569 case CXCursor_OMPTargetTeamsDirective:
5570 return cxstring::createRef("OMPTargetTeamsDirective");
Kelvin Li83c451e2016-12-25 04:52:54 +00005571 case CXCursor_OMPTargetTeamsDistributeDirective:
5572 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
Kelvin Li80e8f562016-12-29 22:16:30 +00005573 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5574 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
Kelvin Li1851df52017-01-03 05:23:48 +00005575 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5576 return cxstring::createRef(
5577 "OMPTargetTeamsDistributeParallelForSimdDirective");
Kelvin Lida681182017-01-10 18:08:18 +00005578 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5579 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00005580 case CXCursor_OverloadCandidate:
Michael Kruse7520cf02020-03-25 09:26:14 -05005581 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00005582 case CXCursor_TypeAliasTemplateDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005583 return cxstring::createRef("TypeAliasTemplateDecl");
Olivier Goffart81978012016-06-09 16:15:55 +00005584 case CXCursor_StaticAssert:
Michael Kruse7520cf02020-03-25 09:26:14 -05005585 return cxstring::createRef("StaticAssert");
Olivier Goffartd211c642016-11-04 06:29:27 +00005586 case CXCursor_FriendDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005587 return cxstring::createRef("FriendDecl");
Sven van Haastregtdc2c9302019-02-11 11:00:56 +00005588 case CXCursor_ConvergentAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005589 return cxstring::createRef("attribute(convergent)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005590 case CXCursor_WarnUnusedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005591 return cxstring::createRef("attribute(warn_unused)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005592 case CXCursor_WarnUnusedResultAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005593 return cxstring::createRef("attribute(warn_unused_result)");
Emilio Cobos Alvarezcd741272019-03-13 16:16:54 +00005594 case CXCursor_AlignedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005595 return cxstring::createRef("attribute(aligned)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 }
5597
5598 llvm_unreachable("Unhandled CXCursorKind");
5599}
5600
5601struct GetCursorData {
5602 SourceLocation TokenBeginLoc;
5603 bool PointsAtMacroArgExpansion;
5604 bool VisitedObjCPropertyImplDecl;
5605 SourceLocation VisitedDeclaratorDeclStartLoc;
5606 CXCursor &BestCursor;
5607
Michael Kruse7520cf02020-03-25 09:26:14 -05005608 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5609 CXCursor &outputCursor)
5610 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005611 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5612 VisitedObjCPropertyImplDecl = false;
5613 }
5614};
5615
Michael Kruse7520cf02020-03-25 09:26:14 -05005616static enum CXChildVisitResult
5617GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005618 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5619 CXCursor *BestCursor = &Data->BestCursor;
5620
5621 // If we point inside a macro argument we should provide info of what the
5622 // token is so use the actual cursor, don't replace it with a macro expansion
5623 // cursor.
5624 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5625 return CXChildVisit_Recurse;
Michael Kruse7520cf02020-03-25 09:26:14 -05005626
Guy Benyei11169dd2012-12-18 14:30:41 +00005627 if (clang_isDeclaration(cursor.kind)) {
5628 // Avoid having the implicit methods override the property decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05005629 if (const ObjCMethodDecl *MD =
5630 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005631 if (MD->isImplicit())
5632 return CXChildVisit_Break;
5633
Michael Kruse7520cf02020-03-25 09:26:14 -05005634 } else if (const ObjCInterfaceDecl *ID =
5635 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005636 // Check that when we have multiple @class references in the same line,
5637 // that later ones do not override the previous ones.
5638 // If we have:
5639 // @class Foo, Bar;
5640 // source ranges for both start at '@', so 'Bar' will end up overriding
5641 // 'Foo' even though the cursor location was at 'Foo'.
5642 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5643 BestCursor->kind == CXCursor_ObjCClassRef)
Michael Kruse7520cf02020-03-25 09:26:14 -05005644 if (const ObjCInterfaceDecl *PrevID =
5645 dyn_cast_or_null<ObjCInterfaceDecl>(
5646 getCursorDecl(*BestCursor))) {
5647 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5648 !ID->isThisDeclarationADefinition())
5649 return CXChildVisit_Break;
Guy Benyei11169dd2012-12-18 14:30:41 +00005650 }
5651
Michael Kruse7520cf02020-03-25 09:26:14 -05005652 } else if (const DeclaratorDecl *DD =
5653 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005654 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5655 // Check that when we have multiple declarators in the same line,
5656 // that later ones do not override the previous ones.
5657 // If we have:
5658 // int Foo, Bar;
5659 // source ranges for both start at 'int', so 'Bar' will end up overriding
5660 // 'Foo' even though the cursor location was at 'Foo'.
5661 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5662 return CXChildVisit_Break;
5663 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5664
Michael Kruse7520cf02020-03-25 09:26:14 -05005665 } else if (const ObjCPropertyImplDecl *PropImp =
5666 dyn_cast_or_null<ObjCPropertyImplDecl>(
5667 getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005668 (void)PropImp;
5669 // Check that when we have multiple @synthesize in the same line,
5670 // that later ones do not override the previous ones.
5671 // If we have:
5672 // @synthesize Foo, Bar;
5673 // source ranges for both start at '@', so 'Bar' will end up overriding
5674 // 'Foo' even though the cursor location was at 'Foo'.
5675 if (Data->VisitedObjCPropertyImplDecl)
5676 return CXChildVisit_Break;
5677 Data->VisitedObjCPropertyImplDecl = true;
5678 }
5679 }
5680
5681 if (clang_isExpression(cursor.kind) &&
5682 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005683 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005684 // Avoid having the cursor of an expression replace the declaration cursor
5685 // when the expression source range overlaps the declaration range.
5686 // This can happen for C++ constructor expressions whose range generally
5687 // include the variable declaration, e.g.:
Michael Kruse7520cf02020-03-25 09:26:14 -05005688 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5689 // cursor.
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5691 D->getLocation() == Data->TokenBeginLoc)
5692 return CXChildVisit_Break;
5693 }
5694 }
5695
Michael Kruse7520cf02020-03-25 09:26:14 -05005696 // If our current best cursor is the construction of a temporary object,
5697 // don't replace that cursor with a type reference, because we want
Guy Benyei11169dd2012-12-18 14:30:41 +00005698 // clang_getCursor() to point at the constructor.
5699 if (clang_isExpression(BestCursor->kind) &&
5700 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5701 cursor.kind == CXCursor_TypeRef) {
5702 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5703 // as having the actual point on the type reference.
5704 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5705 return CXChildVisit_Recurse;
5706 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005707
5708 // If we already have an Objective-C superclass reference, don't
5709 // update it further.
5710 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5711 return CXChildVisit_Break;
5712
Guy Benyei11169dd2012-12-18 14:30:41 +00005713 *BestCursor = cursor;
5714 return CXChildVisit_Recurse;
5715}
5716
5717CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005718 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005719 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005720 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005721 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005722
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005723 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5725
5726 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5727 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5728
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005729 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005730 CXFile SearchFile;
5731 unsigned SearchLine, SearchColumn;
5732 CXFile ResultFile;
5733 unsigned ResultLine, ResultColumn;
5734 CXString SearchFileName, ResultFileName, KindSpelling, USR;
Michael Kruse7520cf02020-03-25 09:26:14 -05005735 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005737
5738 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5739 nullptr);
Michael Kruse7520cf02020-03-25 09:26:14 -05005740 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5741 nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 SearchFileName = clang_getFileName(SearchFile);
5743 ResultFileName = clang_getFileName(ResultFile);
5744 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5745 USR = clang_getCursorUSR(Result);
Michael Kruse7520cf02020-03-25 09:26:14 -05005746 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5747 SearchLine, SearchColumn,
5748 clang_getCString(KindSpelling))
5749 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5750 ResultLine, ResultColumn, clang_getCString(USR),
5751 IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 clang_disposeString(SearchFileName);
5753 clang_disposeString(ResultFileName);
5754 clang_disposeString(KindSpelling);
5755 clang_disposeString(USR);
Michael Kruse7520cf02020-03-25 09:26:14 -05005756
Guy Benyei11169dd2012-12-18 14:30:41 +00005757 CXCursor Definition = clang_getCursorDefinition(Result);
5758 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5759 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
Michael Kruse7520cf02020-03-25 09:26:14 -05005760 CXString DefinitionKindSpelling =
5761 clang_getCursorKindSpelling(Definition.kind);
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 CXFile DefinitionFile;
5763 unsigned DefinitionLine, DefinitionColumn;
Michael Kruse7520cf02020-03-25 09:26:14 -05005764 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5765 &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005767 *Log << llvm::format(" -> %s(%s:%d:%d)",
Michael Kruse7520cf02020-03-25 09:26:14 -05005768 clang_getCString(DefinitionKindSpelling),
5769 clang_getCString(DefinitionFileName), DefinitionLine,
5770 DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005771 clang_disposeString(DefinitionFileName);
5772 clang_disposeString(DefinitionKindSpelling);
5773 }
5774 }
5775
5776 return Result;
5777}
5778
5779CXCursor clang_getNullCursor(void) {
5780 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5781}
5782
5783unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005784 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5785 // can't set consistently. For example, when visiting a DeclStmt we will set
5786 // it but we don't set it on the result of clang_getCursorDefinition for
5787 // a reference of the same declaration.
5788 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5789 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5790 // to provide that kind of info.
5791 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005792 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005793 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005794 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005795
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 return X == Y;
5797}
5798
5799unsigned clang_hashCursor(CXCursor C) {
5800 unsigned Index = 0;
5801 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5802 Index = 1;
Michael Kruse7520cf02020-03-25 09:26:14 -05005803
5804 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5805 std::make_pair(C.kind, C.data[Index]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005806}
5807
5808unsigned clang_isInvalid(enum CXCursorKind K) {
5809 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5810}
5811
5812unsigned clang_isDeclaration(enum CXCursorKind K) {
5813 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005814 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5815}
5816
Ivan Donchevskii08ff9102018-01-04 10:59:50 +00005817unsigned clang_isInvalidDeclaration(CXCursor C) {
5818 if (clang_isDeclaration(C.kind)) {
5819 if (const Decl *D = getCursorDecl(C))
5820 return D->isInvalidDecl();
5821 }
5822
5823 return 0;
5824}
5825
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005826unsigned clang_isReference(enum CXCursorKind K) {
5827 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5828}
Guy Benyei11169dd2012-12-18 14:30:41 +00005829
5830unsigned clang_isExpression(enum CXCursorKind K) {
5831 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5832}
5833
5834unsigned clang_isStatement(enum CXCursorKind K) {
5835 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5836}
5837
5838unsigned clang_isAttribute(enum CXCursorKind K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005839 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005840}
5841
5842unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5843 return K == CXCursor_TranslationUnit;
5844}
5845
5846unsigned clang_isPreprocessing(enum CXCursorKind K) {
5847 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5848}
Michael Kruse7520cf02020-03-25 09:26:14 -05005849
Guy Benyei11169dd2012-12-18 14:30:41 +00005850unsigned clang_isUnexposed(enum CXCursorKind K) {
5851 switch (K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005852 case CXCursor_UnexposedDecl:
5853 case CXCursor_UnexposedExpr:
5854 case CXCursor_UnexposedStmt:
5855 case CXCursor_UnexposedAttr:
5856 return true;
5857 default:
5858 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 }
5860}
5861
Michael Kruse7520cf02020-03-25 09:26:14 -05005862CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005863
5864CXSourceLocation clang_getCursorLocation(CXCursor C) {
5865 if (clang_isReference(C.kind)) {
5866 switch (C.kind) {
5867 case CXCursor_ObjCSuperClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005868 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5869 getCursorObjCSuperClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005870 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5871 }
5872
5873 case CXCursor_ObjCProtocolRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005874 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5875 getCursorObjCProtocolRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005876 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5877 }
5878
5879 case CXCursor_ObjCClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005880 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5881 getCursorObjCClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005882 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5883 }
5884
5885 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005886 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005887 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5888 }
5889
5890 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005891 std::pair<const TemplateDecl *, SourceLocation> P =
5892 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005893 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5894 }
5895
5896 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005897 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5899 }
5900
5901 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005902 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005903 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5904 }
5905
5906 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005907 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005908 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5909 }
5910
5911 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005912 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005913 if (!BaseSpec)
5914 return clang_getNullLocation();
Michael Kruse7520cf02020-03-25 09:26:14 -05005915
Guy Benyei11169dd2012-12-18 14:30:41 +00005916 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
Michael Kruse7520cf02020-03-25 09:26:14 -05005917 return cxloc::translateSourceLocation(
5918 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005919
Guy Benyei11169dd2012-12-18 14:30:41 +00005920 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005921 BaseSpec->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005922 }
5923
5924 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005925 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005926 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5927 }
5928
5929 case CXCursor_OverloadedDeclRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005930 return cxloc::translateSourceLocation(
5931 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
Guy Benyei11169dd2012-12-18 14:30:41 +00005932
5933 default:
5934 // FIXME: Need a way to enumerate all non-reference cases.
5935 llvm_unreachable("Missed a reference kind");
5936 }
5937 }
5938
5939 if (clang_isExpression(C.kind))
Michael Kruse7520cf02020-03-25 09:26:14 -05005940 return cxloc::translateSourceLocation(
5941 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
Guy Benyei11169dd2012-12-18 14:30:41 +00005942
5943 if (clang_isStatement(C.kind))
5944 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005945 getCursorStmt(C)->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005946
5947 if (C.kind == CXCursor_PreprocessingDirective) {
5948 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5949 return cxloc::translateSourceLocation(getCursorContext(C), L);
5950 }
5951
5952 if (C.kind == CXCursor_MacroExpansion) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005953 SourceLocation L =
5954 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005955 return cxloc::translateSourceLocation(getCursorContext(C), L);
5956 }
5957
5958 if (C.kind == CXCursor_MacroDefinition) {
5959 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5960 return cxloc::translateSourceLocation(getCursorContext(C), L);
5961 }
5962
5963 if (C.kind == CXCursor_InclusionDirective) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005964 SourceLocation L =
5965 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005966 return cxloc::translateSourceLocation(getCursorContext(C), L);
5967 }
5968
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005969 if (clang_isAttribute(C.kind)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005970 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005971 return cxloc::translateSourceLocation(getCursorContext(C), L);
5972 }
5973
Guy Benyei11169dd2012-12-18 14:30:41 +00005974 if (!clang_isDeclaration(C.kind))
5975 return clang_getNullLocation();
5976
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005977 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005978 if (!D)
5979 return clang_getNullLocation();
5980
5981 SourceLocation Loc = D->getLocation();
5982 // FIXME: Multiple variables declared in a single declaration
5983 // currently lack the information needed to correctly determine their
5984 // ranges when accounting for the type-specifier. We use context
5985 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5986 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005987 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005988 if (!cxcursor::isFirstInDeclGroup(C))
5989 Loc = VD->getLocation();
5990 }
5991
5992 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005993 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005994 Loc = MD->getSelectorStartLoc();
5995
5996 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5997}
5998
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00005999} // end extern "C"
6000
Guy Benyei11169dd2012-12-18 14:30:41 +00006001CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6002 assert(TU);
6003
6004 // Guard against an invalid SourceLocation, or we may assert in one
6005 // of the following calls.
6006 if (SLoc.isInvalid())
6007 return clang_getNullCursor();
6008
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006009 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006010
6011 // Translate the given source location to make it point at the beginning of
6012 // the token under the cursor.
6013 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6014 CXXUnit->getASTContext().getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05006015
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6017 if (SLoc.isValid()) {
6018 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6019 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Michael Kruse7520cf02020-03-25 09:26:14 -05006020 /*VisitPreprocessorLast=*/true,
Guy Benyei11169dd2012-12-18 14:30:41 +00006021 /*VisitIncludedEntities=*/false,
6022 SourceLocation(SLoc));
6023 CursorVis.visitFileRegion();
6024 }
6025
6026 return Result;
6027}
6028
6029static SourceRange getRawCursorExtent(CXCursor C) {
6030 if (clang_isReference(C.kind)) {
6031 switch (C.kind) {
6032 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05006033 return getCursorObjCSuperClassRef(C).second;
Guy Benyei11169dd2012-12-18 14:30:41 +00006034
6035 case CXCursor_ObjCProtocolRef:
6036 return getCursorObjCProtocolRef(C).second;
6037
6038 case CXCursor_ObjCClassRef:
6039 return getCursorObjCClassRef(C).second;
6040
6041 case CXCursor_TypeRef:
6042 return getCursorTypeRef(C).second;
6043
6044 case CXCursor_TemplateRef:
6045 return getCursorTemplateRef(C).second;
6046
6047 case CXCursor_NamespaceRef:
6048 return getCursorNamespaceRef(C).second;
6049
6050 case CXCursor_MemberRef:
6051 return getCursorMemberRef(C).second;
6052
6053 case CXCursor_CXXBaseSpecifier:
6054 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6055
6056 case CXCursor_LabelRef:
6057 return getCursorLabelRef(C).second;
6058
6059 case CXCursor_OverloadedDeclRef:
6060 return getCursorOverloadedDeclRef(C).second;
6061
6062 case CXCursor_VariableRef:
6063 return getCursorVariableRef(C).second;
Michael Kruse7520cf02020-03-25 09:26:14 -05006064
Guy Benyei11169dd2012-12-18 14:30:41 +00006065 default:
6066 // FIXME: Need a way to enumerate all non-reference cases.
6067 llvm_unreachable("Missed a reference kind");
6068 }
6069 }
6070
6071 if (clang_isExpression(C.kind))
6072 return getCursorExpr(C)->getSourceRange();
6073
6074 if (clang_isStatement(C.kind))
6075 return getCursorStmt(C)->getSourceRange();
6076
6077 if (clang_isAttribute(C.kind))
6078 return getCursorAttr(C)->getRange();
6079
6080 if (C.kind == CXCursor_PreprocessingDirective)
6081 return cxcursor::getCursorPreprocessingDirective(C);
6082
6083 if (C.kind == CXCursor_MacroExpansion) {
6084 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006085 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006086 return TU->mapRangeFromPreamble(Range);
6087 }
6088
6089 if (C.kind == CXCursor_MacroDefinition) {
6090 ASTUnit *TU = getCursorASTUnit(C);
6091 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6092 return TU->mapRangeFromPreamble(Range);
6093 }
6094
6095 if (C.kind == CXCursor_InclusionDirective) {
6096 ASTUnit *TU = getCursorASTUnit(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05006097 SourceRange Range =
6098 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006099 return TU->mapRangeFromPreamble(Range);
6100 }
6101
6102 if (C.kind == CXCursor_TranslationUnit) {
6103 ASTUnit *TU = getCursorASTUnit(C);
6104 FileID MainID = TU->getSourceManager().getMainFileID();
6105 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6106 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6107 return SourceRange(Start, End);
6108 }
6109
6110 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006111 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006112 if (!D)
6113 return SourceRange();
6114
6115 SourceRange R = D->getSourceRange();
6116 // FIXME: Multiple variables declared in a single declaration
6117 // currently lack the information needed to correctly determine their
6118 // ranges when accounting for the type-specifier. We use context
6119 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6120 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006121 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006122 if (!cxcursor::isFirstInDeclGroup(C))
6123 R.setBegin(VD->getLocation());
6124 }
6125 return R;
6126 }
6127 return SourceRange();
6128}
6129
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006130/// Retrieves the "raw" cursor extent, which is then extended to include
Guy Benyei11169dd2012-12-18 14:30:41 +00006131/// the decl-specifier-seq for declarations.
6132static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6133 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006134 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006135 if (!D)
6136 return SourceRange();
6137
6138 SourceRange R = D->getSourceRange();
6139
6140 // Adjust the start of the location for declarations preceded by
6141 // declaration specifiers.
6142 SourceLocation StartLoc;
6143 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6144 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006145 StartLoc = TI->getTypeLoc().getBeginLoc();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006146 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006148 StartLoc = TI->getTypeLoc().getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 }
6150
6151 if (StartLoc.isValid() && R.getBegin().isValid() &&
6152 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6153 R.setBegin(StartLoc);
6154
6155 // FIXME: Multiple variables declared in a single declaration
6156 // currently lack the information needed to correctly determine their
6157 // ranges when accounting for the type-specifier. We use context
6158 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6159 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006160 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006161 if (!cxcursor::isFirstInDeclGroup(C))
6162 R.setBegin(VD->getLocation());
6163 }
6164
Michael Kruse7520cf02020-03-25 09:26:14 -05006165 return R;
Guy Benyei11169dd2012-12-18 14:30:41 +00006166 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006167
Guy Benyei11169dd2012-12-18 14:30:41 +00006168 return getRawCursorExtent(C);
6169}
6170
Guy Benyei11169dd2012-12-18 14:30:41 +00006171CXSourceRange clang_getCursorExtent(CXCursor C) {
6172 SourceRange R = getRawCursorExtent(C);
6173 if (R.isInvalid())
6174 return clang_getNullRange();
6175
6176 return cxloc::translateSourceRange(getCursorContext(C), R);
6177}
6178
6179CXCursor clang_getCursorReferenced(CXCursor C) {
6180 if (clang_isInvalid(C.kind))
6181 return clang_getNullCursor();
6182
6183 CXTranslationUnit tu = getCursorTU(C);
6184 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006185 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006186 if (!D)
6187 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006188 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006189 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006190 if (const ObjCPropertyImplDecl *PropImpl =
6191 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006192 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6193 return MakeCXCursor(Property, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006194
Guy Benyei11169dd2012-12-18 14:30:41 +00006195 return C;
6196 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006197
Guy Benyei11169dd2012-12-18 14:30:41 +00006198 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006199 const Expr *E = getCursorExpr(C);
6200 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00006201 if (D) {
6202 CXCursor declCursor = MakeCXCursor(D, tu);
6203 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6204 declCursor);
6205 return declCursor;
6206 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006207
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006208 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00006209 return MakeCursorOverloadedDeclRef(Ovl, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006210
Guy Benyei11169dd2012-12-18 14:30:41 +00006211 return clang_getNullCursor();
6212 }
6213
6214 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006215 const Stmt *S = getCursorStmt(C);
6216 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00006217 if (LabelDecl *label = Goto->getLabel())
6218 if (LabelStmt *labelS = label->getStmt())
Michael Kruse7520cf02020-03-25 09:26:14 -05006219 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006220
6221 return clang_getNullCursor();
6222 }
Richard Smith66a81862015-05-04 02:25:31 +00006223
Guy Benyei11169dd2012-12-18 14:30:41 +00006224 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00006225 if (const MacroDefinitionRecord *Def =
6226 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006227 return MakeMacroDefinitionCursor(Def, tu);
6228 }
6229
6230 if (!clang_isReference(C.kind))
6231 return clang_getNullCursor();
6232
6233 switch (C.kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006234 case CXCursor_ObjCSuperClassRef:
6235 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006236
Michael Kruse7520cf02020-03-25 09:26:14 -05006237 case CXCursor_ObjCProtocolRef: {
6238 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6239 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6240 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006241
Michael Kruse7520cf02020-03-25 09:26:14 -05006242 return MakeCXCursor(Prot, tu);
6243 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006244
Michael Kruse7520cf02020-03-25 09:26:14 -05006245 case CXCursor_ObjCClassRef: {
6246 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6247 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6248 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006249
Michael Kruse7520cf02020-03-25 09:26:14 -05006250 return MakeCXCursor(Class, tu);
6251 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006252
Michael Kruse7520cf02020-03-25 09:26:14 -05006253 case CXCursor_TypeRef:
6254 return MakeCXCursor(getCursorTypeRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006255
Michael Kruse7520cf02020-03-25 09:26:14 -05006256 case CXCursor_TemplateRef:
6257 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006258
Michael Kruse7520cf02020-03-25 09:26:14 -05006259 case CXCursor_NamespaceRef:
6260 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006261
Michael Kruse7520cf02020-03-25 09:26:14 -05006262 case CXCursor_MemberRef:
6263 return MakeCXCursor(getCursorMemberRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006264
Michael Kruse7520cf02020-03-25 09:26:14 -05006265 case CXCursor_CXXBaseSpecifier: {
6266 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6267 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6268 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006269
Michael Kruse7520cf02020-03-25 09:26:14 -05006270 case CXCursor_LabelRef:
6271 // FIXME: We end up faking the "parent" declaration here because we
6272 // don't want to make CXCursor larger.
6273 return MakeCXCursor(
6274 getCursorLabelRef(C).first,
6275 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006276
Michael Kruse7520cf02020-03-25 09:26:14 -05006277 case CXCursor_OverloadedDeclRef:
6278 return C;
Guy Benyei11169dd2012-12-18 14:30:41 +00006279
Michael Kruse7520cf02020-03-25 09:26:14 -05006280 case CXCursor_VariableRef:
6281 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6282
6283 default:
6284 // We would prefer to enumerate all non-reference cursor kinds here.
6285 llvm_unreachable("Unhandled reference cursor kind");
Guy Benyei11169dd2012-12-18 14:30:41 +00006286 }
6287}
6288
6289CXCursor clang_getCursorDefinition(CXCursor C) {
6290 if (clang_isInvalid(C.kind))
6291 return clang_getNullCursor();
6292
6293 CXTranslationUnit TU = getCursorTU(C);
6294
6295 bool WasReference = false;
6296 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6297 C = clang_getCursorReferenced(C);
6298 WasReference = true;
6299 }
6300
6301 if (C.kind == CXCursor_MacroExpansion)
6302 return clang_getCursorReferenced(C);
6303
6304 if (!clang_isDeclaration(C.kind))
6305 return clang_getNullCursor();
6306
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006307 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006308 if (!D)
6309 return clang_getNullCursor();
6310
6311 switch (D->getKind()) {
6312 // Declaration kinds that don't really separate the notions of
6313 // declaration and definition.
6314 case Decl::Namespace:
6315 case Decl::Typedef:
6316 case Decl::TypeAlias:
6317 case Decl::TypeAliasTemplate:
6318 case Decl::TemplateTypeParm:
6319 case Decl::EnumConstant:
6320 case Decl::Field:
Richard Smithbdb84f32016-07-22 23:36:59 +00006321 case Decl::Binding:
John McCall5e77d762013-04-16 07:28:30 +00006322 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006323 case Decl::IndirectField:
6324 case Decl::ObjCIvar:
6325 case Decl::ObjCAtDefsField:
6326 case Decl::ImplicitParam:
6327 case Decl::ParmVar:
6328 case Decl::NonTypeTemplateParm:
6329 case Decl::TemplateTemplateParm:
6330 case Decl::ObjCCategoryImpl:
6331 case Decl::ObjCImplementation:
6332 case Decl::AccessSpec:
6333 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006334 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006335 case Decl::ObjCPropertyImpl:
6336 case Decl::FileScopeAsm:
6337 case Decl::StaticAssert:
6338 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006339 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006340 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006341 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006342 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006343 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006344 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006345 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006346 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006347 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006348 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006349 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006350 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006351 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006352 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006353 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006354 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006355 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006356 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006357 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006358 return C;
6359
6360 // Declaration kinds that don't make any sense here, but are
6361 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006362 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006363 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006364 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 break;
6366
6367 // Declaration kinds for which the definition is not resolvable.
6368 case Decl::UnresolvedUsingTypename:
6369 case Decl::UnresolvedUsingValue:
6370 break;
6371
6372 case Decl::UsingDirective:
6373 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6374 TU);
6375
6376 case Decl::NamespaceAlias:
6377 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6378
6379 case Decl::Enum:
6380 case Decl::Record:
6381 case Decl::CXXRecord:
6382 case Decl::ClassTemplateSpecialization:
6383 case Decl::ClassTemplatePartialSpecialization:
6384 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6385 return MakeCXCursor(Def, TU);
6386 return clang_getNullCursor();
6387
6388 case Decl::Function:
6389 case Decl::CXXMethod:
6390 case Decl::CXXConstructor:
6391 case Decl::CXXDestructor:
6392 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006393 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006394 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006395 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006396 return clang_getNullCursor();
6397 }
6398
Larisse Voufo39a1e502013-08-06 01:03:05 +00006399 case Decl::Var:
6400 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006401 case Decl::VarTemplatePartialSpecialization:
6402 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006403 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006404 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006405 return MakeCXCursor(Def, TU);
6406 return clang_getNullCursor();
6407 }
6408
6409 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006410 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006411 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6412 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6413 return clang_getNullCursor();
6414 }
6415
6416 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006417 if (RecordDecl *Def =
6418 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006419 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6420 TU);
6421 return clang_getNullCursor();
6422 }
6423
Larisse Voufo39a1e502013-08-06 01:03:05 +00006424 case Decl::VarTemplate: {
6425 if (VarDecl *Def =
6426 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6427 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6428 return clang_getNullCursor();
6429 }
6430
Guy Benyei11169dd2012-12-18 14:30:41 +00006431 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006432 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6433 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006434
6435 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006436 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006437 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006438 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006439
6440 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006441 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006442 if (Method->isThisDeclarationADefinition())
6443 return C;
6444
6445 // Dig out the method definition in the associated
6446 // @implementation, if we have it.
6447 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006448 if (const ObjCInterfaceDecl *Class =
6449 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006450 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006451 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6452 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 if (Def->isThisDeclarationADefinition())
6454 return MakeCXCursor(Def, TU);
6455
6456 return clang_getNullCursor();
6457 }
6458
6459 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006460 if (ObjCCategoryImplDecl *Impl =
6461 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 return MakeCXCursor(Impl, TU);
6463 return clang_getNullCursor();
6464
6465 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006466 if (const ObjCProtocolDecl *Def =
6467 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006468 return MakeCXCursor(Def, TU);
6469 return clang_getNullCursor();
6470
6471 case Decl::ObjCInterface: {
6472 // There are two notions of a "definition" for an Objective-C
6473 // class: the interface and its implementation. When we resolved a
6474 // reference to an Objective-C class, produce the @interface as
6475 // the definition; when we were provided with the interface,
6476 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006477 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006478 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006479 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006480 return MakeCXCursor(Def, TU);
6481 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6482 return MakeCXCursor(Impl, TU);
6483 return clang_getNullCursor();
6484 }
6485
6486 case Decl::ObjCProperty:
6487 // FIXME: We don't really know where to find the
6488 // ObjCPropertyImplDecls that implement this property.
6489 return clang_getNullCursor();
6490
6491 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006492 if (const ObjCInterfaceDecl *Class =
6493 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006494 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006495 return MakeCXCursor(Def, TU);
6496
6497 return clang_getNullCursor();
6498
6499 case Decl::Friend:
6500 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6501 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6502 return clang_getNullCursor();
6503
6504 case Decl::FriendTemplate:
6505 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6506 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6507 return clang_getNullCursor();
6508 }
6509
6510 return clang_getNullCursor();
6511}
6512
6513unsigned clang_isCursorDefinition(CXCursor C) {
6514 if (!clang_isDeclaration(C.kind))
6515 return 0;
6516
6517 return clang_getCursorDefinition(C) == C;
6518}
6519
6520CXCursor clang_getCanonicalCursor(CXCursor C) {
6521 if (!clang_isDeclaration(C.kind))
6522 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006523
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006524 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006525 if (const ObjCCategoryImplDecl *CatImplD =
6526 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006527 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6528 return MakeCXCursor(CatD, getCursorTU(C));
6529
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006530 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6531 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006532 return MakeCXCursor(IFD, getCursorTU(C));
6533
6534 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6535 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006536
Guy Benyei11169dd2012-12-18 14:30:41 +00006537 return C;
6538}
6539
6540int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6541 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6542}
Michael Kruse7520cf02020-03-25 09:26:14 -05006543
Guy Benyei11169dd2012-12-18 14:30:41 +00006544unsigned clang_getNumOverloadedDecls(CXCursor C) {
6545 if (C.kind != CXCursor_OverloadedDeclRef)
6546 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006547
Guy Benyei11169dd2012-12-18 14:30:41 +00006548 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006549 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006550 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006551
6552 if (OverloadedTemplateStorage *S =
6553 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006554 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006555
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006556 const Decl *D = Storage.get<const Decl *>();
6557 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006558 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006559
Guy Benyei11169dd2012-12-18 14:30:41 +00006560 return 0;
6561}
6562
6563CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6564 if (cursor.kind != CXCursor_OverloadedDeclRef)
6565 return clang_getNullCursor();
6566
6567 if (index >= clang_getNumOverloadedDecls(cursor))
6568 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006569
Guy Benyei11169dd2012-12-18 14:30:41 +00006570 CXTranslationUnit TU = getCursorTU(cursor);
6571 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006572 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006573 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006574
6575 if (OverloadedTemplateStorage *S =
6576 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006577 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006578
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006579 const Decl *D = Storage.get<const Decl *>();
6580 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006581 // FIXME: This is, unfortunately, linear time.
6582 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6583 std::advance(Pos, index);
6584 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6585 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006586
Guy Benyei11169dd2012-12-18 14:30:41 +00006587 return clang_getNullCursor();
6588}
Michael Kruse7520cf02020-03-25 09:26:14 -05006589
6590void clang_getDefinitionSpellingAndExtent(
6591 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6592 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006593 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006594 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006595 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6596
6597 SourceManager &SM = FD->getASTContext().getSourceManager();
6598 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6599 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6600 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6601 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6602 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6603 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6604}
6605
Guy Benyei11169dd2012-12-18 14:30:41 +00006606CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6607 unsigned PieceIndex) {
6608 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006609
Guy Benyei11169dd2012-12-18 14:30:41 +00006610 switch (C.kind) {
6611 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006612 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006613 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6614 E->getQualifierLoc().getSourceRange());
6615 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006616
Guy Benyei11169dd2012-12-18 14:30:41 +00006617 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006618 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6619 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6620 Pieces =
6621 buildPieces(NameFlags, false, E->getNameInfo(),
6622 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6623 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006624 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006625
Guy Benyei11169dd2012-12-18 14:30:41 +00006626 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006627 if (const CXXOperatorCallExpr *OCE =
6628 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006629 const Expr *Callee = OCE->getCallee();
6630 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006631 Callee = ICE->getSubExpr();
6632
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006633 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006634 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6635 DRE->getQualifierLoc().getSourceRange());
6636 }
6637 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006638
Guy Benyei11169dd2012-12-18 14:30:41 +00006639 default:
6640 break;
6641 }
6642
6643 if (Pieces.empty()) {
6644 if (PieceIndex == 0)
6645 return clang_getCursorExtent(C);
6646 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006647 SourceRange R = Pieces[PieceIndex];
6648 if (R.isValid())
6649 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006650 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006651
Guy Benyei11169dd2012-12-18 14:30:41 +00006652 return clang_getNullRange();
6653}
6654
6655void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006656 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6657 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006658}
6659
Michael Kruse7520cf02020-03-25 09:26:14 -05006660void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006661 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006662 llvm::llvm_execute_on_thread(fn, user_data,
6663 stack_size == 0
6664 ? clang::DesiredStackSize
6665 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006666}
6667
Guy Benyei11169dd2012-12-18 14:30:41 +00006668//===----------------------------------------------------------------------===//
6669// Token-based Operations.
6670//===----------------------------------------------------------------------===//
6671
6672/* CXToken layout:
6673 * int_data[0]: a CXTokenKind
6674 * int_data[1]: starting token location
6675 * int_data[2]: token length
6676 * int_data[3]: reserved
6677 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6678 * otherwise unused.
6679 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006680CXTokenKind clang_getTokenKind(CXToken CXTok) {
6681 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6682}
6683
6684CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6685 switch (clang_getTokenKind(CXTok)) {
6686 case CXToken_Identifier:
6687 case CXToken_Keyword:
6688 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006689 return cxstring::createRef(
6690 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006691
6692 case CXToken_Literal: {
6693 // We have stashed the starting pointer in the ptr_data field. Use it.
6694 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006695 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006696 }
6697
6698 case CXToken_Punctuation:
6699 case CXToken_Comment:
6700 break;
6701 }
6702
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006703 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006704 LOG_BAD_TU(TU);
6705 return cxstring::createEmpty();
6706 }
6707
Guy Benyei11169dd2012-12-18 14:30:41 +00006708 // We have to find the starting buffer pointer the hard way, by
6709 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006710 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006711 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006712 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006713
6714 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006715 std::pair<FileID, unsigned> LocInfo =
6716 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006717 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006718 StringRef Buffer =
6719 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006720 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006721 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006722
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006723 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006724}
6725
6726CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006727 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006728 LOG_BAD_TU(TU);
6729 return clang_getNullLocation();
6730 }
6731
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006732 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006733 if (!CXXUnit)
6734 return clang_getNullLocation();
6735
Michael Kruse7520cf02020-03-25 09:26:14 -05006736 return cxloc::translateSourceLocation(
6737 CXXUnit->getASTContext(),
6738 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006739}
6740
6741CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006742 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006743 LOG_BAD_TU(TU);
6744 return clang_getNullRange();
6745 }
6746
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006747 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006748 if (!CXXUnit)
6749 return clang_getNullRange();
6750
Michael Kruse7520cf02020-03-25 09:26:14 -05006751 return cxloc::translateSourceRange(
6752 CXXUnit->getASTContext(),
6753 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006754}
6755
6756static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6757 SmallVectorImpl<CXToken> &CXTokens) {
6758 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006759 std::pair<FileID, unsigned> BeginLocInfo =
6760 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6761 std::pair<FileID, unsigned> EndLocInfo =
6762 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006763
6764 // Cannot tokenize across files.
6765 if (BeginLocInfo.first != EndLocInfo.first)
6766 return;
6767
6768 // Create a lexer
6769 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006770 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006771 if (Invalid)
6772 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006773
Guy Benyei11169dd2012-12-18 14:30:41 +00006774 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006775 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6776 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006777 Lex.SetCommentRetentionState(true);
6778
6779 // Lex tokens until we hit the end of the range.
6780 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6781 Token Tok;
6782 bool previousWasAt = false;
6783 do {
6784 // Lex the next token
6785 Lex.LexFromRawLexer(Tok);
6786 if (Tok.is(tok::eof))
6787 break;
6788
6789 // Initialize the CXToken.
6790 CXToken CXTok;
6791
6792 // - Common fields
6793 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6794 CXTok.int_data[2] = Tok.getLength();
6795 CXTok.int_data[3] = 0;
6796
6797 // - Kind-specific fields
6798 if (Tok.isLiteral()) {
6799 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006800 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006801 } else if (Tok.is(tok::raw_identifier)) {
6802 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006803 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006804
6805 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6806 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006807 } else {
6808 CXTok.int_data[0] =
6809 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006810 }
6811 CXTok.ptr_data = II;
6812 } else if (Tok.is(tok::comment)) {
6813 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006814 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006815 } else {
6816 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006817 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006818 }
6819 CXTokens.push_back(CXTok);
6820 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006821 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006822}
6823
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006824CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006825 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006826
6827 if (isNotUsableTU(TU)) {
6828 LOG_BAD_TU(TU);
6829 return NULL;
6830 }
6831
6832 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6833 if (!CXXUnit)
6834 return NULL;
6835
6836 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6837 if (Begin.isInvalid())
6838 return NULL;
6839 SourceManager &SM = CXXUnit->getSourceManager();
6840 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006841 DecomposedEnd.second +=
6842 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006843
Michael Kruse7520cf02020-03-25 09:26:14 -05006844 SourceLocation End =
6845 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006846
6847 SmallVector<CXToken, 32> CXTokens;
6848 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6849
6850 if (CXTokens.empty())
6851 return NULL;
6852
6853 CXTokens.resize(1);
6854 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6855
6856 memmove(Token, CXTokens.data(), sizeof(CXToken));
6857 return Token;
6858}
6859
Michael Kruse7520cf02020-03-25 09:26:14 -05006860void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6861 unsigned *NumTokens) {
6862 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006863
Guy Benyei11169dd2012-12-18 14:30:41 +00006864 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006865 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006866 if (NumTokens)
6867 *NumTokens = 0;
6868
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006869 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006870 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006871 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006872 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006873
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006874 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006875 if (!CXXUnit || !Tokens || !NumTokens)
6876 return;
6877
6878 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006879
Guy Benyei11169dd2012-12-18 14:30:41 +00006880 SourceRange R = cxloc::translateCXSourceRange(Range);
6881 if (R.isInvalid())
6882 return;
6883
6884 SmallVector<CXToken, 32> CXTokens;
6885 getTokens(CXXUnit, R, CXTokens);
6886
6887 if (CXTokens.empty())
6888 return;
6889
Serge Pavlov52525732018-02-21 02:02:39 +00006890 *Tokens = static_cast<CXToken *>(
6891 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006892 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6893 *NumTokens = CXTokens.size();
6894}
6895
Michael Kruse7520cf02020-03-25 09:26:14 -05006896void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6897 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006898 free(Tokens);
6899}
6900
Guy Benyei11169dd2012-12-18 14:30:41 +00006901//===----------------------------------------------------------------------===//
6902// Token annotation APIs.
6903//===----------------------------------------------------------------------===//
6904
Guy Benyei11169dd2012-12-18 14:30:41 +00006905static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6906 CXCursor parent,
6907 CXClientData client_data);
6908static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6909 CXClientData client_data);
6910
6911namespace {
6912class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006913 CXToken *Tokens;
6914 CXCursor *Cursors;
6915 unsigned NumTokens;
6916 unsigned TokIdx;
6917 unsigned PreprocessingTokIdx;
6918 CursorVisitor AnnotateVis;
6919 SourceManager &SrcMgr;
6920 bool HasContextSensitiveKeywords;
6921
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006922 struct PostChildrenAction {
6923 CXCursor cursor;
6924 enum Action { Invalid, Ignore, Postpone } action;
6925 };
6926 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6927
Guy Benyei11169dd2012-12-18 14:30:41 +00006928 struct PostChildrenInfo {
6929 CXCursor Cursor;
6930 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006931 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006932 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006933 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006934 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006935 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006936
6937 CXToken &getTok(unsigned Idx) {
6938 assert(Idx < NumTokens);
6939 return Tokens[Idx];
6940 }
6941 const CXToken &getTok(unsigned Idx) const {
6942 assert(Idx < NumTokens);
6943 return Tokens[Idx];
6944 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006945 bool MoreTokens() const { return TokIdx < NumTokens; }
6946 unsigned NextToken() const { return TokIdx; }
6947 void AdvanceToken() { ++TokIdx; }
6948 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006949 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006950 }
6951 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006952 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006953 }
6954 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006955 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006956 }
6957
6958 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006959 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006960 SourceRange);
6961
6962public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006963 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006964 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05006965 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
6966 PreprocessingTokIdx(0),
6967 AnnotateVis(TU, AnnotateTokensVisitor, this,
6968 /*VisitPreprocessorLast=*/true,
6969 /*VisitIncludedEntities=*/false, RegionOfInterest,
6970 /*VisitDeclsOnly=*/false,
6971 AnnotateTokensPostChildrenVisitor),
6972 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
6973 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00006974
6975 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6976 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006977 bool IsIgnoredChildCursor(CXCursor cursor) const;
6978 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
6979
Guy Benyei11169dd2012-12-18 14:30:41 +00006980 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006981 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
6982 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
6983
Guy Benyei11169dd2012-12-18 14:30:41 +00006984 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05006985
6986 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00006987 /// context-sensitive keywords.
6988 bool hasContextSensitiveKeywords() const {
6989 return HasContextSensitiveKeywords;
6990 }
6991
Michael Kruse7520cf02020-03-25 09:26:14 -05006992 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00006993};
Michael Kruse7520cf02020-03-25 09:26:14 -05006994} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00006995
6996void AnnotateTokensWorker::AnnotateTokens() {
6997 // Walk the AST within the region of interest, annotating tokens
6998 // along the way.
6999 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007000}
Guy Benyei11169dd2012-12-18 14:30:41 +00007001
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007002bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7003 if (PostChildrenInfos.empty())
7004 return false;
7005
7006 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7007 if (ChildAction.cursor == cursor &&
7008 ChildAction.action == PostChildrenAction::Ignore) {
7009 return true;
7010 }
7011 }
7012
7013 return false;
7014}
7015
7016const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7017 if (!clang_isExpression(Cursor.kind))
7018 return nullptr;
7019
7020 const Expr *E = getCursorExpr(Cursor);
7021 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7022 const OverloadedOperatorKind Kind = OCE->getOperator();
7023 if (Kind == OO_Call || Kind == OO_Subscript)
7024 return OCE;
7025 }
7026
7027 return nullptr;
7028}
7029
7030AnnotateTokensWorker::PostChildrenActions
7031AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7032 PostChildrenActions actions;
7033
7034 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7035 // visited before the arguments to the operator call. For the Call and
7036 // Subscript operator the range of this DeclRefExpr includes the whole call
7037 // expression, so that all tokens in that range would be mapped to the
7038 // operator function, including the tokens of the arguments. To avoid that,
7039 // ensure to visit this DeclRefExpr as last node.
7040 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7041 const Expr *Callee = OCE->getCallee();
7042 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7043 const Expr *SubExpr = ICE->getSubExpr();
7044 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007045 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007046 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7047
7048 // Visit the DeclRefExpr as last.
7049 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7050 actions.push_back({cxChild, PostChildrenAction::Postpone});
7051
7052 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7053 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7054 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7055 actions.push_back({cxChild, PostChildrenAction::Ignore});
7056 }
7057 }
7058 }
7059
7060 return actions;
7061}
7062
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007063static inline void updateCursorAnnotation(CXCursor &Cursor,
7064 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007065 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007066 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007067 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007068}
7069
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007070/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007071//// between the cursor location and the source range is the same as
7072/// \arg compResult.
7073///
7074/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7075/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007076void AnnotateTokensWorker::annotateAndAdvanceTokens(
7077 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007078 while (MoreTokens()) {
7079 const unsigned I = NextToken();
7080 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007081 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7082 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007083
7084 SourceLocation TokLoc = GetTokenLoc(I);
7085 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007086 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007087 AdvanceToken();
7088 continue;
7089 }
7090 break;
7091 }
7092}
7093
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007094/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007095/// \returns true if it advanced beyond all macro tokens, false otherwise.
7096bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007097 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007098 assert(MoreTokens());
7099 assert(isFunctionMacroToken(NextToken()) &&
7100 "Should be called only for macro arg tokens");
7101
7102 // This works differently than annotateAndAdvanceTokens; because expanded
7103 // macro arguments can have arbitrary translation-unit source order, we do not
7104 // advance the token index one by one until a token fails the range test.
7105 // We only advance once past all of the macro arg tokens if all of them
7106 // pass the range test. If one of them fails we keep the token index pointing
7107 // at the start of the macro arg tokens so that the failing token will be
7108 // annotated by a subsequent annotation try.
7109
7110 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007111
Guy Benyei11169dd2012-12-18 14:30:41 +00007112 unsigned I = NextToken();
7113 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7114 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7115 if (TokLoc.isFileID())
7116 continue; // not macro arg token, it's parens or comma.
7117 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7118 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7119 Cursors[I] = updateC;
7120 } else
7121 atLeastOneCompFail = true;
7122 }
7123
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007124 if (atLeastOneCompFail)
7125 return false;
7126
7127 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7128 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007129}
7130
Michael Kruse7520cf02020-03-25 09:26:14 -05007131enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7132 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007133 SourceRange cursorRange = getRawCursorExtent(cursor);
7134 if (cursorRange.isInvalid())
7135 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007136
7137 if (IsIgnoredChildCursor(cursor))
7138 return CXChildVisit_Continue;
7139
Guy Benyei11169dd2012-12-18 14:30:41 +00007140 if (!HasContextSensitiveKeywords) {
7141 // Objective-C properties can have context-sensitive keywords.
7142 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007143 if (const ObjCPropertyDecl *Property =
7144 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7145 HasContextSensitiveKeywords =
7146 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007147 }
7148 // Objective-C methods can have context-sensitive keywords.
7149 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7150 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007151 if (const ObjCMethodDecl *Method =
7152 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007153 if (Method->getObjCDeclQualifier())
7154 HasContextSensitiveKeywords = true;
7155 else {
David Majnemer59f77922016-06-24 04:05:48 +00007156 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007157 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007158 HasContextSensitiveKeywords = true;
7159 break;
7160 }
7161 }
7162 }
7163 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007164 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007165 // C++ methods can have context-sensitive keywords.
7166 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007167 if (const CXXMethodDecl *Method =
7168 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007169 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7170 HasContextSensitiveKeywords = true;
7171 }
7172 }
7173 // C++ classes can have context-sensitive keywords.
7174 else if (cursor.kind == CXCursor_StructDecl ||
7175 cursor.kind == CXCursor_ClassDecl ||
7176 cursor.kind == CXCursor_ClassTemplate ||
7177 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007178 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007179 if (D->hasAttr<FinalAttr>())
7180 HasContextSensitiveKeywords = true;
7181 }
7182 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007183
7184 // Don't override a property annotation with its getter/setter method.
7185 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7186 parent.kind == CXCursor_ObjCPropertyDecl)
7187 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007188
7189 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007190 // Items in the preprocessing record are kept separate from items in
7191 // declarations, so we keep a separate token index.
7192 unsigned SavedTokIdx = TokIdx;
7193 TokIdx = PreprocessingTokIdx;
7194
7195 // Skip tokens up until we catch up to the beginning of the preprocessing
7196 // entry.
7197 while (MoreTokens()) {
7198 const unsigned I = NextToken();
7199 SourceLocation TokLoc = GetTokenLoc(I);
7200 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7201 case RangeBefore:
7202 AdvanceToken();
7203 continue;
7204 case RangeAfter:
7205 case RangeOverlap:
7206 break;
7207 }
7208 break;
7209 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007210
Guy Benyei11169dd2012-12-18 14:30:41 +00007211 // Look at all of the tokens within this range.
7212 while (MoreTokens()) {
7213 const unsigned I = NextToken();
7214 SourceLocation TokLoc = GetTokenLoc(I);
7215 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7216 case RangeBefore:
7217 llvm_unreachable("Infeasible");
7218 case RangeAfter:
7219 break;
7220 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007221 // For macro expansions, just note where the beginning of the macro
7222 // expansion occurs.
7223 if (cursor.kind == CXCursor_MacroExpansion) {
7224 if (TokLoc == cursorRange.getBegin())
7225 Cursors[I] = cursor;
7226 AdvanceToken();
7227 break;
7228 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007229 // We may have already annotated macro names inside macro definitions.
7230 if (Cursors[I].kind != CXCursor_MacroExpansion)
7231 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007232 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007233 continue;
7234 }
7235 break;
7236 }
7237
7238 // Save the preprocessing token index; restore the non-preprocessing
7239 // token index.
7240 PreprocessingTokIdx = TokIdx;
7241 TokIdx = SavedTokIdx;
7242 return CXChildVisit_Recurse;
7243 }
7244
7245 if (cursorRange.isInvalid())
7246 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007247
7248 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007249 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007250 const enum CXCursorKind K = clang_getCursorKind(parent);
7251 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007252 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7253 // Attributes are annotated out-of-order, skip tokens until we reach it.
7254 clang_isAttribute(cursor.kind))
7255 ? clang_getNullCursor()
7256 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007257
7258 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7259
7260 // Avoid having the cursor of an expression "overwrite" the annotation of the
7261 // variable declaration that it belongs to.
7262 // This can happen for C++ constructor expressions whose range generally
7263 // include the variable declaration, e.g.:
7264 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007265 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007266 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007267 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007268 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007269 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7270 E->getBeginLoc() == D->getLocation() &&
7271 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007272 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007273 AdvanceToken();
7274 }
7275 }
7276 }
7277
7278 // Before recursing into the children keep some state that we are going
7279 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7280 // extra work after the child nodes are visited.
7281 // Note that we don't call VisitChildren here to avoid traversing statements
7282 // code-recursively which can blow the stack.
7283
7284 PostChildrenInfo Info;
7285 Info.Cursor = cursor;
7286 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007287 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007288 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007289 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007290 PostChildrenInfos.push_back(Info);
7291
7292 return CXChildVisit_Recurse;
7293}
7294
7295bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7296 if (PostChildrenInfos.empty())
7297 return false;
7298 const PostChildrenInfo &Info = PostChildrenInfos.back();
7299 if (!clang_equalCursors(Info.Cursor, cursor))
7300 return false;
7301
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007302 HandlePostPonedChildCursors(Info);
7303
Guy Benyei11169dd2012-12-18 14:30:41 +00007304 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7305 const unsigned AfterChildren = NextToken();
7306 SourceRange cursorRange = Info.CursorRange;
7307
7308 // Scan the tokens that are at the end of the cursor, but are not captured
7309 // but the child cursors.
7310 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7311
7312 // Scan the tokens that are at the beginning of the cursor, but are not
7313 // capture by the child cursors.
7314 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7315 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7316 break;
7317
7318 Cursors[I] = cursor;
7319 }
7320
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007321 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7322 // encountered the attribute cursor.
7323 if (clang_isAttribute(cursor.kind))
7324 TokIdx = Info.BeforeReachingCursorIdx;
7325
Guy Benyei11169dd2012-12-18 14:30:41 +00007326 PostChildrenInfos.pop_back();
7327 return false;
7328}
7329
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007330void AnnotateTokensWorker::HandlePostPonedChildCursors(
7331 const PostChildrenInfo &Info) {
7332 for (const auto &ChildAction : Info.ChildActions) {
7333 if (ChildAction.action == PostChildrenAction::Postpone) {
7334 HandlePostPonedChildCursor(ChildAction.cursor,
7335 Info.BeforeChildrenTokenIdx);
7336 }
7337 }
7338}
7339
7340void AnnotateTokensWorker::HandlePostPonedChildCursor(
7341 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007342 unsigned I = StartTokenIndex;
7343
7344 // The bracket tokens of a Call or Subscript operator are mapped to
7345 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7346 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7347 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007348 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7349 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007350 if (clang_Range_isNull(CXRefNameRange))
7351 break; // All ranges handled.
7352
7353 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7354 while (I < NumTokens) {
7355 const SourceLocation TokenLocation = GetTokenLoc(I);
7356 if (!TokenLocation.isValid())
7357 break;
7358
7359 // Adapt the end range, because LocationCompare() reports
7360 // RangeOverlap even for the not-inclusive end location.
7361 const SourceLocation fixedEnd =
7362 RefNameRange.getEnd().getLocWithOffset(-1);
7363 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7364
7365 const RangeComparisonResult ComparisonResult =
7366 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7367
7368 if (ComparisonResult == RangeOverlap) {
7369 Cursors[I++] = Cursor;
7370 } else if (ComparisonResult == RangeBefore) {
7371 ++I; // Not relevant token, check next one.
7372 } else if (ComparisonResult == RangeAfter) {
7373 break; // All tokens updated for current range, check next.
7374 }
7375 }
7376 }
7377}
7378
Guy Benyei11169dd2012-12-18 14:30:41 +00007379static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7380 CXCursor parent,
7381 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007382 return static_cast<AnnotateTokensWorker *>(client_data)
7383 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007384}
7385
7386static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7387 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007388 return static_cast<AnnotateTokensWorker *>(client_data)
7389 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007390}
7391
7392namespace {
7393
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007394/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007395/// and mark tokens that are macro arguments. This info is used by the
7396/// AnnotateTokensWorker.
7397class MarkMacroArgTokensVisitor {
7398 SourceManager &SM;
7399 CXToken *Tokens;
7400 unsigned NumTokens;
7401 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007402
Guy Benyei11169dd2012-12-18 14:30:41 +00007403public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007404 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7405 unsigned numTokens)
7406 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007407
7408 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7409 if (cursor.kind != CXCursor_MacroExpansion)
7410 return CXChildVisit_Continue;
7411
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007412 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007413 if (macroRange.getBegin() == macroRange.getEnd())
7414 return CXChildVisit_Continue; // it's not a function macro.
7415
7416 for (; CurIdx < NumTokens; ++CurIdx) {
7417 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7418 macroRange.getBegin()))
7419 break;
7420 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007421
Guy Benyei11169dd2012-12-18 14:30:41 +00007422 if (CurIdx == NumTokens)
7423 return CXChildVisit_Break;
7424
7425 for (; CurIdx < NumTokens; ++CurIdx) {
7426 SourceLocation tokLoc = getTokenLoc(CurIdx);
7427 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7428 break;
7429
7430 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7431 }
7432
7433 if (CurIdx == NumTokens)
7434 return CXChildVisit_Break;
7435
7436 return CXChildVisit_Continue;
7437 }
7438
7439private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007440 CXToken &getTok(unsigned Idx) {
7441 assert(Idx < NumTokens);
7442 return Tokens[Idx];
7443 }
7444 const CXToken &getTok(unsigned Idx) const {
7445 assert(Idx < NumTokens);
7446 return Tokens[Idx];
7447 }
7448
Guy Benyei11169dd2012-12-18 14:30:41 +00007449 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007450 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007451 }
7452
7453 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7454 // The third field is reserved and currently not used. Use it here
7455 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007456 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007457 }
7458};
7459
7460} // end anonymous namespace
7461
7462static CXChildVisitResult
7463MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7464 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007465 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7466 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007467}
7468
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007469/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007470/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007471static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7472 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007473 if (NextIdx >= NumTokens)
7474 return true;
7475
7476 ++NextIdx;
7477 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007478 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007479}
7480
Guy Benyei11169dd2012-12-18 14:30:41 +00007481static void annotatePreprocessorTokens(CXTranslationUnit TU,
7482 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007483 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007484 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007485 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007486
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007487 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007488 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007489 std::pair<FileID, unsigned> BeginLocInfo =
7490 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7491 std::pair<FileID, unsigned> EndLocInfo =
7492 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007493
7494 if (BeginLocInfo.first != EndLocInfo.first)
7495 return;
7496
7497 StringRef Buffer;
7498 bool Invalid = false;
7499 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7500 if (Buffer.empty() || Invalid)
7501 return;
7502
7503 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007504 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7505 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007506 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007507
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007508 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007509 // Lex tokens in raw mode until we hit the end of the range, to avoid
7510 // entering #includes or expanding macros.
7511 while (true) {
7512 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007513 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7514 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007515 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007516 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007517 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7518
Guy Benyei11169dd2012-12-18 14:30:41 +00007519 reprocess:
7520 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007521 // We have found a preprocessing directive. Annotate the tokens
7522 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007523 //
7524 // FIXME: Some simple tests here could identify macro definitions and
7525 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007526
7527 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007528 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7529 break;
7530
Craig Topper69186e72014-06-08 08:38:04 +00007531 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007532 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007533 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7534 break;
7535
7536 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007537 IdentifierInfo &II =
7538 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007539 SourceLocation MappedTokLoc =
7540 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7541 MI = getMacroInfo(II, MappedTokLoc, TU);
7542 }
7543 }
7544
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007545 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007546 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007547 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7548 finished = true;
7549 break;
7550 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007551 // If we are in a macro definition, check if the token was ever a
7552 // macro name and annotate it if that's the case.
7553 if (MI) {
7554 SourceLocation SaveLoc = Tok.getLocation();
7555 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007556 MacroDefinitionRecord *MacroDef =
7557 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007558 Tok.setLocation(SaveLoc);
7559 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007560 Cursors[NextIdx - 1] =
7561 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007562 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007563 } while (!Tok.isAtStartOfLine());
7564
Michael Kruse7520cf02020-03-25 09:26:14 -05007565 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007566 assert(TokIdx <= LastIdx);
7567 SourceLocation EndLoc =
7568 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7569 CXCursor Cursor =
7570 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7571
7572 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007573 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007574
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007575 if (finished)
7576 break;
7577 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007578 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007579 }
7580}
7581
7582// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007583static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7584 CXToken *Tokens, unsigned NumTokens,
7585 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007586 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007587 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7588 setThreadBackgroundPriority();
7589
7590 // Determine the region of interest, which contains all of the tokens.
7591 SourceRange RegionOfInterest;
7592 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007593 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7594 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7595 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007596
Guy Benyei11169dd2012-12-18 14:30:41 +00007597 // Relex the tokens within the source range to look for preprocessing
7598 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007599 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007600
7601 // If begin location points inside a macro argument, set it to the expansion
7602 // location so we can have the full context when annotating semantically.
7603 {
7604 SourceManager &SM = CXXUnit->getSourceManager();
7605 SourceLocation Loc =
7606 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7607 if (Loc.isMacroID())
7608 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7609 }
7610
Guy Benyei11169dd2012-12-18 14:30:41 +00007611 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7612 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007613 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7614 NumTokens);
7615 CursorVisitor MacroArgMarker(
7616 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7617 /*VisitPreprocessorLast=*/true,
7618 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007619 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7620 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007621
Guy Benyei11169dd2012-12-18 14:30:41 +00007622 // Annotate all of the source locations in the region of interest that map to
7623 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007624 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007625
Guy Benyei11169dd2012-12-18 14:30:41 +00007626 // FIXME: We use a ridiculous stack size here because the data-recursion
7627 // algorithm uses a large stack frame than the non-data recursive version,
7628 // and AnnotationTokensWorker currently transforms the data-recursion
7629 // algorithm back into a traditional recursion by explicitly calling
7630 // VisitChildren(). We will need to remove this explicit recursive call.
7631 W.AnnotateTokens();
7632
7633 // If we ran into any entities that involve context-sensitive keywords,
7634 // take another pass through the tokens to mark them as such.
7635 if (W.hasContextSensitiveKeywords()) {
7636 for (unsigned I = 0; I != NumTokens; ++I) {
7637 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7638 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007639
Guy Benyei11169dd2012-12-18 14:30:41 +00007640 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7641 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007642 if (const ObjCPropertyDecl *Property =
7643 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007644 if (Property->getPropertyAttributesAsWritten() != 0 &&
7645 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007646 .Case("readonly", true)
7647 .Case("assign", true)
7648 .Case("unsafe_unretained", true)
7649 .Case("readwrite", true)
7650 .Case("retain", true)
7651 .Case("copy", true)
7652 .Case("nonatomic", true)
7653 .Case("atomic", true)
7654 .Case("getter", true)
7655 .Case("setter", true)
7656 .Case("strong", true)
7657 .Case("weak", true)
7658 .Case("class", true)
7659 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007660 Tokens[I].int_data[0] = CXToken_Keyword;
7661 }
7662 continue;
7663 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007664
Guy Benyei11169dd2012-12-18 14:30:41 +00007665 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7666 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7667 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7668 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007669 .Case("in", true)
7670 .Case("out", true)
7671 .Case("inout", true)
7672 .Case("oneway", true)
7673 .Case("bycopy", true)
7674 .Case("byref", true)
7675 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007676 Tokens[I].int_data[0] = CXToken_Keyword;
7677 continue;
7678 }
7679
7680 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7681 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7682 Tokens[I].int_data[0] = CXToken_Keyword;
7683 continue;
7684 }
7685 }
7686 }
7687}
7688
Michael Kruse7520cf02020-03-25 09:26:14 -05007689void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7690 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007691 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007692 LOG_BAD_TU(TU);
7693 return;
7694 }
7695 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007696 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007697 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007698 }
7699
7700 LOG_FUNC_SECTION {
7701 *Log << TU << ' ';
7702 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007703 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007704 *Log << clang_getRange(bloc, eloc);
7705 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007706
7707 // Any token we don't specifically annotate will have a NULL cursor.
7708 CXCursor C = clang_getNullCursor();
7709 for (unsigned I = 0; I != NumTokens; ++I)
7710 Cursors[I] = C;
7711
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007712 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007713 if (!CXXUnit)
7714 return;
7715
7716 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007717
7718 auto AnnotateTokensImpl = [=]() {
7719 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7720 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007721 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007722 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007723 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7724 }
7725}
7726
Guy Benyei11169dd2012-12-18 14:30:41 +00007727//===----------------------------------------------------------------------===//
7728// Operations for querying linkage of a cursor.
7729//===----------------------------------------------------------------------===//
7730
Guy Benyei11169dd2012-12-18 14:30:41 +00007731CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7732 if (!clang_isDeclaration(cursor.kind))
7733 return CXLinkage_Invalid;
7734
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007735 const Decl *D = cxcursor::getCursorDecl(cursor);
7736 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007737 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007738 case NoLinkage:
7739 case VisibleNoLinkage:
7740 return CXLinkage_NoLinkage;
7741 case ModuleInternalLinkage:
7742 case InternalLinkage:
7743 return CXLinkage_Internal;
7744 case UniqueExternalLinkage:
7745 return CXLinkage_UniqueExternal;
7746 case ModuleLinkage:
7747 case ExternalLinkage:
7748 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007749 };
7750
7751 return CXLinkage_Invalid;
7752}
Guy Benyei11169dd2012-12-18 14:30:41 +00007753
7754//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007755// Operations for querying visibility of a cursor.
7756//===----------------------------------------------------------------------===//
7757
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007758CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7759 if (!clang_isDeclaration(cursor.kind))
7760 return CXVisibility_Invalid;
7761
7762 const Decl *D = cxcursor::getCursorDecl(cursor);
7763 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7764 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007765 case HiddenVisibility:
7766 return CXVisibility_Hidden;
7767 case ProtectedVisibility:
7768 return CXVisibility_Protected;
7769 case DefaultVisibility:
7770 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007771 };
7772
7773 return CXVisibility_Invalid;
7774}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007775
7776//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007777// Operations for querying language of a cursor.
7778//===----------------------------------------------------------------------===//
7779
7780static CXLanguageKind getDeclLanguage(const Decl *D) {
7781 if (!D)
7782 return CXLanguage_C;
7783
7784 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007785 default:
7786 break;
7787 case Decl::ImplicitParam:
7788 case Decl::ObjCAtDefsField:
7789 case Decl::ObjCCategory:
7790 case Decl::ObjCCategoryImpl:
7791 case Decl::ObjCCompatibleAlias:
7792 case Decl::ObjCImplementation:
7793 case Decl::ObjCInterface:
7794 case Decl::ObjCIvar:
7795 case Decl::ObjCMethod:
7796 case Decl::ObjCProperty:
7797 case Decl::ObjCPropertyImpl:
7798 case Decl::ObjCProtocol:
7799 case Decl::ObjCTypeParam:
7800 return CXLanguage_ObjC;
7801 case Decl::CXXConstructor:
7802 case Decl::CXXConversion:
7803 case Decl::CXXDestructor:
7804 case Decl::CXXMethod:
7805 case Decl::CXXRecord:
7806 case Decl::ClassTemplate:
7807 case Decl::ClassTemplatePartialSpecialization:
7808 case Decl::ClassTemplateSpecialization:
7809 case Decl::Friend:
7810 case Decl::FriendTemplate:
7811 case Decl::FunctionTemplate:
7812 case Decl::LinkageSpec:
7813 case Decl::Namespace:
7814 case Decl::NamespaceAlias:
7815 case Decl::NonTypeTemplateParm:
7816 case Decl::StaticAssert:
7817 case Decl::TemplateTemplateParm:
7818 case Decl::TemplateTypeParm:
7819 case Decl::UnresolvedUsingTypename:
7820 case Decl::UnresolvedUsingValue:
7821 case Decl::Using:
7822 case Decl::UsingDirective:
7823 case Decl::UsingShadow:
7824 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007825 }
7826
7827 return CXLanguage_C;
7828}
7829
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007830static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7831 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007832 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007833
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007834 switch (D->getAvailability()) {
7835 case AR_Available:
7836 case AR_NotYetIntroduced:
7837 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007838 return getCursorAvailabilityForDecl(
7839 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007840 return CXAvailability_Available;
7841
7842 case AR_Deprecated:
7843 return CXAvailability_Deprecated;
7844
7845 case AR_Unavailable:
7846 return CXAvailability_NotAvailable;
7847 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007848
7849 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007850}
7851
Guy Benyei11169dd2012-12-18 14:30:41 +00007852enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7853 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007854 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7855 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007856
7857 return CXAvailability_Available;
7858}
7859
7860static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007861 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007862 if (In.empty())
7863 return Out;
7864
7865 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007866
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007867 Optional<unsigned> Minor = In.getMinor();
7868 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007869 Out.Minor = *Minor;
7870 else
7871 return Out;
7872
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007873 Optional<unsigned> Subminor = In.getSubminor();
7874 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007875 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007876
Guy Benyei11169dd2012-12-18 14:30:41 +00007877 return Out;
7878}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007879
Alex Lorenz1345ea22017-06-12 19:06:30 +00007880static void getCursorPlatformAvailabilityForDecl(
7881 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7882 int *always_unavailable, CXString *unavailable_message,
7883 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007884 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007885 for (auto A : D->attrs()) {
7886 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007887 HadAvailAttr = true;
7888 if (always_deprecated)
7889 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007890 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007891 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007892 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007893 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007894 continue;
7895 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007896
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007897 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007898 HadAvailAttr = true;
7899 if (always_unavailable)
7900 *always_unavailable = 1;
7901 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007902 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007903 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7904 }
7905 continue;
7906 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007907
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007908 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007909 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007910 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007911 }
7912 }
7913
7914 if (!HadAvailAttr)
7915 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7916 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007917 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7918 deprecated_message, always_unavailable, unavailable_message,
7919 AvailabilityAttrs);
7920
7921 if (AvailabilityAttrs.empty())
7922 return;
7923
Michael Kruse7520cf02020-03-25 09:26:14 -05007924 llvm::sort(
7925 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7926 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7927 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007928 ASTContext &Ctx = D->getASTContext();
7929 auto It = std::unique(
7930 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7931 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7932 if (LHS->getPlatform() != RHS->getPlatform())
7933 return false;
7934
7935 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7936 LHS->getDeprecated() == RHS->getDeprecated() &&
7937 LHS->getObsoleted() == RHS->getObsoleted() &&
7938 LHS->getMessage() == RHS->getMessage() &&
7939 LHS->getReplacement() == RHS->getReplacement())
7940 return true;
7941
7942 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
7943 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
7944 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
7945 return false;
7946
7947 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
7948 LHS->setIntroduced(Ctx, RHS->getIntroduced());
7949
7950 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
7951 LHS->setDeprecated(Ctx, RHS->getDeprecated());
7952 if (LHS->getMessage().empty())
7953 LHS->setMessage(Ctx, RHS->getMessage());
7954 if (LHS->getReplacement().empty())
7955 LHS->setReplacement(Ctx, RHS->getReplacement());
7956 }
7957
7958 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
7959 LHS->setObsoleted(Ctx, RHS->getObsoleted());
7960 if (LHS->getMessage().empty())
7961 LHS->setMessage(Ctx, RHS->getMessage());
7962 if (LHS->getReplacement().empty())
7963 LHS->setReplacement(Ctx, RHS->getReplacement());
7964 }
7965
7966 return true;
7967 });
7968 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007969}
7970
Alex Lorenz1345ea22017-06-12 19:06:30 +00007971int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00007972 CXString *deprecated_message,
7973 int *always_unavailable,
7974 CXString *unavailable_message,
7975 CXPlatformAvailability *availability,
7976 int availability_size) {
7977 if (always_deprecated)
7978 *always_deprecated = 0;
7979 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007980 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007981 if (always_unavailable)
7982 *always_unavailable = 0;
7983 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007984 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007985
Guy Benyei11169dd2012-12-18 14:30:41 +00007986 if (!clang_isDeclaration(cursor.kind))
7987 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007988
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007989 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007990 if (!D)
7991 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007992
Alex Lorenz1345ea22017-06-12 19:06:30 +00007993 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
7994 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
7995 always_unavailable, unavailable_message,
7996 AvailabilityAttrs);
7997 for (const auto &Avail :
7998 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
7999 .take_front(availability_size))) {
8000 availability[Avail.index()].Platform =
8001 cxstring::createDup(Avail.value()->getPlatform()->getName());
8002 availability[Avail.index()].Introduced =
8003 convertVersion(Avail.value()->getIntroduced());
8004 availability[Avail.index()].Deprecated =
8005 convertVersion(Avail.value()->getDeprecated());
8006 availability[Avail.index()].Obsoleted =
8007 convertVersion(Avail.value()->getObsoleted());
8008 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8009 availability[Avail.index()].Message =
8010 cxstring::createDup(Avail.value()->getMessage());
8011 }
8012
8013 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008014}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008015
Guy Benyei11169dd2012-12-18 14:30:41 +00008016void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8017 clang_disposeString(availability->Platform);
8018 clang_disposeString(availability->Message);
8019}
8020
8021CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8022 if (clang_isDeclaration(cursor.kind))
8023 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8024
8025 return CXLanguage_Invalid;
8026}
8027
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008028CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8029 const Decl *D = cxcursor::getCursorDecl(cursor);
8030 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8031 switch (VD->getTLSKind()) {
8032 case VarDecl::TLS_None:
8033 return CXTLS_None;
8034 case VarDecl::TLS_Dynamic:
8035 return CXTLS_Dynamic;
8036 case VarDecl::TLS_Static:
8037 return CXTLS_Static;
8038 }
8039 }
8040
8041 return CXTLS_None;
8042}
8043
Michael Kruse7520cf02020-03-25 09:26:14 -05008044/// If the given cursor is the "templated" declaration
8045/// describing a class or function template, return the class or
8046/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008047static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008048 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008049 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008050
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008051 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008052 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8053 return FunTmpl;
8054
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008055 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008056 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8057 return ClassTmpl;
8058
8059 return D;
8060}
8061
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008062enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8063 StorageClass sc = SC_None;
8064 const Decl *D = getCursorDecl(C);
8065 if (D) {
8066 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8067 sc = FD->getStorageClass();
8068 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8069 sc = VD->getStorageClass();
8070 } else {
8071 return CX_SC_Invalid;
8072 }
8073 } else {
8074 return CX_SC_Invalid;
8075 }
8076 switch (sc) {
8077 case SC_None:
8078 return CX_SC_None;
8079 case SC_Extern:
8080 return CX_SC_Extern;
8081 case SC_Static:
8082 return CX_SC_Static;
8083 case SC_PrivateExtern:
8084 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008085 case SC_Auto:
8086 return CX_SC_Auto;
8087 case SC_Register:
8088 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008089 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008090 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008091}
8092
Guy Benyei11169dd2012-12-18 14:30:41 +00008093CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8094 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008095 if (const Decl *D = getCursorDecl(cursor)) {
8096 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008097 if (!DC)
8098 return clang_getNullCursor();
8099
Michael Kruse7520cf02020-03-25 09:26:14 -05008100 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008101 getCursorTU(cursor));
8102 }
8103 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008104
Guy Benyei11169dd2012-12-18 14:30:41 +00008105 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008106 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008107 return MakeCXCursor(D, getCursorTU(cursor));
8108 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008109
Guy Benyei11169dd2012-12-18 14:30:41 +00008110 return clang_getNullCursor();
8111}
8112
8113CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8114 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008115 if (const Decl *D = getCursorDecl(cursor)) {
8116 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008117 if (!DC)
8118 return clang_getNullCursor();
8119
Michael Kruse7520cf02020-03-25 09:26:14 -05008120 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008121 getCursorTU(cursor));
8122 }
8123 }
8124
Michael Kruse7520cf02020-03-25 09:26:14 -05008125 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008126 // statement or expression, so we return nothing.
8127 return clang_getNullCursor();
8128}
8129
8130CXFile clang_getIncludedFile(CXCursor cursor) {
8131 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008132 return nullptr;
8133
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008134 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008135 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008136}
8137
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008138unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8139 if (C.kind != CXCursor_ObjCPropertyDecl)
8140 return CXObjCPropertyAttr_noattr;
8141
8142 unsigned Result = CXObjCPropertyAttr_noattr;
8143 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8144 ObjCPropertyDecl::PropertyAttributeKind Attr =
8145 PD->getPropertyAttributesAsWritten();
8146
Michael Kruse7520cf02020-03-25 09:26:14 -05008147#define SET_CXOBJCPROP_ATTR(A) \
8148 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
8149 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008150 SET_CXOBJCPROP_ATTR(readonly);
8151 SET_CXOBJCPROP_ATTR(getter);
8152 SET_CXOBJCPROP_ATTR(assign);
8153 SET_CXOBJCPROP_ATTR(readwrite);
8154 SET_CXOBJCPROP_ATTR(retain);
8155 SET_CXOBJCPROP_ATTR(copy);
8156 SET_CXOBJCPROP_ATTR(nonatomic);
8157 SET_CXOBJCPROP_ATTR(setter);
8158 SET_CXOBJCPROP_ATTR(atomic);
8159 SET_CXOBJCPROP_ATTR(weak);
8160 SET_CXOBJCPROP_ATTR(strong);
8161 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008162 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008163#undef SET_CXOBJCPROP_ATTR
8164
8165 return Result;
8166}
8167
Michael Wu6e88f532018-08-03 05:38:29 +00008168CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8169 if (C.kind != CXCursor_ObjCPropertyDecl)
8170 return cxstring::createNull();
8171
8172 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8173 Selector sel = PD->getGetterName();
8174 if (sel.isNull())
8175 return cxstring::createNull();
8176
8177 return cxstring::createDup(sel.getAsString());
8178}
8179
8180CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8181 if (C.kind != CXCursor_ObjCPropertyDecl)
8182 return cxstring::createNull();
8183
8184 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8185 Selector sel = PD->getSetterName();
8186 if (sel.isNull())
8187 return cxstring::createNull();
8188
8189 return cxstring::createDup(sel.getAsString());
8190}
8191
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008192unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8193 if (!clang_isDeclaration(C.kind))
8194 return CXObjCDeclQualifier_None;
8195
8196 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8197 const Decl *D = getCursorDecl(C);
8198 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8199 QT = MD->getObjCDeclQualifier();
8200 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8201 QT = PD->getObjCDeclQualifier();
8202 if (QT == Decl::OBJC_TQ_None)
8203 return CXObjCDeclQualifier_None;
8204
8205 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008206 if (QT & Decl::OBJC_TQ_In)
8207 Result |= CXObjCDeclQualifier_In;
8208 if (QT & Decl::OBJC_TQ_Inout)
8209 Result |= CXObjCDeclQualifier_Inout;
8210 if (QT & Decl::OBJC_TQ_Out)
8211 Result |= CXObjCDeclQualifier_Out;
8212 if (QT & Decl::OBJC_TQ_Bycopy)
8213 Result |= CXObjCDeclQualifier_Bycopy;
8214 if (QT & Decl::OBJC_TQ_Byref)
8215 Result |= CXObjCDeclQualifier_Byref;
8216 if (QT & Decl::OBJC_TQ_Oneway)
8217 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008218
8219 return Result;
8220}
8221
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008222unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8223 if (!clang_isDeclaration(C.kind))
8224 return 0;
8225
8226 const Decl *D = getCursorDecl(C);
8227 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8228 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8229 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8230 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8231
8232 return 0;
8233}
8234
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008235unsigned clang_Cursor_isVariadic(CXCursor C) {
8236 if (!clang_isDeclaration(C.kind))
8237 return 0;
8238
8239 const Decl *D = getCursorDecl(C);
8240 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8241 return FD->isVariadic();
8242 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8243 return MD->isVariadic();
8244
8245 return 0;
8246}
8247
Michael Kruse7520cf02020-03-25 09:26:14 -05008248unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8249 CXString *definedIn,
8250 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008251 if (!clang_isDeclaration(C.kind))
8252 return 0;
8253
8254 const Decl *D = getCursorDecl(C);
8255
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008256 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008257 if (language)
8258 *language = cxstring::createDup(attr->getLanguage());
8259 if (definedIn)
8260 *definedIn = cxstring::createDup(attr->getDefinedIn());
8261 if (isGenerated)
8262 *isGenerated = attr->getGeneratedDeclaration();
8263 return 1;
8264 }
8265 return 0;
8266}
8267
Guy Benyei11169dd2012-12-18 14:30:41 +00008268CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8269 if (!clang_isDeclaration(C.kind))
8270 return clang_getNullRange();
8271
8272 const Decl *D = getCursorDecl(C);
8273 ASTContext &Context = getCursorContext(C);
8274 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8275 if (!RC)
8276 return clang_getNullRange();
8277
8278 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8279}
8280
8281CXString clang_Cursor_getRawCommentText(CXCursor C) {
8282 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008283 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008284
8285 const Decl *D = getCursorDecl(C);
8286 ASTContext &Context = getCursorContext(C);
8287 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008288 StringRef RawText =
8289 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008290
8291 // Don't duplicate the string because RawText points directly into source
8292 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008293 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008294}
8295
8296CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8297 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008298 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008299
8300 const Decl *D = getCursorDecl(C);
8301 const ASTContext &Context = getCursorContext(C);
8302 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8303
8304 if (RC) {
8305 StringRef BriefText = RC->getBriefText(Context);
8306
8307 // Don't duplicate the string because RawComment ensures that this memory
8308 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008309 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008310 }
8311
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008312 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008313}
8314
Guy Benyei11169dd2012-12-18 14:30:41 +00008315CXModule clang_Cursor_getModule(CXCursor C) {
8316 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008317 if (const ImportDecl *ImportD =
8318 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008319 return ImportD->getImportedModule();
8320 }
8321
Craig Topper69186e72014-06-08 08:38:04 +00008322 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008323}
8324
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008325CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8326 if (isNotUsableTU(TU)) {
8327 LOG_BAD_TU(TU);
8328 return nullptr;
8329 }
8330 if (!File)
8331 return nullptr;
8332 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008333
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008334 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8335 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8336 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008337
Richard Smithfeb54b62014-10-23 02:01:19 +00008338 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008339}
8340
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008341CXFile clang_Module_getASTFile(CXModule CXMod) {
8342 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008343 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008344 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008345 return const_cast<FileEntry *>(Mod->getASTFile());
8346}
8347
Guy Benyei11169dd2012-12-18 14:30:41 +00008348CXModule clang_Module_getParent(CXModule CXMod) {
8349 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008350 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008351 Module *Mod = static_cast<Module *>(CXMod);
Guy Benyei11169dd2012-12-18 14:30:41 +00008352 return Mod->Parent;
8353}
8354
8355CXString clang_Module_getName(CXModule CXMod) {
8356 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008357 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008358 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008359 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008360}
8361
8362CXString clang_Module_getFullName(CXModule CXMod) {
8363 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008364 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008365 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008366 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008367}
8368
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008369int clang_Module_isSystem(CXModule CXMod) {
8370 if (!CXMod)
8371 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008372 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008373 return Mod->IsSystem;
8374}
8375
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008376unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8377 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008378 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008379 LOG_BAD_TU(TU);
8380 return 0;
8381 }
8382 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008383 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008384 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008385 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8386 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8387 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008388}
8389
Michael Kruse7520cf02020-03-25 09:26:14 -05008390CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8391 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008392 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008393 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008394 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008395 }
8396 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008397 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008398 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008399 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008400
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008401 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8402 if (Index < TopHeaders.size())
8403 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008404
Craig Topper69186e72014-06-08 08:38:04 +00008405 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008406}
8407
Guy Benyei11169dd2012-12-18 14:30:41 +00008408//===----------------------------------------------------------------------===//
8409// C++ AST instrospection.
8410//===----------------------------------------------------------------------===//
8411
Jonathan Coe29565352016-04-27 12:48:25 +00008412unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8413 if (!clang_isDeclaration(C.kind))
8414 return 0;
8415
8416 const Decl *D = cxcursor::getCursorDecl(C);
8417 const CXXConstructorDecl *Constructor =
8418 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8419 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8420}
8421
8422unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8423 if (!clang_isDeclaration(C.kind))
8424 return 0;
8425
8426 const Decl *D = cxcursor::getCursorDecl(C);
8427 const CXXConstructorDecl *Constructor =
8428 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8429 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8430}
8431
8432unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8433 if (!clang_isDeclaration(C.kind))
8434 return 0;
8435
8436 const Decl *D = cxcursor::getCursorDecl(C);
8437 const CXXConstructorDecl *Constructor =
8438 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8439 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8440}
8441
8442unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8443 if (!clang_isDeclaration(C.kind))
8444 return 0;
8445
8446 const Decl *D = cxcursor::getCursorDecl(C);
8447 const CXXConstructorDecl *Constructor =
8448 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8449 // Passing 'false' excludes constructors marked 'explicit'.
8450 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8451}
8452
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008453unsigned clang_CXXField_isMutable(CXCursor C) {
8454 if (!clang_isDeclaration(C.kind))
8455 return 0;
8456
8457 if (const auto D = cxcursor::getCursorDecl(C))
8458 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8459 return FD->isMutable() ? 1 : 0;
8460 return 0;
8461}
8462
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008463unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8464 if (!clang_isDeclaration(C.kind))
8465 return 0;
8466
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008467 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008468 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008469 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008470 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8471}
8472
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008473unsigned clang_CXXMethod_isConst(CXCursor C) {
8474 if (!clang_isDeclaration(C.kind))
8475 return 0;
8476
8477 const Decl *D = cxcursor::getCursorDecl(C);
8478 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008479 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008480 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008481}
8482
Jonathan Coe29565352016-04-27 12:48:25 +00008483unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8484 if (!clang_isDeclaration(C.kind))
8485 return 0;
8486
8487 const Decl *D = cxcursor::getCursorDecl(C);
8488 const CXXMethodDecl *Method =
8489 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8490 return (Method && Method->isDefaulted()) ? 1 : 0;
8491}
8492
Guy Benyei11169dd2012-12-18 14:30:41 +00008493unsigned clang_CXXMethod_isStatic(CXCursor C) {
8494 if (!clang_isDeclaration(C.kind))
8495 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008496
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008497 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008498 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008499 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008500 return (Method && Method->isStatic()) ? 1 : 0;
8501}
8502
8503unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8504 if (!clang_isDeclaration(C.kind))
8505 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008506
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008507 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008508 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008509 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008510 return (Method && Method->isVirtual()) ? 1 : 0;
8511}
Guy Benyei11169dd2012-12-18 14:30:41 +00008512
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008513unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8514 if (!clang_isDeclaration(C.kind))
8515 return 0;
8516
8517 const auto *D = cxcursor::getCursorDecl(C);
8518 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8519 if (RD)
8520 RD = RD->getDefinition();
8521 return (RD && RD->isAbstract()) ? 1 : 0;
8522}
8523
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008524unsigned clang_EnumDecl_isScoped(CXCursor C) {
8525 if (!clang_isDeclaration(C.kind))
8526 return 0;
8527
8528 const Decl *D = cxcursor::getCursorDecl(C);
8529 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8530 return (Enum && Enum->isScoped()) ? 1 : 0;
8531}
8532
Guy Benyei11169dd2012-12-18 14:30:41 +00008533//===----------------------------------------------------------------------===//
8534// Attribute introspection.
8535//===----------------------------------------------------------------------===//
8536
Guy Benyei11169dd2012-12-18 14:30:41 +00008537CXType clang_getIBOutletCollectionType(CXCursor C) {
8538 if (C.kind != CXCursor_IBOutletCollectionAttr)
8539 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008540
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008541 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008542 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8543
8544 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008545}
Guy Benyei11169dd2012-12-18 14:30:41 +00008546
8547//===----------------------------------------------------------------------===//
8548// Inspecting memory usage.
8549//===----------------------------------------------------------------------===//
8550
8551typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8552
8553static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008554 enum CXTUResourceUsageKind k,
8555 unsigned long amount) {
8556 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008557 entries.push_back(entry);
8558}
8559
Guy Benyei11169dd2012-12-18 14:30:41 +00008560const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8561 const char *str = "";
8562 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008563 case CXTUResourceUsage_AST:
8564 str = "ASTContext: expressions, declarations, and types";
8565 break;
8566 case CXTUResourceUsage_Identifiers:
8567 str = "ASTContext: identifiers";
8568 break;
8569 case CXTUResourceUsage_Selectors:
8570 str = "ASTContext: selectors";
8571 break;
8572 case CXTUResourceUsage_GlobalCompletionResults:
8573 str = "Code completion: cached global results";
8574 break;
8575 case CXTUResourceUsage_SourceManagerContentCache:
8576 str = "SourceManager: content cache allocator";
8577 break;
8578 case CXTUResourceUsage_AST_SideTables:
8579 str = "ASTContext: side tables";
8580 break;
8581 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8582 str = "SourceManager: malloc'ed memory buffers";
8583 break;
8584 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8585 str = "SourceManager: mmap'ed memory buffers";
8586 break;
8587 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8588 str = "ExternalASTSource: malloc'ed memory buffers";
8589 break;
8590 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8591 str = "ExternalASTSource: mmap'ed memory buffers";
8592 break;
8593 case CXTUResourceUsage_Preprocessor:
8594 str = "Preprocessor: malloc'ed memory";
8595 break;
8596 case CXTUResourceUsage_PreprocessingRecord:
8597 str = "Preprocessor: PreprocessingRecord";
8598 break;
8599 case CXTUResourceUsage_SourceManager_DataStructures:
8600 str = "SourceManager: data structures and tables";
8601 break;
8602 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8603 str = "Preprocessor: header search tables";
8604 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008605 }
8606 return str;
8607}
8608
8609CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008610 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008611 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008612 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008613 return usage;
8614 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008615
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008616 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008617 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008618 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008619
Guy Benyei11169dd2012-12-18 14:30:41 +00008620 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008621 createCXTUResourceUsageEntry(
8622 *entries, CXTUResourceUsage_AST,
8623 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008624
8625 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008626 createCXTUResourceUsageEntry(
8627 *entries, CXTUResourceUsage_Identifiers,
8628 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008629
8630 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008631 createCXTUResourceUsageEntry(
8632 *entries, CXTUResourceUsage_Selectors,
8633 (unsigned long)astContext.Selectors.getTotalMemory());
8634
Guy Benyei11169dd2012-12-18 14:30:41 +00008635 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008636 createCXTUResourceUsageEntry(
8637 *entries, CXTUResourceUsage_AST_SideTables,
8638 (unsigned long)astContext.getSideTableAllocatedMemory());
8639
Guy Benyei11169dd2012-12-18 14:30:41 +00008640 // How much memory is used for caching global code completion results?
8641 unsigned long completionBytes = 0;
8642 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008643 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008644 completionBytes = completionAllocator->getTotalMemory();
8645 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008646 createCXTUResourceUsageEntry(
8647 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8648
Guy Benyei11169dd2012-12-18 14:30:41 +00008649 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008650 createCXTUResourceUsageEntry(
8651 *entries, CXTUResourceUsage_SourceManagerContentCache,
8652 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8653
Guy Benyei11169dd2012-12-18 14:30:41 +00008654 // How much memory is being used by the MemoryBuffer's in SourceManager?
8655 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008656 astUnit->getSourceManager().getMemoryBufferSizes();
8657
Guy Benyei11169dd2012-12-18 14:30:41 +00008658 createCXTUResourceUsageEntry(*entries,
8659 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008660 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008661 createCXTUResourceUsageEntry(*entries,
8662 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008663 (unsigned long)srcBufs.mmap_bytes);
8664 createCXTUResourceUsageEntry(
8665 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8666 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8667
Guy Benyei11169dd2012-12-18 14:30:41 +00008668 // How much memory is being used by the ExternalASTSource?
8669 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8670 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008671 esrc->getMemoryBufferSizes();
8672
8673 createCXTUResourceUsageEntry(
8674 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8675 (unsigned long)sizes.malloc_bytes);
8676 createCXTUResourceUsageEntry(
8677 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8678 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008679 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008680
Guy Benyei11169dd2012-12-18 14:30:41 +00008681 // How much memory is being used by the Preprocessor?
8682 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008683 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008684 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008685
Guy Benyei11169dd2012-12-18 14:30:41 +00008686 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8687 createCXTUResourceUsageEntry(*entries,
8688 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008689 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008690 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008691
Guy Benyei11169dd2012-12-18 14:30:41 +00008692 createCXTUResourceUsageEntry(*entries,
8693 CXTUResourceUsage_Preprocessor_HeaderSearch,
8694 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008695
Michael Kruse7520cf02020-03-25 09:26:14 -05008696 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8697 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008698 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008699 return usage;
8700}
8701
8702void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8703 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008704 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008705}
8706
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008707CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8708 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008709 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008710 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008711
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008712 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008713 LOG_BAD_TU(TU);
8714 return skipped;
8715 }
8716
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008717 if (!file)
8718 return skipped;
8719
8720 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008721 PreprocessingRecord *ppRec =
8722 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008723 if (!ppRec)
8724 return skipped;
8725
8726 ASTContext &Ctx = astUnit->getASTContext();
8727 SourceManager &sm = Ctx.getSourceManager();
8728 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8729 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008730 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008731
8732 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8733 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008734 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8735 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008736 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008737 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8738 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008739 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008740 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8741 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008742 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008743 }
8744
8745 skipped->count = wantedRanges.size();
8746 skipped->ranges = new CXSourceRange[skipped->count];
8747 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8748 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8749
8750 return skipped;
8751}
8752
Cameron Desrochersd8091282016-08-18 15:43:55 +00008753CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8754 CXSourceRangeList *skipped = new CXSourceRangeList;
8755 skipped->count = 0;
8756 skipped->ranges = nullptr;
8757
8758 if (isNotUsableTU(TU)) {
8759 LOG_BAD_TU(TU);
8760 return skipped;
8761 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008762
Cameron Desrochersd8091282016-08-18 15:43:55 +00008763 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008764 PreprocessingRecord *ppRec =
8765 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008766 if (!ppRec)
8767 return skipped;
8768
8769 ASTContext &Ctx = astUnit->getASTContext();
8770
8771 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8772
8773 skipped->count = SkippedRanges.size();
8774 skipped->ranges = new CXSourceRange[skipped->count];
8775 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8776 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8777
8778 return skipped;
8779}
8780
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008781void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8782 if (ranges) {
8783 delete[] ranges->ranges;
8784 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008785 }
8786}
8787
Guy Benyei11169dd2012-12-18 14:30:41 +00008788void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8789 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8790 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008791 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008792 clang_getTUResourceUsageName(Usage.entries[I].kind),
8793 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008794
Guy Benyei11169dd2012-12-18 14:30:41 +00008795 clang_disposeCXTUResourceUsage(Usage);
8796}
8797
8798//===----------------------------------------------------------------------===//
8799// Misc. utility functions.
8800//===----------------------------------------------------------------------===//
8801
Richard Smith0a7b2972018-07-03 21:34:13 +00008802/// Default to using our desired 8 MB stack size on "safety" threads.
8803static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008804
8805namespace clang {
8806
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008807bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008808 unsigned Size) {
8809 if (!Size)
8810 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008811 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008812 return CRC.RunSafelyOnThread(Fn, Size);
8813 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008814}
8815
Michael Kruse7520cf02020-03-25 09:26:14 -05008816unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008817
Michael Kruse7520cf02020-03-25 09:26:14 -05008818void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008819
Michael Kruse7520cf02020-03-25 09:26:14 -05008820} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008821
8822void clang::setThreadBackgroundPriority() {
8823 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8824 return;
8825
Nico Weber18cfd9f2019-04-21 19:18:41 +00008826#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008827 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008828#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008829}
8830
8831void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8832 if (!Unit)
8833 return;
8834
Michael Kruse7520cf02020-03-25 09:26:14 -05008835 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8836 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008837 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008838 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008839 CXString Msg =
8840 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008841 fprintf(stderr, "%s\n", clang_getCString(Msg));
8842 clang_disposeString(Msg);
8843 }
Nico Weber1865df42018-04-27 19:11:14 +00008844#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008845 // On Windows, force a flush, since there may be multiple copies of
8846 // stderr and stdout in the file system, all with different buffers
8847 // but writing to the same device.
8848 fflush(stderr);
8849#endif
8850}
8851
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008852MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8853 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008854 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008855 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008856 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008857 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008858 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008859
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008860 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008861 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008862 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008863 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008864 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8865 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008866 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8867 return Def.getMacroInfo();
8868 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008869 }
8870
Craig Topper69186e72014-06-08 08:38:04 +00008871 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008872}
8873
Richard Smith66a81862015-05-04 02:25:31 +00008874const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008875 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008876 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008877 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008878 const IdentifierInfo *II = MacroDef->getName();
8879 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008880 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008881
8882 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8883}
8884
Richard Smith66a81862015-05-04 02:25:31 +00008885MacroDefinitionRecord *
8886cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8887 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008888 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008889 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008890 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008891 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008892
8893 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008894 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008895 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8896 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008897 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008898
8899 // Check that the token is inside the definition and not its argument list.
8900 SourceManager &SM = Unit->getSourceManager();
8901 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008902 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008903 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00008904 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008905
8906 Preprocessor &PP = Unit->getPreprocessor();
8907 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
8908 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00008909 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008910
Alp Toker2d57cea2014-05-17 04:53:25 +00008911 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008912 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008913 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008914
8915 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00008916 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00008917 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008918
Richard Smith20e883e2015-04-29 23:20:19 +00008919 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00008920 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00008921 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008922
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008923 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008924}
8925
Richard Smith66a81862015-05-04 02:25:31 +00008926MacroDefinitionRecord *
8927cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
8928 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008929 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008930 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008931
8932 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008933 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008934 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008935 Preprocessor &PP = Unit->getPreprocessor();
8936 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00008937 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008938 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
8939 Token Tok;
8940 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00008941 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008942
8943 return checkForMacroInMacroDefinition(MI, Tok, TU);
8944}
8945
Guy Benyei11169dd2012-12-18 14:30:41 +00008946CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008947 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00008948}
8949
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008950Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
8951 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008952 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008953 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00008954 if (Unit->isMainFileAST())
8955 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008956 return *this;
8957 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00008958 } else {
8959 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008960 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008961 return *this;
8962}
8963
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00008964Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
8965 *this << FE->getName();
8966 return *this;
8967}
8968
8969Logger &cxindex::Logger::operator<<(CXCursor cursor) {
8970 CXString cursorName = clang_getCursorDisplayName(cursor);
8971 *this << cursorName << "@" << clang_getCursorLocation(cursor);
8972 clang_disposeString(cursorName);
8973 return *this;
8974}
8975
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008976Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
8977 CXFile File;
8978 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00008979 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008980 CXString FileName = clang_getFileName(File);
8981 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
8982 clang_disposeString(FileName);
8983 return *this;
8984}
8985
8986Logger &cxindex::Logger::operator<<(CXSourceRange range) {
8987 CXSourceLocation BLoc = clang_getRangeStart(range);
8988 CXSourceLocation ELoc = clang_getRangeEnd(range);
8989
8990 CXFile BFile;
8991 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00008992 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008993
8994 CXFile EFile;
8995 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00008996 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008997
8998 CXString BFileName = clang_getFileName(BFile);
8999 if (BFile == EFile) {
9000 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05009001 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009002 } else {
9003 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009004 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9005 BColumn)
9006 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9007 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009008 clang_disposeString(EFileName);
9009 }
9010 clang_disposeString(BFileName);
9011 return *this;
9012}
9013
9014Logger &cxindex::Logger::operator<<(CXString Str) {
9015 *this << clang_getCString(Str);
9016 return *this;
9017}
9018
9019Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9020 LogOS << Fmt;
9021 return *this;
9022}
9023
Benjamin Kramer762bc332019-08-07 14:44:40 +00009024static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009025
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009026cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009027 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009028
9029 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9030
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009031 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009032 OS << "[libclang:" << Name << ':';
9033
Alp Toker1a86ad22014-07-06 06:24:00 +00009034#ifdef USE_DARWIN_THREADS
9035 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009036 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9037 OS << tid << ':';
9038#endif
9039
9040 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9041 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009042 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009043
9044 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009045 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009046 OS << "--------------------------------------------------\n";
9047 }
9048}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009049
9050#ifdef CLANG_TOOL_EXTRA_BUILD
9051// This anchor is used to force the linker to link the clang-tidy plugin.
9052extern volatile int ClangTidyPluginAnchorSource;
9053static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9054 ClangTidyPluginAnchorSource;
9055
9056// This anchor is used to force the linker to link the clang-include-fixer
9057// plugin.
9058extern volatile int ClangIncludeFixerPluginAnchorSource;
9059static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9060 ClangIncludeFixerPluginAnchorSource;
9061#endif