blob: dafe4ccda05f9d3beef2fc4d395dcc7b0d57ae74 [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)
Erich Keane5f0903e2020-04-17 10:44:19 -07001796DEFAULT_TYPELOC_IMPL(ExtInt, Type)
1797DEFAULT_TYPELOC_IMPL(DependentExtInt, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001798
1799bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1800 // Visit the nested-name-specifier, if present.
1801 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1803 return true;
1804
1805 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001806 for (const auto &I : D->bases()) {
1807 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001808 return true;
1809 }
1810 }
1811
1812 return VisitTagDecl(D);
1813}
1814
1815bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001816 for (const auto *I : D->attrs())
Michael Wu40ff1052018-08-03 05:20:23 +00001817 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1818 !I->isImplicit()) &&
1819 Visit(MakeCXCursor(I, D, TU)))
Michael Kruse7520cf02020-03-25 09:26:14 -05001820 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00001821
1822 return false;
1823}
1824
1825//===----------------------------------------------------------------------===//
1826// Data-recursive visitor methods.
1827//===----------------------------------------------------------------------===//
1828
1829namespace {
Michael Kruse7520cf02020-03-25 09:26:14 -05001830#define DEF_JOB(NAME, DATA, KIND) \
1831 class NAME : public VisitorJob { \
1832 public: \
1833 NAME(const DATA *d, CXCursor parent) \
1834 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1835 static bool classof(const VisitorJob *VJ) { \
1836 return VJ->getKind() == KIND; \
1837 } \
1838 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1839 };
Guy Benyei11169dd2012-12-18 14:30:41 +00001840
1841DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1842DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1843DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1844DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001845DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1846DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1847DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1848#undef DEF_JOB
1849
James Y Knight04ec5bf2015-12-24 02:59:37 +00001850class ExplicitTemplateArgsVisit : public VisitorJob {
1851public:
1852 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1853 const TemplateArgumentLoc *End, CXCursor parent)
1854 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1855 End) {}
1856 static bool classof(const VisitorJob *VJ) {
1857 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1858 }
1859 const TemplateArgumentLoc *begin() const {
1860 return static_cast<const TemplateArgumentLoc *>(data[0]);
1861 }
1862 const TemplateArgumentLoc *end() {
1863 return static_cast<const TemplateArgumentLoc *>(data[1]);
1864 }
1865};
Guy Benyei11169dd2012-12-18 14:30:41 +00001866class DeclVisit : public VisitorJob {
1867public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001868 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1869 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1870 isFirst ? (void *)1 : (void *)nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001871 static bool classof(const VisitorJob *VJ) {
1872 return VJ->getKind() == DeclVisitKind;
1873 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001874 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001875 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001876};
1877class TypeLocVisit : public VisitorJob {
1878public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001879 TypeLocVisit(TypeLoc tl, CXCursor parent)
1880 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1881 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001882
1883 static bool classof(const VisitorJob *VJ) {
1884 return VJ->getKind() == TypeLocVisitKind;
1885 }
1886
Michael Kruse7520cf02020-03-25 09:26:14 -05001887 TypeLoc get() const {
Guy Benyei11169dd2012-12-18 14:30:41 +00001888 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 }
1891};
1892
1893class LabelRefVisit : public VisitorJob {
1894public:
1895 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001896 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1897 labelLoc.getPtrEncoding()) {}
1898
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 static bool classof(const VisitorJob *VJ) {
1900 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1901 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902 const LabelDecl *get() const {
1903 return static_cast<const LabelDecl *>(data[0]);
1904 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001905 SourceLocation getLoc() const {
1906 return SourceLocation::getFromPtrEncoding(data[1]);
1907 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001908};
Michael Kruse7520cf02020-03-25 09:26:14 -05001909
Guy Benyei11169dd2012-12-18 14:30:41 +00001910class NestedNameSpecifierLocVisit : public VisitorJob {
1911public:
1912 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001913 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1914 Qualifier.getNestedNameSpecifier(),
1915 Qualifier.getOpaqueData()) {}
1916
Guy Benyei11169dd2012-12-18 14:30:41 +00001917 static bool classof(const VisitorJob *VJ) {
1918 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1919 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001920
Guy Benyei11169dd2012-12-18 14:30:41 +00001921 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001922 return NestedNameSpecifierLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001923 const_cast<NestedNameSpecifier *>(
1924 static_cast<const NestedNameSpecifier *>(data[0])),
1925 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001926 }
1927};
Michael Kruse7520cf02020-03-25 09:26:14 -05001928
Guy Benyei11169dd2012-12-18 14:30:41 +00001929class DeclarationNameInfoVisit : public VisitorJob {
1930public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001931 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001932 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001933 static bool classof(const VisitorJob *VJ) {
1934 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1935 }
1936 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001937 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001938 switch (S->getStmtClass()) {
1939 default:
1940 llvm_unreachable("Unhandled Stmt");
1941 case clang::Stmt::MSDependentExistsStmtClass:
1942 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1943 case Stmt::CXXDependentScopeMemberExprClass:
1944 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1945 case Stmt::DependentScopeDeclRefExprClass:
1946 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001947 case Stmt::OMPCriticalDirectiveClass:
1948 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001949 }
1950 }
1951};
1952class MemberRefVisit : public VisitorJob {
1953public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001954 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001955 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1956 L.getPtrEncoding()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001957 static bool classof(const VisitorJob *VJ) {
1958 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1959 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001960 const FieldDecl *get() const {
1961 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001962 }
1963 SourceLocation getLoc() const {
Michael Kruse7520cf02020-03-25 09:26:14 -05001964 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001965 }
1966};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001967class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001968 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001969 VisitorWorkList &WL;
1970 CXCursor Parent;
Michael Kruse7520cf02020-03-25 09:26:14 -05001971
Guy Benyei11169dd2012-12-18 14:30:41 +00001972public:
1973 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001974 : WL(wl), Parent(parent) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001975
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1977 void VisitBlockExpr(const BlockExpr *B);
1978 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1979 void VisitCompoundStmt(const CompoundStmt *S);
Michael Kruse7520cf02020-03-25 09:26:14 -05001980 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
1981 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1983 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1984 void VisitCXXNewExpr(const CXXNewExpr *E);
1985 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1986 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1987 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1988 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1989 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1990 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1991 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1992 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001993 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001994 void VisitDeclRefExpr(const DeclRefExpr *D);
1995 void VisitDeclStmt(const DeclStmt *S);
1996 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1997 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1998 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1999 void VisitForStmt(const ForStmt *FS);
2000 void VisitGotoStmt(const GotoStmt *GS);
2001 void VisitIfStmt(const IfStmt *If);
2002 void VisitInitListExpr(const InitListExpr *IE);
2003 void VisitMemberExpr(const MemberExpr *M);
2004 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2005 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2006 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2007 void VisitOverloadExpr(const OverloadExpr *E);
2008 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2009 void VisitStmt(const Stmt *S);
2010 void VisitSwitchStmt(const SwitchStmt *S);
2011 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002012 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2013 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2014 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2015 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2016 void VisitVAArgExpr(const VAArgExpr *E);
2017 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2018 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2019 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2020 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002021 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00002022 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002023 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002024 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002025 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00002026 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002027 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002028 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002029 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00002030 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002031 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002032 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002033 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
cchen47d60942019-12-05 13:43:48 -05002034 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002035 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002036 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00002037 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002038 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00002039 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002040 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002041 void
2042 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00002043 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00002044 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataevc112e942020-02-28 09:52:15 -05002045 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002046 void VisitOMPScanDirective(const OMPScanDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002047 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00002048 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002049 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00002050 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00002051 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00002052 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002053 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002054 void
2055 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00002056 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00002057 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002058 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Alexey Bataev60e51c42019-10-10 20:13:02 +00002059 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002060 void
2061 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002062 void VisitOMPParallelMasterTaskLoopDirective(
2063 const OMPParallelMasterTaskLoopDirective *D);
Alexey Bataev14a388f2019-10-25 10:27:13 -04002064 void VisitOMPParallelMasterTaskLoopSimdDirective(
2065 const OMPParallelMasterTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002066 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002067 void VisitOMPDistributeParallelForDirective(
2068 const OMPDistributeParallelForDirective *D);
Kelvin Li4a39add2016-07-05 05:00:15 +00002069 void VisitOMPDistributeParallelForSimdDirective(
2070 const OMPDistributeParallelForSimdDirective *D);
Kelvin Li787f3fc2016-07-06 04:45:38 +00002071 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
Kelvin Lia579b912016-07-14 02:54:56 +00002072 void VisitOMPTargetParallelForSimdDirective(
2073 const OMPTargetParallelForSimdDirective *D);
Kelvin Li986330c2016-07-20 22:57:10 +00002074 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
Kelvin Li02532872016-08-05 14:37:37 +00002075 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
Kelvin Li4e325f72016-10-25 12:50:55 +00002076 void VisitOMPTeamsDistributeSimdDirective(
2077 const OMPTeamsDistributeSimdDirective *D);
Kelvin Li579e41c2016-11-30 23:51:03 +00002078 void VisitOMPTeamsDistributeParallelForSimdDirective(
2079 const OMPTeamsDistributeParallelForSimdDirective *D);
Kelvin Li7ade93f2016-12-09 03:24:30 +00002080 void VisitOMPTeamsDistributeParallelForDirective(
2081 const OMPTeamsDistributeParallelForDirective *D);
Kelvin Libf594a52016-12-17 05:48:59 +00002082 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
Kelvin Li83c451e2016-12-25 04:52:54 +00002083 void VisitOMPTargetTeamsDistributeDirective(
2084 const OMPTargetTeamsDistributeDirective *D);
Kelvin Li80e8f562016-12-29 22:16:30 +00002085 void VisitOMPTargetTeamsDistributeParallelForDirective(
2086 const OMPTargetTeamsDistributeParallelForDirective *D);
Kelvin Li1851df52017-01-03 05:23:48 +00002087 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2088 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
Kelvin Lida681182017-01-10 18:08:18 +00002089 void VisitOMPTargetTeamsDistributeSimdDirective(
2090 const OMPTargetTeamsDistributeSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002091
Guy Benyei11169dd2012-12-18 14:30:41 +00002092private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00002095 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2096 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2098 void AddStmt(const Stmt *S);
2099 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002100 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002101 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002102 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002103};
Michael Kruse7520cf02020-03-25 09:26:14 -05002104} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00002105
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002106void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002107 // 'S' should always be non-null, since it comes from the
2108 // statement we are visiting.
2109 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2110}
2111
Michael Kruse7520cf02020-03-25 09:26:14 -05002112void EnqueueVisitor::AddNestedNameSpecifierLoc(
2113 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002114 if (Qualifier)
2115 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2116}
2117
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 if (S)
2120 WL.push_back(StmtVisit(S, Parent));
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 if (D)
2124 WL.push_back(DeclVisit(D, Parent, isFirst));
2125}
James Y Knight04ec5bf2015-12-24 02:59:37 +00002126void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2127 unsigned NumTemplateArgs) {
2128 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 if (D)
2132 WL.push_back(MemberRefVisit(D, L, Parent));
2133}
2134void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2135 if (TI)
2136 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002137}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002140 for (const Stmt *SubStmt : S->children()) {
2141 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 }
2143 if (size == WL.size())
2144 return;
2145 // Now reverse the entries we just added. This will match the DFS
2146 // ordering performed by the worklist.
2147 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2148 std::reverse(I, E);
2149}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002150namespace {
2151class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2152 EnqueueVisitor *Visitor;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002153 /// Process clauses with list of variables.
Michael Kruse7520cf02020-03-25 09:26:14 -05002154 template <typename T> void VisitOMPClauseList(T *Node);
2155
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002156public:
Michael Kruse7520cf02020-03-25 09:26:14 -05002157 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
Johannes Doerfert419a5592020-03-30 19:58:40 -05002158#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2159#include "llvm/Frontend/OpenMP/OMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002160 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002161 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002162};
2163
Alexey Bataev3392d762016-02-16 11:18:12 +00002164void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2165 const OMPClauseWithPreInit *C) {
2166 Visitor->AddStmt(C->getPreInitStmt());
2167}
2168
Alexey Bataev005248a2016-02-25 05:25:57 +00002169void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2170 const OMPClauseWithPostUpdate *C) {
Alexey Bataev37e594c2016-03-04 07:21:16 +00002171 VisitOMPClauseWithPreInit(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002172 Visitor->AddStmt(C->getPostUpdateExpr());
2173}
2174
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002175void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00002176 VisitOMPClauseWithPreInit(C);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002177 Visitor->AddStmt(C->getCondition());
2178}
2179
Alexey Bataev3778b602014-07-17 07:32:53 +00002180void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2181 Visitor->AddStmt(C->getCondition());
2182}
2183
Alexey Bataev568a8332014-03-06 06:15:19 +00002184void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00002185 VisitOMPClauseWithPreInit(C);
Alexey Bataev568a8332014-03-06 06:15:19 +00002186 Visitor->AddStmt(C->getNumThreads());
2187}
2188
Alexey Bataev62c87d22014-03-21 04:51:18 +00002189void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2190 Visitor->AddStmt(C->getSafelen());
2191}
2192
Alexey Bataev66b15b52015-08-21 11:14:16 +00002193void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2194 Visitor->AddStmt(C->getSimdlen());
2195}
2196
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002197void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2198 Visitor->AddStmt(C->getAllocator());
2199}
2200
Alexander Musman8bd31e62014-05-27 15:12:19 +00002201void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2202 Visitor->AddStmt(C->getNumForLoops());
2203}
2204
Michael Kruse7520cf02020-03-25 09:26:14 -05002205void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
Alexey Bataev756c1962013-09-24 03:17:45 +00002206
Michael Kruse7520cf02020-03-25 09:26:14 -05002207void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002208
Alexey Bataev56dafe82014-06-20 07:16:17 +00002209void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002210 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002211 Visitor->AddStmt(C->getChunkSize());
2212}
2213
Alexey Bataev10e775f2015-07-30 11:36:16 +00002214void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2215 Visitor->AddStmt(C->getNumForLoops());
2216}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002217
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002218void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2219 Visitor->AddStmt(C->getEventHandler());
2220}
2221
Alexey Bataev236070f2014-06-20 11:19:47 +00002222void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2223
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002224void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2225
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002226void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2227
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002228void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2229
Alexey Bataevdea47612014-07-23 07:46:59 +00002230void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2231
Alexey Bataev67a4f222014-07-23 10:25:33 +00002232void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2233
Alexey Bataev459dec02014-07-24 06:46:57 +00002234void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2235
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002236void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2237
Alexey Bataevea9166b2020-02-06 16:30:23 -05002238void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2239
Alexey Bataev04a830f2020-02-10 14:30:39 -05002240void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2241
Alexey Bataev95598342020-02-10 15:49:05 -05002242void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2243
Alexey Bataev9a8defc2020-02-11 11:10:43 -05002244void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2245
Alexey Bataev346265e2015-09-25 10:37:12 +00002246void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2247
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002248void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2249
Alexey Bataevb825de12015-12-07 10:51:44 +00002250void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2251
Alexey Bataev375437a2020-03-02 14:21:20 -05002252void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {}
2253
Kelvin Li1408f912018-09-26 04:28:39 +00002254void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2255 const OMPUnifiedAddressClause *) {}
2256
Patrick Lyster4a370b92018-10-01 13:47:43 +00002257void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2258 const OMPUnifiedSharedMemoryClause *) {}
2259
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00002260void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2261 const OMPReverseOffloadClause *) {}
2262
Patrick Lyster3fe9e392018-10-11 14:41:10 +00002263void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2264 const OMPDynamicAllocatorsClause *) {}
2265
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002266void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2267 const OMPAtomicDefaultMemOrderClause *) {}
2268
Michael Wonge710d542015-08-07 16:16:36 +00002269void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2270 Visitor->AddStmt(C->getDevice());
2271}
2272
Kelvin Li099bb8c2015-11-24 20:50:12 +00002273void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00002274 VisitOMPClauseWithPreInit(C);
Kelvin Li099bb8c2015-11-24 20:50:12 +00002275 Visitor->AddStmt(C->getNumTeams());
2276}
2277
Michael Kruse7520cf02020-03-25 09:26:14 -05002278void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2279 const OMPThreadLimitClause *C) {
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00002280 VisitOMPClauseWithPreInit(C);
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002281 Visitor->AddStmt(C->getThreadLimit());
2282}
2283
Alexey Bataeva0569352015-12-01 10:17:31 +00002284void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2285 Visitor->AddStmt(C->getPriority());
2286}
2287
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002288void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2289 Visitor->AddStmt(C->getGrainsize());
2290}
2291
Alexey Bataev382967a2015-12-08 12:06:20 +00002292void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2293 Visitor->AddStmt(C->getNumTasks());
2294}
2295
Alexey Bataev28c75412015-12-15 08:19:24 +00002296void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2297 Visitor->AddStmt(C->getHint());
2298}
2299
Michael Kruse7520cf02020-03-25 09:26:14 -05002300template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002301 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002302 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002303 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002304}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002305
Alexey Bataev06dea732020-03-20 09:41:22 -04002306void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2307 VisitOMPClauseList(C);
2308}
Alexey Bataev63828a32020-03-23 10:41:08 -04002309void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2310 VisitOMPClauseList(C);
2311}
Alexey Bataeve04483e2019-03-27 14:14:31 +00002312void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2313 VisitOMPClauseList(C);
2314 Visitor->AddStmt(C->getAllocator());
2315}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002316void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002317 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002318 for (const auto *E : C->private_copies()) {
2319 Visitor->AddStmt(E);
2320 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002321}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002322void OMPClauseEnqueue::VisitOMPFirstprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002323 const OMPFirstprivateClause *C) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002324 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002325 VisitOMPClauseWithPreInit(C);
2326 for (const auto *E : C->private_copies()) {
2327 Visitor->AddStmt(E);
2328 }
2329 for (const auto *E : C->inits()) {
2330 Visitor->AddStmt(E);
2331 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002332}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002333void OMPClauseEnqueue::VisitOMPLastprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002334 const OMPLastprivateClause *C) {
Alexander Musman1bb328c2014-06-04 13:06:39 +00002335 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002336 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002337 for (auto *E : C->private_copies()) {
2338 Visitor->AddStmt(E);
2339 }
2340 for (auto *E : C->source_exprs()) {
2341 Visitor->AddStmt(E);
2342 }
2343 for (auto *E : C->destination_exprs()) {
2344 Visitor->AddStmt(E);
2345 }
2346 for (auto *E : C->assignment_ops()) {
2347 Visitor->AddStmt(E);
2348 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002349}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002350void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002351 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002352}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002353void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2354 VisitOMPClauseList(C);
Alexey Bataev61205072016-03-02 04:57:40 +00002355 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002356 for (auto *E : C->privates()) {
2357 Visitor->AddStmt(E);
2358 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002359 for (auto *E : C->lhs_exprs()) {
2360 Visitor->AddStmt(E);
2361 }
2362 for (auto *E : C->rhs_exprs()) {
2363 Visitor->AddStmt(E);
2364 }
2365 for (auto *E : C->reduction_ops()) {
2366 Visitor->AddStmt(E);
2367 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002368}
Alexey Bataev169d96a2017-07-18 20:17:46 +00002369void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2370 const OMPTaskReductionClause *C) {
2371 VisitOMPClauseList(C);
2372 VisitOMPClauseWithPostUpdate(C);
2373 for (auto *E : C->privates()) {
2374 Visitor->AddStmt(E);
2375 }
2376 for (auto *E : C->lhs_exprs()) {
2377 Visitor->AddStmt(E);
2378 }
2379 for (auto *E : C->rhs_exprs()) {
2380 Visitor->AddStmt(E);
2381 }
2382 for (auto *E : C->reduction_ops()) {
2383 Visitor->AddStmt(E);
2384 }
2385}
Alexey Bataevfa312f32017-07-21 18:48:21 +00002386void OMPClauseEnqueue::VisitOMPInReductionClause(
2387 const OMPInReductionClause *C) {
2388 VisitOMPClauseList(C);
2389 VisitOMPClauseWithPostUpdate(C);
2390 for (auto *E : C->privates()) {
2391 Visitor->AddStmt(E);
2392 }
2393 for (auto *E : C->lhs_exprs()) {
2394 Visitor->AddStmt(E);
2395 }
2396 for (auto *E : C->rhs_exprs()) {
2397 Visitor->AddStmt(E);
2398 }
2399 for (auto *E : C->reduction_ops()) {
2400 Visitor->AddStmt(E);
2401 }
Alexey Bataev88202be2017-07-27 13:20:36 +00002402 for (auto *E : C->taskgroup_descriptors())
2403 Visitor->AddStmt(E);
Alexey Bataevfa312f32017-07-21 18:48:21 +00002404}
Alexander Musman8dba6642014-04-22 13:09:42 +00002405void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2406 VisitOMPClauseList(C);
Alexey Bataev78849fb2016-03-09 09:49:00 +00002407 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002408 for (const auto *E : C->privates()) {
2409 Visitor->AddStmt(E);
2410 }
Alexander Musman3276a272015-03-21 10:12:56 +00002411 for (const auto *E : C->inits()) {
2412 Visitor->AddStmt(E);
2413 }
2414 for (const auto *E : C->updates()) {
2415 Visitor->AddStmt(E);
2416 }
2417 for (const auto *E : C->finals()) {
2418 Visitor->AddStmt(E);
2419 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002420 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002421 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002422}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002423void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2424 VisitOMPClauseList(C);
2425 Visitor->AddStmt(C->getAlignment());
2426}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002427void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2428 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002429 for (auto *E : C->source_exprs()) {
2430 Visitor->AddStmt(E);
2431 }
2432 for (auto *E : C->destination_exprs()) {
2433 Visitor->AddStmt(E);
2434 }
2435 for (auto *E : C->assignment_ops()) {
2436 Visitor->AddStmt(E);
2437 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002438}
Michael Kruse7520cf02020-03-25 09:26:14 -05002439void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2440 const OMPCopyprivateClause *C) {
Alexey Bataevbae9a792014-06-27 10:37:06 +00002441 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002442 for (auto *E : C->source_exprs()) {
2443 Visitor->AddStmt(E);
2444 }
2445 for (auto *E : C->destination_exprs()) {
2446 Visitor->AddStmt(E);
2447 }
2448 for (auto *E : C->assignment_ops()) {
2449 Visitor->AddStmt(E);
2450 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002451}
Alexey Bataev6125da92014-07-21 11:26:11 +00002452void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2453 VisitOMPClauseList(C);
2454}
Alexey Bataevc112e942020-02-28 09:52:15 -05002455void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2456 Visitor->AddStmt(C->getDepobj());
2457}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002458void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2459 VisitOMPClauseList(C);
2460}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002461void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2462 VisitOMPClauseList(C);
2463}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002464void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2465 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002466 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002467 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002468}
Alexey Bataev3392d762016-02-16 11:18:12 +00002469void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2470 const OMPDefaultmapClause * /*C*/) {}
Samuel Antao661c0902016-05-26 17:39:58 +00002471void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2472 VisitOMPClauseList(C);
2473}
Samuel Antaoec172c62016-05-26 17:49:04 +00002474void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2475 VisitOMPClauseList(C);
2476}
Michael Kruse7520cf02020-03-25 09:26:14 -05002477void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2478 const OMPUseDevicePtrClause *C) {
Carlo Bertolli2404b172016-07-13 15:37:16 +00002479 VisitOMPClauseList(C);
2480}
Michael Kruse7520cf02020-03-25 09:26:14 -05002481void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2482 const OMPIsDevicePtrClause *C) {
Carlo Bertolli70594e92016-07-13 17:16:49 +00002483 VisitOMPClauseList(C);
2484}
Alexey Bataevb6e70842019-12-16 15:54:17 -05002485void OMPClauseEnqueue::VisitOMPNontemporalClause(
2486 const OMPNontemporalClause *C) {
2487 VisitOMPClauseList(C);
Alexey Bataev0860db92019-12-19 10:01:10 -05002488 for (const auto *E : C->private_refs())
2489 Visitor->AddStmt(E);
Alexey Bataevb6e70842019-12-16 15:54:17 -05002490}
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002491void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
Michael Kruse7520cf02020-03-25 09:26:14 -05002492} // namespace
Alexey Bataev756c1962013-09-24 03:17:45 +00002493
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002494void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2495 unsigned size = WL.size();
2496 OMPClauseEnqueue Visitor(this);
2497 Visitor.Visit(S);
2498 if (size == WL.size())
2499 return;
2500 // Now reverse the entries we just added. This will match the DFS
2501 // ordering performed by the worklist.
2502 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2503 std::reverse(I, E);
2504}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002505void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002506 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2507}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002508void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002509 AddDecl(B->getBlockDecl());
2510}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002511void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002512 EnqueueChildren(E);
2513 AddTypeLoc(E->getTypeSourceInfo());
2514}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002515void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002516 for (auto &I : llvm::reverse(S->body()))
2517 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002518}
Michael Kruse7520cf02020-03-25 09:26:14 -05002519void EnqueueVisitor::VisitMSDependentExistsStmt(
2520 const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002521 AddStmt(S->getSubStmt());
2522 AddDeclarationNameInfo(S);
2523 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2524 AddNestedNameSpecifierLoc(QualifierLoc);
2525}
2526
Michael Kruse7520cf02020-03-25 09:26:14 -05002527void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2528 const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002529 if (E->hasExplicitTemplateArgs())
2530 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002531 AddDeclarationNameInfo(E);
2532 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2533 AddNestedNameSpecifierLoc(QualifierLoc);
2534 if (!E->isImplicitAccess())
2535 AddStmt(E->getBase());
2536}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002537void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002538 // Enqueue the initializer , if any.
2539 AddStmt(E->getInitializer());
2540 // Enqueue the array size, if any.
Richard Smithb9fb1212019-05-06 03:47:15 +00002541 AddStmt(E->getArraySize().getValueOr(nullptr));
Guy Benyei11169dd2012-12-18 14:30:41 +00002542 // Enqueue the allocated type.
2543 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2544 // Enqueue the placement arguments.
2545 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002546 AddStmt(E->getPlacementArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002547}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002548void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002549 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002550 AddStmt(CE->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002551 AddStmt(CE->getCallee());
2552 AddStmt(CE->getArg(0));
2553}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002554void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002555 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002556 // Visit the name of the type being destroyed.
2557 AddTypeLoc(E->getDestroyedTypeInfo());
2558 // Visit the scope type that looks disturbingly like the nested-name-specifier
2559 // but isn't.
2560 AddTypeLoc(E->getScopeTypeInfo());
2561 // Visit the nested-name-specifier.
2562 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2563 AddNestedNameSpecifierLoc(QualifierLoc);
2564 // Visit base expression.
2565 AddStmt(E->getBase());
2566}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002567void EnqueueVisitor::VisitCXXScalarValueInitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002568 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002569 AddTypeLoc(E->getTypeSourceInfo());
2570}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002571void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002572 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002573 EnqueueChildren(E);
2574 AddTypeLoc(E->getTypeSourceInfo());
2575}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002576void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002577 EnqueueChildren(E);
2578 if (E->isTypeOperand())
2579 AddTypeLoc(E->getTypeOperandSourceInfo());
2580}
2581
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002582void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002583 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002584 EnqueueChildren(E);
2585 AddTypeLoc(E->getTypeSourceInfo());
2586}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002587void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002588 EnqueueChildren(E);
2589 if (E->isTypeOperand())
2590 AddTypeLoc(E->getTypeOperandSourceInfo());
2591}
2592
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002593void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002594 EnqueueChildren(S);
2595 AddDecl(S->getExceptionDecl());
2596}
2597
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002598void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002599 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002600 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002601 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002602}
2603
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002604void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002605 if (DR->hasExplicitTemplateArgs())
2606 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002607 WL.push_back(DeclRefExprParts(DR, Parent));
2608}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002609void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002610 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002611 if (E->hasExplicitTemplateArgs())
2612 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002613 AddDeclarationNameInfo(E);
2614 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2615}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002616void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002617 unsigned size = WL.size();
2618 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002619 for (const auto *D : S->decls()) {
2620 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002621 isFirst = false;
2622 }
2623 if (size == WL.size())
2624 return;
2625 // Now reverse the entries we just added. This will match the DFS
2626 // ordering performed by the worklist.
2627 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2628 std::reverse(I, E);
2629}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002630void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002631 AddStmt(E->getInit());
David Majnemerf7e36092016-06-23 00:15:04 +00002632 for (const DesignatedInitExpr::Designator &D :
2633 llvm::reverse(E->designators())) {
2634 if (D.isFieldDesignator()) {
2635 if (FieldDecl *Field = D.getField())
2636 AddMemberRef(Field, D.getFieldLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00002637 continue;
2638 }
David Majnemerf7e36092016-06-23 00:15:04 +00002639 if (D.isArrayDesignator()) {
2640 AddStmt(E->getArrayIndex(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002641 continue;
2642 }
David Majnemerf7e36092016-06-23 00:15:04 +00002643 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2644 AddStmt(E->getArrayRangeEnd(D));
2645 AddStmt(E->getArrayRangeStart(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002646 }
2647}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002648void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002649 EnqueueChildren(E);
2650 AddTypeLoc(E->getTypeInfoAsWritten());
2651}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002652void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002653 AddStmt(FS->getBody());
2654 AddStmt(FS->getInc());
2655 AddStmt(FS->getCond());
2656 AddDecl(FS->getConditionVariable());
2657 AddStmt(FS->getInit());
2658}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002659void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002660 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2661}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002662void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002663 AddStmt(If->getElse());
2664 AddStmt(If->getThen());
2665 AddStmt(If->getCond());
2666 AddDecl(If->getConditionVariable());
2667}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002668void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002669 // We care about the syntactic form of the initializer list, only.
2670 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2671 IE = Syntactic;
2672 EnqueueChildren(IE);
2673}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002674void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002675 WL.push_back(MemberExprParts(M, Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002676
Guy Benyei11169dd2012-12-18 14:30:41 +00002677 // If the base of the member access expression is an implicit 'this', don't
2678 // visit it.
2679 // FIXME: If we ever want to show these implicit accesses, this will be
2680 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002681 if (M->isImplicitAccess())
2682 return;
2683
2684 // Ignore base anonymous struct/union fields, otherwise they will shadow the
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00002685 // real field that we are interested in.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002686 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2687 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2688 if (FD->isAnonymousStructOrUnion()) {
2689 AddStmt(SubME->getBase());
2690 return;
2691 }
2692 }
2693 }
2694
2695 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002696}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002697void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 AddTypeLoc(E->getEncodedTypeSourceInfo());
2699}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002700void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 EnqueueChildren(M);
2702 AddTypeLoc(M->getClassReceiverTypeInfo());
2703}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002704void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002705 // Visit the components of the offsetof expression.
2706 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Michael Kruse7520cf02020-03-25 09:26:14 -05002707 const OffsetOfNode &Node = E->getComponent(I - 1);
Guy Benyei11169dd2012-12-18 14:30:41 +00002708 switch (Node.getKind()) {
2709 case OffsetOfNode::Array:
2710 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2711 break;
2712 case OffsetOfNode::Field:
2713 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2714 break;
2715 case OffsetOfNode::Identifier:
2716 case OffsetOfNode::Base:
2717 continue;
2718 }
2719 }
2720 // Visit the type into which we're computing the offset.
2721 AddTypeLoc(E->getTypeSourceInfo());
2722}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002723void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002724 if (E->hasExplicitTemplateArgs())
2725 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002726 WL.push_back(OverloadExprParts(E, Parent));
2727}
2728void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002729 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002730 EnqueueChildren(E);
2731 if (E->isArgumentType())
2732 AddTypeLoc(E->getArgumentTypeInfo());
2733}
Michael Kruse7520cf02020-03-25 09:26:14 -05002734void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002735void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002736 AddStmt(S->getBody());
2737 AddStmt(S->getCond());
2738 AddDecl(S->getConditionVariable());
2739}
2740
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002741void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002742 AddStmt(W->getBody());
2743 AddStmt(W->getCond());
2744 AddDecl(W->getConditionVariable());
2745}
2746
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002747void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 for (unsigned I = E->getNumArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002749 AddTypeLoc(E->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002750}
2751
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002752void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002753 AddTypeLoc(E->getQueriedTypeSourceInfo());
2754}
2755
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002756void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002757 EnqueueChildren(E);
2758}
2759
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002760void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002761 VisitOverloadExpr(U);
2762 if (!U->isImplicitAccess())
2763 AddStmt(U->getBase());
2764}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002765void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002766 AddStmt(E->getSubExpr());
2767 AddTypeLoc(E->getWrittenTypeInfo());
2768}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002769void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002770 WL.push_back(SizeOfPackExprParts(E, Parent));
2771}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002772void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002773 // If the opaque value has a source expression, just transparently
2774 // visit that. This is useful for (e.g.) pseudo-object expressions.
2775 if (Expr *SourceExpr = E->getSourceExpr())
2776 return Visit(SourceExpr);
2777}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002778void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002779 AddStmt(E->getBody());
2780 WL.push_back(LambdaExprParts(E, Parent));
2781}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002782void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002783 // Treat the expression like its syntactic form.
2784 Visit(E->getSyntacticForm());
2785}
2786
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002787void EnqueueVisitor::VisitOMPExecutableDirective(
Michael Kruse7520cf02020-03-25 09:26:14 -05002788 const OMPExecutableDirective *D) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002789 EnqueueChildren(D);
2790 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2791 E = D->clauses().end();
2792 I != E; ++I)
2793 EnqueueChildren(*I);
2794}
2795
Alexander Musman3aaab662014-08-19 11:27:13 +00002796void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2797 VisitOMPExecutableDirective(D);
2798}
2799
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002800void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2801 VisitOMPExecutableDirective(D);
2802}
2803
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002804void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002805 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002806}
2807
Alexey Bataevf29276e2014-06-18 04:14:57 +00002808void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002809 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002810}
2811
Alexander Musmanf82886e2014-09-18 05:12:34 +00002812void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2813 VisitOMPLoopDirective(D);
2814}
2815
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002816void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2817 VisitOMPExecutableDirective(D);
2818}
2819
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002820void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2821 VisitOMPExecutableDirective(D);
2822}
2823
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002824void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2825 VisitOMPExecutableDirective(D);
2826}
2827
Alexander Musman80c22892014-07-17 08:54:58 +00002828void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2829 VisitOMPExecutableDirective(D);
2830}
2831
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002832void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2833 VisitOMPExecutableDirective(D);
2834 AddDeclarationNameInfo(D);
2835}
2836
Michael Kruse7520cf02020-03-25 09:26:14 -05002837void EnqueueVisitor::VisitOMPParallelForDirective(
2838 const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002839 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002840}
2841
Alexander Musmane4e893b2014-09-23 09:33:00 +00002842void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2843 const OMPParallelForSimdDirective *D) {
2844 VisitOMPLoopDirective(D);
2845}
2846
cchen47d60942019-12-05 13:43:48 -05002847void EnqueueVisitor::VisitOMPParallelMasterDirective(
2848 const OMPParallelMasterDirective *D) {
2849 VisitOMPExecutableDirective(D);
2850}
2851
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002852void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2853 const OMPParallelSectionsDirective *D) {
2854 VisitOMPExecutableDirective(D);
2855}
2856
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002857void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2858 VisitOMPExecutableDirective(D);
2859}
2860
Michael Kruse7520cf02020-03-25 09:26:14 -05002861void EnqueueVisitor::VisitOMPTaskyieldDirective(
2862 const OMPTaskyieldDirective *D) {
Alexey Bataev68446b72014-07-18 07:47:19 +00002863 VisitOMPExecutableDirective(D);
2864}
2865
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002866void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2867 VisitOMPExecutableDirective(D);
2868}
2869
Alexey Bataev2df347a2014-07-18 10:17:07 +00002870void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2871 VisitOMPExecutableDirective(D);
2872}
2873
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002874void EnqueueVisitor::VisitOMPTaskgroupDirective(
2875 const OMPTaskgroupDirective *D) {
2876 VisitOMPExecutableDirective(D);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00002877 if (const Expr *E = D->getReductionRef())
2878 VisitStmt(E);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002879}
2880
Alexey Bataev6125da92014-07-21 11:26:11 +00002881void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2882 VisitOMPExecutableDirective(D);
2883}
2884
Alexey Bataevc112e942020-02-28 09:52:15 -05002885void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
2886 VisitOMPExecutableDirective(D);
2887}
2888
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002889void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
2890 VisitOMPExecutableDirective(D);
2891}
2892
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002893void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2894 VisitOMPExecutableDirective(D);
2895}
2896
Alexey Bataev0162e452014-07-22 10:10:35 +00002897void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2898 VisitOMPExecutableDirective(D);
2899}
2900
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002901void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2902 VisitOMPExecutableDirective(D);
2903}
2904
Alexey Bataevc112e942020-02-28 09:52:15 -05002905void EnqueueVisitor::VisitOMPTargetDataDirective(
2906 const OMPTargetDataDirective *D) {
Michael Wong65f367f2015-07-21 13:44:28 +00002907 VisitOMPExecutableDirective(D);
2908}
2909
Samuel Antaodf67fc42016-01-19 19:15:56 +00002910void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2911 const OMPTargetEnterDataDirective *D) {
2912 VisitOMPExecutableDirective(D);
2913}
2914
Samuel Antao72590762016-01-19 20:04:50 +00002915void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2916 const OMPTargetExitDataDirective *D) {
2917 VisitOMPExecutableDirective(D);
2918}
2919
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002920void EnqueueVisitor::VisitOMPTargetParallelDirective(
2921 const OMPTargetParallelDirective *D) {
2922 VisitOMPExecutableDirective(D);
2923}
2924
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002925void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2926 const OMPTargetParallelForDirective *D) {
2927 VisitOMPLoopDirective(D);
2928}
2929
Alexey Bataev13314bf2014-10-09 04:18:56 +00002930void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2931 VisitOMPExecutableDirective(D);
2932}
2933
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002934void EnqueueVisitor::VisitOMPCancellationPointDirective(
2935 const OMPCancellationPointDirective *D) {
2936 VisitOMPExecutableDirective(D);
2937}
2938
Alexey Bataev80909872015-07-02 11:25:17 +00002939void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2940 VisitOMPExecutableDirective(D);
2941}
2942
Alexey Bataev49f6e782015-12-01 04:18:41 +00002943void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2944 VisitOMPLoopDirective(D);
2945}
2946
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002947void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2948 const OMPTaskLoopSimdDirective *D) {
2949 VisitOMPLoopDirective(D);
2950}
2951
Alexey Bataev60e51c42019-10-10 20:13:02 +00002952void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
2953 const OMPMasterTaskLoopDirective *D) {
2954 VisitOMPLoopDirective(D);
2955}
2956
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002957void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
2958 const OMPMasterTaskLoopSimdDirective *D) {
2959 VisitOMPLoopDirective(D);
2960}
2961
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002962void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
2963 const OMPParallelMasterTaskLoopDirective *D) {
2964 VisitOMPLoopDirective(D);
2965}
2966
Alexey Bataev14a388f2019-10-25 10:27:13 -04002967void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
2968 const OMPParallelMasterTaskLoopSimdDirective *D) {
2969 VisitOMPLoopDirective(D);
2970}
2971
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002972void EnqueueVisitor::VisitOMPDistributeDirective(
2973 const OMPDistributeDirective *D) {
2974 VisitOMPLoopDirective(D);
2975}
2976
Carlo Bertolli9925f152016-06-27 14:55:37 +00002977void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
2978 const OMPDistributeParallelForDirective *D) {
2979 VisitOMPLoopDirective(D);
2980}
2981
Kelvin Li4a39add2016-07-05 05:00:15 +00002982void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
2983 const OMPDistributeParallelForSimdDirective *D) {
2984 VisitOMPLoopDirective(D);
2985}
2986
Kelvin Li787f3fc2016-07-06 04:45:38 +00002987void EnqueueVisitor::VisitOMPDistributeSimdDirective(
2988 const OMPDistributeSimdDirective *D) {
2989 VisitOMPLoopDirective(D);
2990}
2991
Kelvin Lia579b912016-07-14 02:54:56 +00002992void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
2993 const OMPTargetParallelForSimdDirective *D) {
2994 VisitOMPLoopDirective(D);
2995}
2996
Kelvin Li986330c2016-07-20 22:57:10 +00002997void EnqueueVisitor::VisitOMPTargetSimdDirective(
2998 const OMPTargetSimdDirective *D) {
2999 VisitOMPLoopDirective(D);
3000}
3001
Kelvin Li02532872016-08-05 14:37:37 +00003002void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3003 const OMPTeamsDistributeDirective *D) {
3004 VisitOMPLoopDirective(D);
3005}
3006
Kelvin Li4e325f72016-10-25 12:50:55 +00003007void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3008 const OMPTeamsDistributeSimdDirective *D) {
3009 VisitOMPLoopDirective(D);
3010}
3011
Kelvin Li579e41c2016-11-30 23:51:03 +00003012void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3013 const OMPTeamsDistributeParallelForSimdDirective *D) {
3014 VisitOMPLoopDirective(D);
3015}
3016
Kelvin Li7ade93f2016-12-09 03:24:30 +00003017void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3018 const OMPTeamsDistributeParallelForDirective *D) {
3019 VisitOMPLoopDirective(D);
3020}
3021
Kelvin Libf594a52016-12-17 05:48:59 +00003022void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3023 const OMPTargetTeamsDirective *D) {
3024 VisitOMPExecutableDirective(D);
3025}
3026
Kelvin Li83c451e2016-12-25 04:52:54 +00003027void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3028 const OMPTargetTeamsDistributeDirective *D) {
3029 VisitOMPLoopDirective(D);
3030}
3031
Kelvin Li80e8f562016-12-29 22:16:30 +00003032void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3033 const OMPTargetTeamsDistributeParallelForDirective *D) {
3034 VisitOMPLoopDirective(D);
3035}
3036
Kelvin Li1851df52017-01-03 05:23:48 +00003037void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3038 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3039 VisitOMPLoopDirective(D);
3040}
3041
Kelvin Lida681182017-01-10 18:08:18 +00003042void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3043 const OMPTargetTeamsDistributeSimdDirective *D) {
3044 VisitOMPLoopDirective(D);
3045}
3046
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003047void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003048 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3049 .Visit(S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003050}
3051
3052bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3053 if (RegionOfInterest.isValid()) {
3054 SourceRange Range = getRawCursorExtent(C);
3055 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3056 return false;
3057 }
3058 return true;
3059}
3060
3061bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3062 while (!WL.empty()) {
3063 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00003064 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00003065
3066 // Set the Parent field, then back to its old value once we're done.
3067 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
Michael Kruse7520cf02020-03-25 09:26:14 -05003068
Guy Benyei11169dd2012-12-18 14:30:41 +00003069 switch (LI.getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003070 case VisitorJob::DeclVisitKind: {
3071 const Decl *D = cast<DeclVisit>(&LI)->get();
3072 if (!D)
3073 continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00003074
Michael Kruse7520cf02020-03-25 09:26:14 -05003075 // For now, perform default visitation for Decls.
3076 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3077 cast<DeclVisit>(&LI)->isFirst())))
3078 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003079
Michael Kruse7520cf02020-03-25 09:26:14 -05003080 continue;
3081 }
3082 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3083 for (const TemplateArgumentLoc &Arg :
3084 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3085 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00003086 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003087 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003088 continue;
3089 }
3090 case VisitorJob::TypeLocVisitKind: {
3091 // Perform default visitation for TypeLocs.
3092 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3093 return true;
3094 continue;
3095 }
3096 case VisitorJob::LabelRefVisitKind: {
3097 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3098 if (LabelStmt *stmt = LS->getStmt()) {
3099 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3100 TU))) {
3101 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003102 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003103 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003104 continue;
3105 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003106
Michael Kruse7520cf02020-03-25 09:26:14 -05003107 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3108 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3109 if (VisitNestedNameSpecifierLoc(V->get()))
3110 return true;
3111 continue;
3112 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003113
Michael Kruse7520cf02020-03-25 09:26:14 -05003114 case VisitorJob::DeclarationNameInfoVisitKind: {
3115 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3116 return true;
3117 continue;
3118 }
3119 case VisitorJob::MemberRefVisitKind: {
3120 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3121 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3122 return true;
3123 continue;
3124 }
3125 case VisitorJob::StmtVisitKind: {
3126 const Stmt *S = cast<StmtVisit>(&LI)->get();
3127 if (!S)
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 continue;
Richard Smithba71c082013-05-16 06:20:58 +00003129
Michael Kruse7520cf02020-03-25 09:26:14 -05003130 // Update the current cursor.
3131 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3132 if (!IsInRegionOfInterest(Cursor))
3133 continue;
3134 switch (Visitor(Cursor, Parent, ClientData)) {
3135 case CXChildVisit_Break:
3136 return true;
3137 case CXChildVisit_Continue:
3138 break;
3139 case CXChildVisit_Recurse:
3140 if (PostChildrenVisitor)
3141 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3142 EnqueueWorkList(WL, S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 break;
3144 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003145 continue;
3146 }
3147 case VisitorJob::MemberExprPartsKind: {
3148 // Handle the other pieces in the MemberExpr besides the base.
3149 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00003150
Michael Kruse7520cf02020-03-25 09:26:14 -05003151 // Visit the nested-name-specifier
3152 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3153 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +00003154 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05003155
3156 // Visit the declaration name.
3157 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3158 return true;
3159
3160 // Visit the explicitly-specified template arguments, if any.
3161 if (M->hasExplicitTemplateArgs()) {
3162 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3163 *ArgEnd = Arg + M->getNumTemplateArgs();
3164 Arg != ArgEnd; ++Arg) {
3165 if (VisitTemplateArgumentLoc(*Arg))
3166 return true;
3167 }
3168 }
3169 continue;
3170 }
3171 case VisitorJob::DeclRefExprPartsKind: {
3172 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3173 // Visit nested-name-specifier, if present.
3174 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3175 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3176 return true;
3177 // Visit declaration name.
3178 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3179 return true;
3180 continue;
3181 }
3182 case VisitorJob::OverloadExprPartsKind: {
3183 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3184 // Visit the nested-name-specifier.
3185 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3186 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3187 return true;
3188 // Visit the declaration name.
3189 if (VisitDeclarationNameInfo(O->getNameInfo()))
3190 return true;
3191 // Visit the overloaded declaration reference.
3192 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3193 return true;
3194 continue;
3195 }
3196 case VisitorJob::SizeOfPackExprPartsKind: {
3197 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3198 NamedDecl *Pack = E->getPack();
3199 if (isa<TemplateTypeParmDecl>(Pack)) {
3200 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3201 E->getPackLoc(), TU)))
3202 return true;
3203
3204 continue;
3205 }
3206
3207 if (isa<TemplateTemplateParmDecl>(Pack)) {
3208 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3209 E->getPackLoc(), TU)))
3210 return true;
3211
3212 continue;
3213 }
3214
3215 // Non-type template parameter packs and function parameter packs are
3216 // treated like DeclRefExpr cursors.
3217 continue;
3218 }
3219
3220 case VisitorJob::LambdaExprPartsKind: {
3221 // Visit non-init captures.
3222 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3223 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3224 CEnd = E->explicit_capture_end();
3225 C != CEnd; ++C) {
3226 if (!C->capturesVariable())
3227 continue;
3228
3229 if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
3230 TU)))
3231 return true;
3232 }
3233 // Visit init captures
3234 for (auto InitExpr : E->capture_inits()) {
3235 if (Visit(InitExpr))
3236 return true;
3237 }
3238
3239 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3240 // Visit parameters and return type, if present.
3241 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3242 if (E->hasExplicitParameters()) {
3243 // Visit parameters.
3244 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3245 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3246 return true;
3247 }
3248 if (E->hasExplicitResultType()) {
3249 // Visit result type.
3250 if (Visit(Proto.getReturnLoc()))
3251 return true;
3252 }
3253 }
3254 break;
3255 }
3256
3257 case VisitorJob::PostChildrenVisitKind:
3258 if (PostChildrenVisitor(Parent, ClientData))
3259 return true;
3260 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 }
3262 }
3263 return false;
3264}
3265
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003266bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00003267 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 if (!WorkListFreeList.empty()) {
3269 WL = WorkListFreeList.back();
3270 WL->clear();
3271 WorkListFreeList.pop_back();
Michael Kruse7520cf02020-03-25 09:26:14 -05003272 } else {
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 WL = new VisitorWorkList();
3274 WorkListCache.push_back(WL);
3275 }
3276 EnqueueWorkList(*WL, S);
3277 bool result = RunVisitorWorkList(*WL);
3278 WorkListFreeList.push_back(WL);
3279 return result;
3280}
3281
3282namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003283typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00003284RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3285 const DeclarationNameInfo &NI, SourceRange QLoc,
3286 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3288 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3289 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
Michael Kruse7520cf02020-03-25 09:26:14 -05003290
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
Michael Kruse7520cf02020-03-25 09:26:14 -05003292
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 RefNamePieces Pieces;
3294
3295 if (WantQualifier && QLoc.isValid())
3296 Pieces.push_back(QLoc);
Michael Kruse7520cf02020-03-25 09:26:14 -05003297
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3299 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00003300
3301 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3302 Pieces.push_back(*TemplateArgsLoc);
3303
Guy Benyei11169dd2012-12-18 14:30:41 +00003304 if (Kind == DeclarationName::CXXOperatorName) {
3305 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003306 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003308 NI.getInfo().CXXOperatorName.EndOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003310
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 if (WantSinglePiece) {
3312 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3313 Pieces.clear();
3314 Pieces.push_back(R);
Michael Kruse7520cf02020-03-25 09:26:14 -05003315 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003316
Michael Kruse7520cf02020-03-25 09:26:14 -05003317 return Pieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00003318}
Michael Kruse7520cf02020-03-25 09:26:14 -05003319} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00003320
3321//===----------------------------------------------------------------------===//
3322// Misc. API hooks.
Michael Kruse7520cf02020-03-25 09:26:14 -05003323//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00003324
Chandler Carruth66660742014-06-27 16:37:27 +00003325namespace {
3326struct RegisterFatalErrorHandler {
3327 RegisterFatalErrorHandler() {
Jan Korousf7d23762019-09-12 22:55:55 +00003328 clang_install_aborting_llvm_fatal_error_handler();
Chandler Carruth66660742014-06-27 16:37:27 +00003329 }
3330};
Michael Kruse7520cf02020-03-25 09:26:14 -05003331} // namespace
Chandler Carruth66660742014-06-27 16:37:27 +00003332
Michael Kruse7520cf02020-03-25 09:26:14 -05003333static llvm::ManagedStatic<RegisterFatalErrorHandler>
3334 RegisterFatalErrorHandlerOnce;
Chandler Carruth66660742014-06-27 16:37:27 +00003335
Guy Benyei11169dd2012-12-18 14:30:41 +00003336CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3337 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 // We use crash recovery to make some of our APIs more reliable, implicitly
3339 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003340 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3341 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003342
Chandler Carruth66660742014-06-27 16:37:27 +00003343 // Look through the managed static to trigger construction of the managed
3344 // static which registers our fatal error handler. This ensures it is only
3345 // registered once.
3346 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003347
Adrian Prantlbc068582015-07-08 01:00:30 +00003348 // Initialize targets for clang module support.
3349 llvm::InitializeAllTargets();
3350 llvm::InitializeAllTargetMCs();
3351 llvm::InitializeAllAsmPrinters();
3352 llvm::InitializeAllAsmParsers();
3353
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003354 CIndexer *CIdxr = new CIndexer();
3355
Guy Benyei11169dd2012-12-18 14:30:41 +00003356 if (excludeDeclarationsFromPCH)
3357 CIdxr->setOnlyLocalDecls();
3358 if (displayDiagnostics)
3359 CIdxr->setDisplayDiagnostics();
3360
3361 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3362 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3363 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3364 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3365 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3366 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3367
3368 return CIdxr;
3369}
3370
3371void clang_disposeIndex(CXIndex CIdx) {
3372 if (CIdx)
3373 delete static_cast<CIndexer *>(CIdx);
3374}
3375
3376void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3377 if (CIdx)
3378 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3379}
3380
3381unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3382 if (CIdx)
3383 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3384 return 0;
3385}
3386
Alex Lorenz08615792017-12-04 21:56:36 +00003387void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
3388 const char *Path) {
3389 if (CIdx)
3390 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
3391}
3392
Guy Benyei11169dd2012-12-18 14:30:41 +00003393void clang_toggleCrashRecovery(unsigned isEnabled) {
3394 if (isEnabled)
3395 llvm::CrashRecoveryContext::Enable();
3396 else
3397 llvm::CrashRecoveryContext::Disable();
3398}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003399
Guy Benyei11169dd2012-12-18 14:30:41 +00003400CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3401 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003402 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003403 enum CXErrorCode Result =
3404 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003405 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003406 assert((TU && Result == CXError_Success) ||
3407 (!TU && Result != CXError_Success));
3408 return TU;
3409}
3410
3411enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3412 const char *ast_filename,
3413 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003414 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003415 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003416
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003417 if (!CIdx || !ast_filename || !out_TU)
3418 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003419
Michael Kruse7520cf02020-03-25 09:26:14 -05003420 LOG_FUNC_SECTION { *Log << ast_filename; }
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003421
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3423 FileSystemOptions FileSystemOpts;
3424
Justin Bognerd512c1e2014-10-15 00:33:06 +00003425 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3426 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003427 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Richard Smithdbafb6c2017-06-29 23:23:46 +00003428 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
Michael Kruse7520cf02020-03-25 09:26:14 -05003429 ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3430 CXXIdx->getOnlyLocalDecls(), None, CaptureDiagsKind::All,
David Blaikie6f7382d2014-08-10 19:08:04 +00003431 /*AllowPCHWithCompilerErrors=*/true,
3432 /*UserFilesAreVolatile=*/true);
David Blaikieea4395e2017-01-06 19:49:01 +00003433 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003434 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003435}
3436
3437unsigned clang_defaultEditingTranslationUnitOptions() {
Michael Kruse7520cf02020-03-25 09:26:14 -05003438 return CXTranslationUnit_PrecompiledPreamble |
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 CXTranslationUnit_CacheCompletionResults;
3440}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003441
Michael Kruse7520cf02020-03-25 09:26:14 -05003442CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3443 CXIndex CIdx, const char *source_filename, int num_command_line_args,
3444 const char *const *command_line_args, unsigned num_unsaved_files,
3445 struct CXUnsavedFile *unsaved_files) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
Michael Kruse7520cf02020-03-25 09:26:14 -05003447 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3448 num_command_line_args, unsaved_files,
3449 num_unsaved_files, Options);
Guy Benyei11169dd2012-12-18 14:30:41 +00003450}
3451
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003452static CXErrorCode
3453clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3454 const char *const *command_line_args,
3455 int num_command_line_args,
3456 ArrayRef<CXUnsavedFile> unsaved_files,
3457 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003458 // Set up the initial return values.
3459 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003460 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003461
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003462 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003463 if (!CIdx || !out_TU)
3464 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003465
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3467
3468 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3469 setThreadBackgroundPriority();
3470
3471 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003472 bool CreatePreambleOnFirstParse =
3473 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 // FIXME: Add a flag for modules.
Michael Kruse7520cf02020-03-25 09:26:14 -05003475 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3476 CXTranslationUnit_SingleFileParse))
3477 ? TU_Prefix
3478 : TU_Complete;
3479 bool CacheCodeCompletionResults =
3480 options & CXTranslationUnit_CacheCompletionResults;
3481 bool IncludeBriefCommentsInCodeCompletion =
3482 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003483 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
3484 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
Michael Kruse7520cf02020-03-25 09:26:14 -05003485 bool RetainExcludedCB =
3486 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
Ivan Donchevskii6e895282018-05-17 09:24:37 +00003487 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
3488 if (options & CXTranslationUnit_SkipFunctionBodies) {
3489 SkipFunctionBodies =
3490 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
3491 ? SkipFunctionBodiesScope::Preamble
3492 : SkipFunctionBodiesScope::PreambleAndMainFile;
3493 }
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003494
3495 // Configure the diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05003496 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3497 CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003498
Manuel Klimek016c0242016-03-01 10:56:19 +00003499 if (options & CXTranslationUnit_KeepGoing)
Ivan Donchevskii878271b2019-03-07 10:13:50 +00003500 Diags->setFatalsAsError(true);
Manuel Klimek016c0242016-03-01 10:56:19 +00003501
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003502 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
3503 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
3504 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
3505
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003507 llvm::CrashRecoveryContextCleanupRegistrar<
3508 DiagnosticsEngine,
3509 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
3510 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003511
Ahmed Charlesb8984322014-03-07 20:03:18 +00003512 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3513 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003514
3515 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003516 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3517 RemappedCleanup(RemappedFiles.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003518
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003519 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003520 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003521 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003522 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003523 }
3524
Ahmed Charlesb8984322014-03-07 20:03:18 +00003525 std::unique_ptr<std::vector<const char *>> Args(
3526 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003527
3528 // Recover resources if we crash before exiting this method.
Michael Kruse7520cf02020-03-25 09:26:14 -05003529 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
3530 ArgsCleanup(Args.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003531
3532 // Since the Clang C library is primarily used by batch tools dealing with
3533 // (often very broken) source code, where spell-checking can have a
Michael Kruse7520cf02020-03-25 09:26:14 -05003534 // significant negative impact on performance (particularly when
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 // precompiled headers are involved), we disable it by default.
3536 // Only do this if we haven't found a spell-checking-related argument.
3537 bool FoundSpellCheckingArgument = false;
3538 for (int I = 0; I != num_command_line_args; ++I) {
3539 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3540 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3541 FoundSpellCheckingArgument = true;
3542 break;
3543 }
3544 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 Args->insert(Args->end(), command_line_args,
3546 command_line_args + num_command_line_args);
3547
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003548 if (!FoundSpellCheckingArgument)
3549 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3550
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 // The 'source_filename' argument is optional. If the caller does not
3552 // specify it then it is assumed that the source file is specified
3553 // in the actual argument list.
3554 // Put the source file after command_line_args otherwise if '-x' flag is
3555 // present it will be unused.
3556 if (source_filename)
3557 Args->push_back(source_filename);
3558
3559 // Do we need the detailed preprocessing record?
3560 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3561 Args->push_back("-Xclang");
3562 Args->push_back("-detailed-preprocessing-record");
3563 }
Alex Lorenzcb006402017-04-27 13:47:03 +00003564
3565 // Suppress any editor placeholder diagnostics.
3566 Args->push_back("-fallow-editor-placeholders");
3567
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003569 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003570 // Unless the user specified that they want the preamble on the first parse
3571 // set it up to be created on the first reparse. This makes the first parse
3572 // faster, trading for a slower (first) reparse.
3573 unsigned PrecompilePreambleAfterNParses =
3574 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Alex Lorenz08615792017-12-04 21:56:36 +00003575
Alex Lorenz08615792017-12-04 21:56:36 +00003576 LibclangInvocationReporter InvocationReporter(
3577 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
Alex Lorenz690f0e22017-12-07 20:37:50 +00003578 options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
3579 unsaved_files);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003580 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003581 Args->data(), Args->data() + Args->size(),
3582 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003583 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003584 CaptureDiagnostics, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003585 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3586 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Argyrios Kyrtzidis735e92c2017-06-09 01:20:48 +00003587 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
Evgeny Mankov2ed2e622019-08-27 22:15:32 +00003588 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003589 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3590 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003591
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003592 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003593 if (!Unit && !ErrUnit)
3594 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003595
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 if (NumErrors != Diags->getClient()->getNumErrors()) {
3597 // Make sure to check that 'Unit' is non-NULL.
3598 if (CXXIdx->getDisplayDiagnostics())
3599 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3600 }
3601
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003602 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3603 return CXError_ASTReadError;
3604
David Blaikieea4395e2017-01-06 19:49:01 +00003605 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
Alex Lorenz690f0e22017-12-07 20:37:50 +00003606 if (CXTranslationUnitImpl *TU = *out_TU) {
3607 TU->ParsingOptions = options;
3608 TU->Arguments.reserve(Args->size());
3609 for (const char *Arg : *Args)
3610 TU->Arguments.push_back(Arg);
3611 return CXError_Success;
3612 }
3613 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003614}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003615
3616CXTranslationUnit
Michael Kruse7520cf02020-03-25 09:26:14 -05003617clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003618 const char *const *command_line_args,
3619 int num_command_line_args,
3620 struct CXUnsavedFile *unsaved_files,
Michael Kruse7520cf02020-03-25 09:26:14 -05003621 unsigned num_unsaved_files, unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003622 CXTranslationUnit TU;
3623 enum CXErrorCode Result = clang_parseTranslationUnit2(
3624 CIdx, source_filename, command_line_args, num_command_line_args,
3625 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003626 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003627 assert((TU && Result == CXError_Success) ||
3628 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003629 return TU;
3630}
3631
3632enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003633 CXIndex CIdx, const char *source_filename,
3634 const char *const *command_line_args, int num_command_line_args,
3635 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3636 unsigned options, CXTranslationUnit *out_TU) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003637 noteBottomOfStack();
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003638 SmallVector<const char *, 4> Args;
3639 Args.push_back("clang");
3640 Args.append(command_line_args, command_line_args + num_command_line_args);
3641 return clang_parseTranslationUnit2FullArgv(
3642 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3643 num_unsaved_files, options, out_TU);
3644}
3645
3646enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3647 CXIndex CIdx, const char *source_filename,
3648 const char *const *command_line_args, int num_command_line_args,
3649 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3650 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003651 LOG_FUNC_SECTION {
3652 *Log << source_filename << ": ";
3653 for (int i = 0; i != num_command_line_args; ++i)
3654 *Log << command_line_args[i] << " ";
3655 }
3656
Alp Toker9d85b182014-07-07 01:23:14 +00003657 if (num_unsaved_files && !unsaved_files)
3658 return CXError_InvalidArguments;
3659
Alp Toker5c532982014-07-07 22:42:03 +00003660 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003661 auto ParseTranslationUnitImpl = [=, &result] {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003662 noteBottomOfStack();
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003663 result = clang_parseTranslationUnit_Impl(
3664 CIdx, source_filename, command_line_args, num_command_line_args,
3665 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3666 };
Erik Verbruggen284848d2017-08-29 09:08:02 +00003667
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 llvm::CrashRecoveryContext CRC;
3669
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003670 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3672 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3673 fprintf(stderr, " 'command_line_args' : [");
3674 for (int i = 0; i != num_command_line_args; ++i) {
3675 if (i)
3676 fprintf(stderr, ", ");
3677 fprintf(stderr, "'%s'", command_line_args[i]);
3678 }
3679 fprintf(stderr, "],\n");
3680 fprintf(stderr, " 'unsaved_files' : [");
3681 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3682 if (i)
3683 fprintf(stderr, ", ");
3684 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3685 unsaved_files[i].Length);
3686 }
3687 fprintf(stderr, "],\n");
3688 fprintf(stderr, " 'options' : %d,\n", options);
3689 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003690
3691 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003693 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003694 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 }
Alp Toker5c532982014-07-07 22:42:03 +00003696
3697 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003698}
3699
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003700CXString clang_Type_getObjCEncoding(CXType CT) {
3701 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3702 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3703 std::string encoding;
Michael Kruse7520cf02020-03-25 09:26:14 -05003704 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003705
3706 return cxstring::createDup(encoding);
3707}
3708
3709static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3710 if (C.kind == CXCursor_MacroDefinition) {
3711 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3712 return MDR->getName();
3713 } else if (C.kind == CXCursor_MacroExpansion) {
3714 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3715 return ME.getName();
3716 }
3717 return nullptr;
3718}
3719
3720unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3721 const IdentifierInfo *II = getMacroIdentifier(C);
3722 if (!II) {
3723 return false;
3724 }
3725 ASTUnit *ASTU = getCursorASTUnit(C);
3726 Preprocessor &PP = ASTU->getPreprocessor();
3727 if (const MacroInfo *MI = PP.getMacroInfo(II))
3728 return MI->isFunctionLike();
3729 return false;
3730}
3731
3732unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3733 const IdentifierInfo *II = getMacroIdentifier(C);
3734 if (!II) {
3735 return false;
3736 }
3737 ASTUnit *ASTU = getCursorASTUnit(C);
3738 Preprocessor &PP = ASTU->getPreprocessor();
3739 if (const MacroInfo *MI = PP.getMacroInfo(II))
3740 return MI->isBuiltinMacro();
3741 return false;
3742}
3743
3744unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3745 const Decl *D = getCursorDecl(C);
3746 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3747 if (!FD) {
3748 return false;
3749 }
3750 return FD->isInlined();
3751}
3752
Michael Kruse7520cf02020-03-25 09:26:14 -05003753static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003754 if (callExpr->getNumArgs() != 1) {
3755 return nullptr;
3756 }
3757
3758 StringLiteral *S = nullptr;
3759 auto *arg = callExpr->getArg(0);
3760 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3761 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3762 auto *subExpr = I->getSubExprAsWritten();
3763
Michael Kruse7520cf02020-03-25 09:26:14 -05003764 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003765 return nullptr;
3766 }
3767
3768 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3769 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3770 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3771 } else {
3772 return nullptr;
3773 }
3774 return S;
3775}
3776
David Blaikie59272572016-04-13 18:23:33 +00003777struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003778 CXEvalResultKind EvalType;
3779 union {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003780 unsigned long long unsignedVal;
3781 long long intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003782 double floatVal;
3783 char *stringVal;
3784 } EvalData;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003785 bool IsUnsignedInt;
David Blaikie59272572016-04-13 18:23:33 +00003786 ~ExprEvalResult() {
3787 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3788 EvalType != CXEval_Int) {
Alex Lorenza19cb2e2019-01-08 23:28:37 +00003789 delete[] EvalData.stringVal;
David Blaikie59272572016-04-13 18:23:33 +00003790 }
3791 }
3792};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003793
3794void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003795 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003796}
3797
3798CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3799 if (!E) {
3800 return CXEval_UnExposed;
3801 }
3802 return ((ExprEvalResult *)E)->EvalType;
3803}
3804
3805int clang_EvalResult_getAsInt(CXEvalResult E) {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003806 return clang_EvalResult_getAsLongLong(E);
3807}
3808
3809long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003810 if (!E) {
3811 return 0;
3812 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003813 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003814 if (Result->IsUnsignedInt)
3815 return Result->EvalData.unsignedVal;
3816 return Result->EvalData.intVal;
3817}
3818
3819unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
3820 return ((ExprEvalResult *)E)->IsUnsignedInt;
3821}
3822
3823unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
3824 if (!E) {
3825 return 0;
3826 }
3827
Michael Kruse7520cf02020-03-25 09:26:14 -05003828 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003829 if (Result->IsUnsignedInt)
3830 return Result->EvalData.unsignedVal;
3831 return Result->EvalData.intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003832}
3833
3834double clang_EvalResult_getAsDouble(CXEvalResult E) {
3835 if (!E) {
3836 return 0;
3837 }
3838 return ((ExprEvalResult *)E)->EvalData.floatVal;
3839}
3840
Michael Kruse7520cf02020-03-25 09:26:14 -05003841const char *clang_EvalResult_getAsStr(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003842 if (!E) {
3843 return nullptr;
3844 }
3845 return ((ExprEvalResult *)E)->EvalData.stringVal;
3846}
3847
Michael Kruse7520cf02020-03-25 09:26:14 -05003848static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003849 Expr::EvalResult ER;
3850 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003851 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003852 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003853
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003854 expr = expr->IgnoreParens();
Emilio Cobos Alvarez74375452019-07-09 14:27:01 +00003855 if (expr->isValueDependent())
3856 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003857 if (!expr->EvaluateAsRValue(ER, ctx))
3858 return nullptr;
3859
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003860 QualType rettype;
3861 CallExpr *callExpr;
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00003862 auto result = std::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003863 result->EvalType = CXEval_UnExposed;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003864 result->IsUnsignedInt = false;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003865
David Blaikiebbc00882016-04-13 18:36:19 +00003866 if (ER.Val.isInt()) {
3867 result->EvalType = CXEval_Int;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003868
Michael Kruse7520cf02020-03-25 09:26:14 -05003869 auto &val = ER.Val.getInt();
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003870 if (val.isUnsigned()) {
3871 result->IsUnsignedInt = true;
3872 result->EvalData.unsignedVal = val.getZExtValue();
3873 } else {
3874 result->EvalData.intVal = val.getExtValue();
3875 }
3876
David Blaikiebbc00882016-04-13 18:36:19 +00003877 return result.release();
3878 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003879
David Blaikiebbc00882016-04-13 18:36:19 +00003880 if (ER.Val.isFloat()) {
3881 llvm::SmallVector<char, 100> Buffer;
3882 ER.Val.getFloat().toString(Buffer);
3883 std::string floatStr(Buffer.data(), Buffer.size());
3884 result->EvalType = CXEval_Float;
3885 bool ignored;
3886 llvm::APFloat apFloat = ER.Val.getFloat();
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003887 apFloat.convert(llvm::APFloat::IEEEdouble(),
David Blaikiebbc00882016-04-13 18:36:19 +00003888 llvm::APFloat::rmNearestTiesToEven, &ignored);
3889 result->EvalData.floatVal = apFloat.convertToDouble();
3890 return result.release();
3891 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003892
David Blaikiebbc00882016-04-13 18:36:19 +00003893 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3894 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3895 auto *subExpr = I->getSubExprAsWritten();
3896 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3897 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003898 const StringLiteral *StrE = nullptr;
3899 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003900 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003901
3902 if (ObjCExpr) {
3903 StrE = ObjCExpr->getString();
3904 result->EvalType = CXEval_ObjCStrLiteral;
3905 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003906 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003907 result->EvalType = CXEval_StrLiteral;
3908 }
3909
3910 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003911 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003912 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3913 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003914 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003915 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003916 }
3917 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3918 expr->getStmtClass() == Stmt::StringLiteralClass) {
3919 const StringLiteral *StrE = nullptr;
3920 const ObjCStringLiteral *ObjCExpr;
3921 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003922
David Blaikiebbc00882016-04-13 18:36:19 +00003923 if (ObjCExpr) {
3924 StrE = ObjCExpr->getString();
3925 result->EvalType = CXEval_ObjCStrLiteral;
3926 } else {
3927 StrE = cast<StringLiteral>(expr);
3928 result->EvalType = CXEval_StrLiteral;
3929 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003930
David Blaikiebbc00882016-04-13 18:36:19 +00003931 std::string strRef(StrE->getString().str());
3932 result->EvalData.stringVal = new char[strRef.size() + 1];
3933 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3934 result->EvalData.stringVal[strRef.size()] = '\0';
3935 return result.release();
3936 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003937
David Blaikiebbc00882016-04-13 18:36:19 +00003938 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3939 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003940
David Blaikiebbc00882016-04-13 18:36:19 +00003941 rettype = CC->getType();
3942 if (rettype.getAsString() == "CFStringRef" &&
3943 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003944
David Blaikiebbc00882016-04-13 18:36:19 +00003945 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3946 StringLiteral *S = getCFSTR_value(callExpr);
3947 if (S) {
3948 std::string strLiteral(S->getString().str());
3949 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003950
David Blaikiebbc00882016-04-13 18:36:19 +00003951 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3952 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3953 strLiteral.size());
3954 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003955 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003956 }
3957 }
3958
David Blaikiebbc00882016-04-13 18:36:19 +00003959 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3960 callExpr = static_cast<CallExpr *>(expr);
3961 rettype = callExpr->getCallReturnType(ctx);
3962
3963 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
3964 return nullptr;
3965
3966 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3967 if (callExpr->getNumArgs() == 1 &&
3968 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
3969 return nullptr;
3970 } else if (rettype.getAsString() == "CFStringRef") {
3971
3972 StringLiteral *S = getCFSTR_value(callExpr);
3973 if (S) {
3974 std::string strLiteral(S->getString().str());
3975 result->EvalType = CXEval_CFStr;
3976 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3977 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3978 strLiteral.size());
3979 result->EvalData.stringVal[strLiteral.size()] = '\0';
3980 return result.release();
3981 }
3982 }
3983 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3984 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3985 ValueDecl *V = D->getDecl();
3986 if (V->getKind() == Decl::Function) {
3987 std::string strName = V->getNameAsString();
3988 result->EvalType = CXEval_Other;
3989 result->EvalData.stringVal = new char[strName.size() + 1];
3990 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
3991 result->EvalData.stringVal[strName.size()] = '\0';
3992 return result.release();
3993 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003994 }
3995
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003996 return nullptr;
3997}
3998
Alex Lorenz65317e12019-01-08 22:32:51 +00003999static const Expr *evaluateDeclExpr(const Decl *D) {
4000 if (!D)
Evgeniy Stepanov9b871492018-07-10 19:48:53 +00004001 return nullptr;
Alex Lorenz65317e12019-01-08 22:32:51 +00004002 if (auto *Var = dyn_cast<VarDecl>(D))
4003 return Var->getInit();
4004 else if (auto *Field = dyn_cast<FieldDecl>(D))
4005 return Field->getInClassInitializer();
4006 return nullptr;
4007}
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004008
Alex Lorenz65317e12019-01-08 22:32:51 +00004009static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4010 assert(CS && "invalid compound statement");
4011 for (auto *bodyIterator : CS->body()) {
4012 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4013 return E;
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004014 }
Alex Lorenzc4cf96e2018-07-09 19:56:45 +00004015 return nullptr;
4016}
4017
Alex Lorenz65317e12019-01-08 22:32:51 +00004018CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
4019 if (const Expr *E =
4020 clang_getCursorKind(C) == CXCursor_CompoundStmt
4021 ? evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)))
4022 : evaluateDeclExpr(getCursorDecl(C)))
4023 return const_cast<CXEvalResult>(
4024 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4025 return nullptr;
4026}
4027
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004028unsigned clang_Cursor_hasAttrs(CXCursor C) {
4029 const Decl *D = getCursorDecl(C);
4030 if (!D) {
4031 return 0;
4032 }
4033
4034 if (D->hasAttrs()) {
4035 return 1;
4036 }
4037
4038 return 0;
4039}
Guy Benyei11169dd2012-12-18 14:30:41 +00004040unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4041 return CXSaveTranslationUnit_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05004042}
Guy Benyei11169dd2012-12-18 14:30:41 +00004043
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004044static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4045 const char *FileName,
4046 unsigned options) {
4047 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4049 setThreadBackgroundPriority();
4050
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004051 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4052 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00004053}
4054
4055int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4056 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004057 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004058
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004059 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004060 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004062 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004063
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004064 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4066 if (!CXXUnit->hasSema())
4067 return CXSaveError_InvalidTU;
4068
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004069 CXSaveError result;
4070 auto SaveTranslationUnitImpl = [=, &result]() {
4071 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4072 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004073
Erik Verbruggen3cc39112017-11-14 09:34:39 +00004074 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004075 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00004076
4077 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4078 PrintLibclangResourceUsage(TU);
4079
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004080 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 }
4082
4083 // We have an AST that has invalid nodes due to compiler errors.
4084 // Use a crash recovery thread for protection.
4085
4086 llvm::CrashRecoveryContext CRC;
4087
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004088 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4090 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4091 fprintf(stderr, " 'options' : %d,\n", options);
4092 fprintf(stderr, "}\n");
4093
4094 return CXSaveError_Unknown;
4095
4096 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4097 PrintLibclangResourceUsage(TU);
4098 }
4099
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004100 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004101}
4102
4103void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4104 if (CTUnit) {
4105 // If the translation unit has been marked as unsafe to free, just discard
4106 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004107 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4108 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 return;
4110
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004111 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00004112 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4114 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00004115 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 delete CTUnit;
4117 }
4118}
4119
Erik Verbruggen346066b2017-05-30 14:25:54 +00004120unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4121 if (CTUnit) {
4122 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4123
4124 if (Unit && Unit->isUnsafeToFree())
4125 return false;
4126
4127 Unit->ResetForParse();
4128 return true;
4129 }
4130
4131 return false;
4132}
4133
Guy Benyei11169dd2012-12-18 14:30:41 +00004134unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4135 return CXReparse_None;
4136}
4137
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004138static CXErrorCode
4139clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4140 ArrayRef<CXUnsavedFile> unsaved_files,
4141 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004142 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004143 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004144 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004145 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004146 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004147
4148 // Reset the associated diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05004149 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00004150 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004151
Dmitri Gribenko183436e2013-01-26 21:49:50 +00004152 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4154 setThreadBackgroundPriority();
4155
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004156 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00004158
4159 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4160 new std::vector<ASTUnit::RemappedFile>());
4161
Guy Benyei11169dd2012-12-18 14:30:41 +00004162 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05004163 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4164 RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00004165
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004166 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004167 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00004168 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004169 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004171
Adrian Prantlbb165fb2015-06-20 18:53:08 +00004172 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4173 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004174 return CXError_Success;
4175 if (isASTReadError(CXXUnit))
4176 return CXError_ASTReadError;
4177 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00004178}
4179
4180int clang_reparseTranslationUnit(CXTranslationUnit TU,
4181 unsigned num_unsaved_files,
4182 struct CXUnsavedFile *unsaved_files,
4183 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004184 LOG_FUNC_SECTION { *Log << TU; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004185
Alp Toker9d85b182014-07-07 01:23:14 +00004186 if (num_unsaved_files && !unsaved_files)
4187 return CXError_InvalidArguments;
4188
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004189 CXErrorCode result;
4190 auto ReparseTranslationUnitImpl = [=, &result]() {
4191 result = clang_reparseTranslationUnit_Impl(
4192 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
4193 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004194
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 llvm::CrashRecoveryContext CRC;
4196
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004197 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004199 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004200 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4202 PrintLibclangResourceUsage(TU);
4203
Alp Toker5c532982014-07-07 22:42:03 +00004204 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004205}
4206
Guy Benyei11169dd2012-12-18 14:30:41 +00004207CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004208 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004209 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004210 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004211 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004212
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004213 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004214 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004215}
4216
4217CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004218 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004219 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004220 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004221 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004222
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004223 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4225}
4226
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004227CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4228 if (isNotUsableTU(CTUnit)) {
4229 LOG_BAD_TU(CTUnit);
4230 return nullptr;
4231 }
4232
Michael Kruse7520cf02020-03-25 09:26:14 -05004233 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004234 impl->TranslationUnit = CTUnit;
4235 return impl;
4236}
4237
4238CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4239 if (!TargetInfo)
4240 return cxstring::createEmpty();
4241
4242 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4243 assert(!isNotUsableTU(CTUnit) &&
4244 "Unexpected unusable translation unit in TargetInfo");
4245
4246 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4247 std::string Triple =
Michael Kruse7520cf02020-03-25 09:26:14 -05004248 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004249 return cxstring::createDup(Triple);
4250}
4251
4252int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4253 if (!TargetInfo)
4254 return -1;
4255
4256 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4257 assert(!isNotUsableTU(CTUnit) &&
4258 "Unexpected unusable translation unit in TargetInfo");
4259
4260 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4261 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4262}
4263
4264void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4265 if (!TargetInfo)
4266 return;
4267
4268 delete TargetInfo;
4269}
4270
Guy Benyei11169dd2012-12-18 14:30:41 +00004271//===----------------------------------------------------------------------===//
4272// CXFile Operations.
4273//===----------------------------------------------------------------------===//
4274
Guy Benyei11169dd2012-12-18 14:30:41 +00004275CXString clang_getFileName(CXFile SFile) {
4276 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00004277 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00004278
4279 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004281}
4282
4283time_t clang_getFileTime(CXFile SFile) {
4284 if (!SFile)
4285 return 0;
4286
4287 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4288 return FEnt->getModificationTime();
4289}
4290
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004291CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004292 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004293 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00004294 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004295 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004296
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004297 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004298
4299 FileManager &FMgr = CXXUnit->getFileManager();
Harlan Haskins8d323d12019-08-01 21:31:56 +00004300 auto File = FMgr.getFile(file_name);
4301 if (!File)
4302 return nullptr;
4303 return const_cast<FileEntry *>(*File);
Guy Benyei11169dd2012-12-18 14:30:41 +00004304}
4305
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004306const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4307 size_t *size) {
4308 if (isNotUsableTU(TU)) {
4309 LOG_BAD_TU(TU);
4310 return nullptr;
4311 }
4312
4313 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4314 FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
4315 bool Invalid = true;
Nico Weber04347d82019-04-04 21:06:41 +00004316 const llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid);
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004317 if (Invalid) {
4318 if (size)
4319 *size = 0;
4320 return nullptr;
4321 }
4322 if (size)
4323 *size = buf->getBufferSize();
4324 return buf->getBufferStart();
4325}
4326
Michael Kruse7520cf02020-03-25 09:26:14 -05004327unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004328 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004329 LOG_BAD_TU(TU);
4330 return 0;
4331 }
4332
4333 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00004334 return 0;
4335
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004336 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004337 FileEntry *FEnt = static_cast<FileEntry *>(file);
Michael Kruse7520cf02020-03-25 09:26:14 -05004338 return CXXUnit->getPreprocessor()
4339 .getHeaderSearchInfo()
4340 .isFileMultipleIncludeGuarded(FEnt);
Guy Benyei11169dd2012-12-18 14:30:41 +00004341}
4342
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004343int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
4344 if (!file || !outID)
4345 return 1;
4346
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004347 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00004348 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
4349 outID->data[0] = ID.getDevice();
4350 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004351 outID->data[2] = FEnt->getModificationTime();
4352 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004353}
4354
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00004355int clang_File_isEqual(CXFile file1, CXFile file2) {
4356 if (file1 == file2)
4357 return true;
4358
4359 if (!file1 || !file2)
4360 return false;
4361
4362 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
4363 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
4364 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
4365}
4366
Fangrui Songe46ac5f2018-04-07 20:50:35 +00004367CXString clang_File_tryGetRealPathName(CXFile SFile) {
4368 if (!SFile)
4369 return cxstring::createNull();
4370
4371 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4372 return cxstring::createRef(FEnt->tryGetRealPathName());
4373}
4374
Guy Benyei11169dd2012-12-18 14:30:41 +00004375//===----------------------------------------------------------------------===//
4376// CXCursor Operations.
4377//===----------------------------------------------------------------------===//
4378
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004379static const Decl *getDeclFromExpr(const Stmt *E) {
4380 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 return getDeclFromExpr(CE->getSubExpr());
4382
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004383 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004385 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004386 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004387 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004389 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004390 if (PRE->isExplicitProperty())
4391 return PRE->getExplicitProperty();
4392 // It could be messaging both getter and setter as in:
4393 // ++myobj.myprop;
4394 // in which case prefer to associate the setter since it is less obvious
4395 // from inspecting the source that the setter is going to get called.
4396 if (PRE->isMessagingSetter())
4397 return PRE->getImplicitPropertySetter();
4398 return PRE->getImplicitPropertyGetter();
4399 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004400 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004402 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004403 if (Expr *Src = OVE->getSourceExpr())
4404 return getDeclFromExpr(Src);
Michael Kruse7520cf02020-03-25 09:26:14 -05004405
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004406 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004408 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004409 if (!CE->isElidable())
Michael Kruse7520cf02020-03-25 09:26:14 -05004410 return CE->getConstructor();
Richard Smith5179eb72016-06-28 19:03:57 +00004411 if (const CXXInheritedCtorInitExpr *CE =
4412 dyn_cast<CXXInheritedCtorInitExpr>(E))
4413 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004414 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 return OME->getMethodDecl();
4416
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004417 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004418 return PE->getProtocol();
Michael Kruse7520cf02020-03-25 09:26:14 -05004419 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4420 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004422 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004423 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 isa<ParmVarDecl>(SizeOfPack->getPack()))
4425 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00004426
4427 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004428}
4429
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004430static SourceLocation getLocationFromExpr(const Expr *E) {
4431 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 return getLocationFromExpr(CE->getSubExpr());
4433
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004434 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004435 return /*FIXME:*/ Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004436 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004437 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004438 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004440 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004442 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004444 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004445 return PropRef->getLocation();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004446
4447 return E->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00004448}
4449
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00004450extern "C" {
4451
Michael Kruse7520cf02020-03-25 09:26:14 -05004452unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 CXClientData client_data) {
4454 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4455 /*VisitPreprocessorLast=*/false);
4456 return CursorVis.VisitChildren(parent);
4457}
4458
4459#ifndef __has_feature
4460#define __has_feature(x) 0
4461#endif
4462#if __has_feature(blocks)
Michael Kruse7520cf02020-03-25 09:26:14 -05004463typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4464 CXCursor parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00004465
4466static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004467 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4469 return block(cursor, parent);
4470}
4471#else
4472// If we are compiled with a compiler that doesn't have native blocks support,
Michael Kruse7520cf02020-03-25 09:26:14 -05004473// define and call the block manually, so the
4474typedef struct _CXChildVisitResult {
4475 void *isa;
4476 int flags;
4477 int reserved;
4478 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
4479 CXCursor);
4480} * CXCursorVisitorBlock;
Guy Benyei11169dd2012-12-18 14:30:41 +00004481
4482static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004483 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4485 return block->invoke(block, cursor, parent);
4486}
4487#endif
4488
Guy Benyei11169dd2012-12-18 14:30:41 +00004489unsigned clang_visitChildrenWithBlock(CXCursor parent,
4490 CXCursorVisitorBlock block) {
4491 return clang_visitChildren(parent, visitWithBlock, block);
4492}
4493
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004494static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004496 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004497
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004498 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004500 if (const ObjCPropertyImplDecl *PropImpl =
4501 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004503 return cxstring::createDup(Property->getIdentifier()->getName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004504
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004505 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004507 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004508
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004509 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004511
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004513 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004514
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004515 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4517 // and returns different names. NamedDecl returns the class name and
4518 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004519 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004520
4521 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004522 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05004523
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 SmallString<1024> S;
4525 llvm::raw_svector_ostream os(S);
4526 ND->printName(os);
Michael Kruse7520cf02020-03-25 09:26:14 -05004527
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004528 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004529}
4530
4531CXString clang_getCursorSpelling(CXCursor C) {
4532 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004533 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004534
4535 if (clang_isReference(C.kind)) {
4536 switch (C.kind) {
4537 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004538 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004539 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 }
4541 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004542 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004543 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 }
4545 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004546 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004548 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 }
4550 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004551 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004552 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 }
4554 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004555 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 assert(Type && "Missing type decl");
4557
Michael Kruse7520cf02020-03-25 09:26:14 -05004558 return cxstring::createDup(
4559 getCursorContext(C).getTypeDeclType(Type).getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 }
4561 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004562 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 assert(Template && "Missing template decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004564
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004565 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004567
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004569 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 assert(NS && "Missing namespace decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004571
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004572 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 }
4574
4575 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004576 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 assert(Field && "Missing member decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004578
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004579 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 }
4581
4582 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004583 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 assert(Label && "Missing label");
Michael Kruse7520cf02020-03-25 09:26:14 -05004585
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004586 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 }
4588
4589 case CXCursor_OverloadedDeclRef: {
4590 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004591 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4592 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004593 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004594 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004596 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004597 return cxstring::createDup(E->getName().getAsString());
Michael Kruse7520cf02020-03-25 09:26:14 -05004598 OverloadedTemplateStorage *Ovl =
4599 Storage.get<OverloadedTemplateStorage *>();
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004601 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004602 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004604
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004606 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 assert(Var && "Missing variable decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004608
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004609 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004611
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004613 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 }
4615 }
4616
4617 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004618 const Expr *E = getCursorExpr(C);
4619
4620 if (C.kind == CXCursor_ObjCStringLiteral ||
4621 C.kind == CXCursor_StringLiteral) {
4622 const StringLiteral *SLit;
4623 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4624 SLit = OSL->getString();
4625 } else {
4626 SLit = cast<StringLiteral>(E);
4627 }
4628 SmallString<256> Buf;
4629 llvm::raw_svector_ostream OS(Buf);
4630 SLit->outputString(OS);
4631 return cxstring::createDup(OS.str());
4632 }
4633
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004634 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 if (D)
4636 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004637 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 }
4639
4640 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004641 const Stmt *S = getCursorStmt(C);
4642 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004643 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004644
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004645 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004647
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 if (C.kind == CXCursor_MacroExpansion)
Michael Kruse7520cf02020-03-25 09:26:14 -05004649 return cxstring::createRef(
4650 getCursorMacroExpansion(C).getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004651
4652 if (C.kind == CXCursor_MacroDefinition)
Michael Kruse7520cf02020-03-25 09:26:14 -05004653 return cxstring::createRef(
4654 getCursorMacroDefinition(C)->getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004655
4656 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004657 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004658
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 if (clang_isDeclaration(C.kind))
4660 return getDeclSpelling(getCursorDecl(C));
4661
4662 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004663 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004664 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 }
4666
4667 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004668 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004669 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 }
4671
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004672 if (C.kind == CXCursor_PackedAttr) {
4673 return cxstring::createRef("packed");
4674 }
4675
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004676 if (C.kind == CXCursor_VisibilityAttr) {
4677 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4678 switch (AA->getVisibility()) {
4679 case VisibilityAttr::VisibilityType::Default:
4680 return cxstring::createRef("default");
4681 case VisibilityAttr::VisibilityType::Hidden:
4682 return cxstring::createRef("hidden");
4683 case VisibilityAttr::VisibilityType::Protected:
4684 return cxstring::createRef("protected");
4685 }
4686 llvm_unreachable("unknown visibility type");
4687 }
4688
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004689 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004690}
4691
Michael Kruse7520cf02020-03-25 09:26:14 -05004692CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 unsigned options) {
4694 if (clang_Cursor_isNull(C))
4695 return clang_getNullRange();
4696
4697 ASTContext &Ctx = getCursorContext(C);
4698
4699 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004700 const Stmt *S = getCursorStmt(C);
4701 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 if (pieceIndex > 0)
4703 return clang_getNullRange();
4704 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4705 }
4706
4707 return clang_getNullRange();
4708 }
4709
4710 if (C.kind == CXCursor_ObjCMessageExpr) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004711 if (const ObjCMessageExpr *ME =
4712 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 if (pieceIndex >= ME->getNumSelectorLocs())
4714 return clang_getNullRange();
4715 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4716 }
4717 }
4718
4719 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4720 C.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004721 if (const ObjCMethodDecl *MD =
4722 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 if (pieceIndex >= MD->getNumSelectorLocs())
4724 return clang_getNullRange();
4725 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4726 }
4727 }
4728
4729 if (C.kind == CXCursor_ObjCCategoryDecl ||
4730 C.kind == CXCursor_ObjCCategoryImplDecl) {
4731 if (pieceIndex > 0)
4732 return clang_getNullRange();
Michael Kruse7520cf02020-03-25 09:26:14 -05004733 if (const ObjCCategoryDecl *CD =
4734 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Michael Kruse7520cf02020-03-25 09:26:14 -05004736 if (const ObjCCategoryImplDecl *CID =
4737 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4739 }
4740
4741 if (C.kind == CXCursor_ModuleImportDecl) {
4742 if (pieceIndex > 0)
4743 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004744 if (const ImportDecl *ImportD =
4745 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4747 if (!Locs.empty())
Michael Kruse7520cf02020-03-25 09:26:14 -05004748 return cxloc::translateSourceRange(
4749 Ctx, SourceRange(Locs.front(), Locs.back()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 }
4751 return clang_getNullRange();
4752 }
4753
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004754 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
Kevin Funk4be5d672016-12-20 09:56:56 +00004755 C.kind == CXCursor_ConversionFunction ||
4756 C.kind == CXCursor_FunctionDecl) {
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004757 if (pieceIndex > 0)
4758 return clang_getNullRange();
4759 if (const FunctionDecl *FD =
4760 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4761 DeclarationNameInfo FunctionName = FD->getNameInfo();
4762 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4763 }
4764 return clang_getNullRange();
4765 }
4766
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 // FIXME: A CXCursor_InclusionDirective should give the location of the
4768 // filename, but we don't keep track of this.
4769
4770 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4771 // but we don't keep track of this.
4772
4773 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4774 // but we don't keep track of this.
4775
4776 // Default handling, give the location of the cursor.
4777
4778 if (pieceIndex > 0)
4779 return clang_getNullRange();
4780
4781 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4782 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4783 return cxloc::translateSourceRange(Ctx, Loc);
4784}
4785
Eli Bendersky44a206f2014-07-31 18:04:56 +00004786CXString clang_Cursor_getMangling(CXCursor C) {
4787 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4788 return cxstring::createEmpty();
4789
Eli Bendersky44a206f2014-07-31 18:04:56 +00004790 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004791 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004792 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4793 return cxstring::createEmpty();
4794
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004795 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004796 ASTNameGenerator ASTNameGen(Ctx);
4797 return cxstring::createDup(ASTNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004798}
4799
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004800CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4801 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4802 return nullptr;
4803
4804 const Decl *D = getCursorDecl(C);
4805 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4806 return nullptr;
4807
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004808 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004809 ASTNameGenerator ASTNameGen(Ctx);
4810 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004811 return cxstring::createSet(Manglings);
4812}
4813
Dave Lee1a532c92017-09-22 16:58:57 +00004814CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
4815 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4816 return nullptr;
4817
4818 const Decl *D = getCursorDecl(C);
4819 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
4820 return nullptr;
4821
4822 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004823 ASTNameGenerator ASTNameGen(Ctx);
4824 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Dave Lee1a532c92017-09-22 16:58:57 +00004825 return cxstring::createSet(Manglings);
4826}
4827
Jonathan Coe45ef5032018-01-16 10:19:56 +00004828CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
4829 if (clang_Cursor_isNull(C))
4830 return 0;
4831 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
4832}
4833
4834void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
4835 if (Policy)
4836 delete static_cast<PrintingPolicy *>(Policy);
4837}
4838
4839unsigned
4840clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
4841 enum CXPrintingPolicyProperty Property) {
4842 if (!Policy)
4843 return 0;
4844
4845 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4846 switch (Property) {
4847 case CXPrintingPolicy_Indentation:
4848 return P->Indentation;
4849 case CXPrintingPolicy_SuppressSpecifiers:
4850 return P->SuppressSpecifiers;
4851 case CXPrintingPolicy_SuppressTagKeyword:
4852 return P->SuppressTagKeyword;
4853 case CXPrintingPolicy_IncludeTagDefinition:
4854 return P->IncludeTagDefinition;
4855 case CXPrintingPolicy_SuppressScope:
4856 return P->SuppressScope;
4857 case CXPrintingPolicy_SuppressUnwrittenScope:
4858 return P->SuppressUnwrittenScope;
4859 case CXPrintingPolicy_SuppressInitializers:
4860 return P->SuppressInitializers;
4861 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4862 return P->ConstantArraySizeAsWritten;
4863 case CXPrintingPolicy_AnonymousTagLocations:
4864 return P->AnonymousTagLocations;
4865 case CXPrintingPolicy_SuppressStrongLifetime:
4866 return P->SuppressStrongLifetime;
4867 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4868 return P->SuppressLifetimeQualifiers;
4869 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4870 return P->SuppressTemplateArgsInCXXConstructors;
4871 case CXPrintingPolicy_Bool:
4872 return P->Bool;
4873 case CXPrintingPolicy_Restrict:
4874 return P->Restrict;
4875 case CXPrintingPolicy_Alignof:
4876 return P->Alignof;
4877 case CXPrintingPolicy_UnderscoreAlignof:
4878 return P->UnderscoreAlignof;
4879 case CXPrintingPolicy_UseVoidForZeroParams:
4880 return P->UseVoidForZeroParams;
4881 case CXPrintingPolicy_TerseOutput:
4882 return P->TerseOutput;
4883 case CXPrintingPolicy_PolishForDeclaration:
4884 return P->PolishForDeclaration;
4885 case CXPrintingPolicy_Half:
4886 return P->Half;
4887 case CXPrintingPolicy_MSWChar:
4888 return P->MSWChar;
4889 case CXPrintingPolicy_IncludeNewlines:
4890 return P->IncludeNewlines;
4891 case CXPrintingPolicy_MSVCFormatting:
4892 return P->MSVCFormatting;
4893 case CXPrintingPolicy_ConstantsAsWritten:
4894 return P->ConstantsAsWritten;
4895 case CXPrintingPolicy_SuppressImplicitBase:
4896 return P->SuppressImplicitBase;
4897 case CXPrintingPolicy_FullyQualifiedName:
4898 return P->FullyQualifiedName;
4899 }
4900
4901 assert(false && "Invalid CXPrintingPolicyProperty");
4902 return 0;
4903}
4904
4905void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
4906 enum CXPrintingPolicyProperty Property,
4907 unsigned Value) {
4908 if (!Policy)
4909 return;
4910
4911 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4912 switch (Property) {
4913 case CXPrintingPolicy_Indentation:
4914 P->Indentation = Value;
4915 return;
4916 case CXPrintingPolicy_SuppressSpecifiers:
4917 P->SuppressSpecifiers = Value;
4918 return;
4919 case CXPrintingPolicy_SuppressTagKeyword:
4920 P->SuppressTagKeyword = Value;
4921 return;
4922 case CXPrintingPolicy_IncludeTagDefinition:
4923 P->IncludeTagDefinition = Value;
4924 return;
4925 case CXPrintingPolicy_SuppressScope:
4926 P->SuppressScope = Value;
4927 return;
4928 case CXPrintingPolicy_SuppressUnwrittenScope:
4929 P->SuppressUnwrittenScope = Value;
4930 return;
4931 case CXPrintingPolicy_SuppressInitializers:
4932 P->SuppressInitializers = Value;
4933 return;
4934 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4935 P->ConstantArraySizeAsWritten = Value;
4936 return;
4937 case CXPrintingPolicy_AnonymousTagLocations:
4938 P->AnonymousTagLocations = Value;
4939 return;
4940 case CXPrintingPolicy_SuppressStrongLifetime:
4941 P->SuppressStrongLifetime = Value;
4942 return;
4943 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4944 P->SuppressLifetimeQualifiers = Value;
4945 return;
4946 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4947 P->SuppressTemplateArgsInCXXConstructors = Value;
4948 return;
4949 case CXPrintingPolicy_Bool:
4950 P->Bool = Value;
4951 return;
4952 case CXPrintingPolicy_Restrict:
4953 P->Restrict = Value;
4954 return;
4955 case CXPrintingPolicy_Alignof:
4956 P->Alignof = Value;
4957 return;
4958 case CXPrintingPolicy_UnderscoreAlignof:
4959 P->UnderscoreAlignof = Value;
4960 return;
4961 case CXPrintingPolicy_UseVoidForZeroParams:
4962 P->UseVoidForZeroParams = Value;
4963 return;
4964 case CXPrintingPolicy_TerseOutput:
4965 P->TerseOutput = Value;
4966 return;
4967 case CXPrintingPolicy_PolishForDeclaration:
4968 P->PolishForDeclaration = Value;
4969 return;
4970 case CXPrintingPolicy_Half:
4971 P->Half = Value;
4972 return;
4973 case CXPrintingPolicy_MSWChar:
4974 P->MSWChar = Value;
4975 return;
4976 case CXPrintingPolicy_IncludeNewlines:
4977 P->IncludeNewlines = Value;
4978 return;
4979 case CXPrintingPolicy_MSVCFormatting:
4980 P->MSVCFormatting = Value;
4981 return;
4982 case CXPrintingPolicy_ConstantsAsWritten:
4983 P->ConstantsAsWritten = Value;
4984 return;
4985 case CXPrintingPolicy_SuppressImplicitBase:
4986 P->SuppressImplicitBase = Value;
4987 return;
4988 case CXPrintingPolicy_FullyQualifiedName:
4989 P->FullyQualifiedName = Value;
4990 return;
4991 }
4992
4993 assert(false && "Invalid CXPrintingPolicyProperty");
4994}
4995
4996CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
4997 if (clang_Cursor_isNull(C))
4998 return cxstring::createEmpty();
4999
5000 if (clang_isDeclaration(C.kind)) {
5001 const Decl *D = getCursorDecl(C);
5002 if (!D)
5003 return cxstring::createEmpty();
5004
5005 SmallString<128> Str;
5006 llvm::raw_svector_ostream OS(Str);
5007 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5008 D->print(OS, UserPolicy ? *UserPolicy
5009 : getCursorContext(C).getPrintingPolicy());
5010
5011 return cxstring::createDup(OS.str());
5012 }
5013
5014 return cxstring::createEmpty();
5015}
5016
Guy Benyei11169dd2012-12-18 14:30:41 +00005017CXString clang_getCursorDisplayName(CXCursor C) {
5018 if (!clang_isDeclaration(C.kind))
5019 return clang_getCursorSpelling(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05005020
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005021 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005022 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005023 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005024
5025 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005026 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005027 D = FunTmpl->getTemplatedDecl();
Michael Kruse7520cf02020-03-25 09:26:14 -05005028
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005029 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 SmallString<64> Str;
5031 llvm::raw_svector_ostream OS(Str);
5032 OS << *Function;
5033 if (Function->getPrimaryTemplate())
5034 OS << "<>";
5035 OS << "(";
5036 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5037 if (I)
5038 OS << ", ";
5039 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5040 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005041
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 if (Function->isVariadic()) {
5043 if (Function->getNumParams())
5044 OS << ", ";
5045 OS << "...";
5046 }
5047 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005048 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005050
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005051 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 SmallString<64> Str;
5053 llvm::raw_svector_ostream OS(Str);
5054 OS << *ClassTemplate;
5055 OS << "<";
5056 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5057 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5058 if (I)
5059 OS << ", ";
Michael Kruse7520cf02020-03-25 09:26:14 -05005060
Guy Benyei11169dd2012-12-18 14:30:41 +00005061 NamedDecl *Param = Params->getParam(I);
5062 if (Param->getIdentifier()) {
5063 OS << Param->getIdentifier()->getName();
5064 continue;
5065 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005066
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 // There is no parameter name, which makes this tricky. Try to come up
5068 // with something useful that isn't too long.
5069 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
Saar Razff1e0fc2020-01-15 02:48:42 +02005070 if (const auto *TC = TTP->getTypeConstraint()) {
5071 TC->getConceptNameInfo().printName(OS, Policy);
5072 if (TC->hasExplicitTemplateArgs())
5073 OS << "<...>";
5074 } else
Michael Kruse7520cf02020-03-25 09:26:14 -05005075 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5076 else if (NonTypeTemplateParmDecl *NTTP =
5077 dyn_cast<NonTypeTemplateParmDecl>(Param))
Guy Benyei11169dd2012-12-18 14:30:41 +00005078 OS << NTTP->getType().getAsString(Policy);
5079 else
5080 OS << "template<...> class";
5081 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005082
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005084 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005085 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005086
5087 if (const ClassTemplateSpecializationDecl *ClassSpec =
5088 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 // If the type was explicitly written, use that.
5090 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005091 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Serge Pavlov03e672c2017-11-28 16:14:14 +00005092
Benjamin Kramer9170e912013-02-22 15:46:01 +00005093 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 llvm::raw_svector_ostream OS(Str);
5095 OS << *ClassSpec;
Serge Pavlov03e672c2017-11-28 16:14:14 +00005096 printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
5097 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005098 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005100
Guy Benyei11169dd2012-12-18 14:30:41 +00005101 return clang_getCursorSpelling(C);
5102}
Michael Kruse7520cf02020-03-25 09:26:14 -05005103
Guy Benyei11169dd2012-12-18 14:30:41 +00005104CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5105 switch (Kind) {
5106 case CXCursor_FunctionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005107 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 case CXCursor_TypedefDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005109 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 case CXCursor_EnumDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005111 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 case CXCursor_EnumConstantDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005113 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 case CXCursor_StructDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005115 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 case CXCursor_UnionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005117 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 case CXCursor_ClassDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005119 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 case CXCursor_FieldDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005121 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 case CXCursor_VarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005123 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 case CXCursor_ParmDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005125 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 case CXCursor_ObjCInterfaceDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005127 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 case CXCursor_ObjCCategoryDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005129 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 case CXCursor_ObjCProtocolDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005131 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 case CXCursor_ObjCPropertyDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005133 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 case CXCursor_ObjCIvarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005135 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 case CXCursor_ObjCInstanceMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005137 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 case CXCursor_ObjCClassMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005139 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 case CXCursor_ObjCImplementationDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005141 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 case CXCursor_ObjCCategoryImplDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005143 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 case CXCursor_CXXMethod:
Michael Kruse7520cf02020-03-25 09:26:14 -05005145 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 case CXCursor_UnexposedDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005147 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005149 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 case CXCursor_ObjCProtocolRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005151 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 case CXCursor_ObjCClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005153 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 case CXCursor_TypeRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005155 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 case CXCursor_TemplateRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005157 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005159 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005161 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005163 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005165 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005167 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 case CXCursor_IntegerLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005169 return cxstring::createRef("IntegerLiteral");
Leonard Chandb01c3a2018-06-20 17:19:40 +00005170 case CXCursor_FixedPointLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005171 return cxstring::createRef("FixedPointLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 case CXCursor_FloatingLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005173 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 case CXCursor_ImaginaryLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005175 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 case CXCursor_StringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005177 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 case CXCursor_CharacterLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005179 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 case CXCursor_ParenExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005181 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 case CXCursor_UnaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005183 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 case CXCursor_ArraySubscriptExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005185 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00005186 case CXCursor_OMPArraySectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005187 return cxstring::createRef("OMPArraySectionExpr");
Alexey Bataev7ac9efb2020-02-05 09:33:05 -05005188 case CXCursor_OMPArrayShapingExpr:
5189 return cxstring::createRef("OMPArrayShapingExpr");
Alexey Bataev13a15042020-04-01 15:06:38 -04005190 case CXCursor_OMPIteratorExpr:
5191 return cxstring::createRef("OMPIteratorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 case CXCursor_BinaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005193 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 case CXCursor_CompoundAssignOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005195 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 case CXCursor_ConditionalOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005197 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 case CXCursor_CStyleCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005199 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 case CXCursor_CompoundLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005201 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 case CXCursor_InitListExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005203 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 case CXCursor_AddrLabelExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005205 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 case CXCursor_StmtExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005207 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 case CXCursor_GenericSelectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005209 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 case CXCursor_GNUNullExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005211 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 case CXCursor_CXXStaticCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005213 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 case CXCursor_CXXDynamicCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005215 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 case CXCursor_CXXReinterpretCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005217 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 case CXCursor_CXXConstCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005219 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 case CXCursor_CXXFunctionalCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005221 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 case CXCursor_CXXTypeidExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005223 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 case CXCursor_CXXBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005225 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 case CXCursor_CXXNullPtrLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005227 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 case CXCursor_CXXThisExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005229 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 case CXCursor_CXXThrowExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005231 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 case CXCursor_CXXNewExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005233 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 case CXCursor_CXXDeleteExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005235 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 case CXCursor_UnaryExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005237 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 case CXCursor_ObjCStringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005239 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 case CXCursor_ObjCBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005241 return cxstring::createRef("ObjCBoolLiteralExpr");
Erik Pilkington29099de2016-07-16 00:35:23 +00005242 case CXCursor_ObjCAvailabilityCheckExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005243 return cxstring::createRef("ObjCAvailabilityCheckExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00005244 case CXCursor_ObjCSelfExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005245 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 case CXCursor_ObjCEncodeExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005247 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 case CXCursor_ObjCSelectorExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005249 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 case CXCursor_ObjCProtocolExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005251 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 case CXCursor_ObjCBridgedCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005253 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 case CXCursor_BlockExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005255 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 case CXCursor_PackExpansionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005257 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 case CXCursor_SizeOfPackExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005259 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005261 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 case CXCursor_UnexposedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005263 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 case CXCursor_DeclRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005265 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 case CXCursor_MemberRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005267 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005269 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 case CXCursor_ObjCMessageExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005271 return cxstring::createRef("ObjCMessageExpr");
Erik Pilkingtoneee944e2019-07-02 18:28:13 +00005272 case CXCursor_BuiltinBitCastExpr:
5273 return cxstring::createRef("BuiltinBitCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 case CXCursor_UnexposedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005275 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 case CXCursor_DeclStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005277 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 case CXCursor_LabelStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005279 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 case CXCursor_CompoundStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005281 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 case CXCursor_CaseStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005283 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 case CXCursor_DefaultStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005285 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 case CXCursor_IfStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005287 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 case CXCursor_SwitchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005289 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 case CXCursor_WhileStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005291 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 case CXCursor_DoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005293 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 case CXCursor_ForStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005295 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 case CXCursor_GotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005297 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 case CXCursor_IndirectGotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005299 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 case CXCursor_ContinueStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005301 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 case CXCursor_BreakStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005303 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 case CXCursor_ReturnStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005305 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 case CXCursor_GCCAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005307 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 case CXCursor_MSAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005309 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 case CXCursor_ObjCAtTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005311 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 case CXCursor_ObjCAtCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005313 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 case CXCursor_ObjCAtFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005315 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 case CXCursor_ObjCAtThrowStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005317 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 case CXCursor_ObjCAtSynchronizedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005319 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 case CXCursor_ObjCAutoreleasePoolStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005321 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 case CXCursor_ObjCForCollectionStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005323 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 case CXCursor_CXXCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005325 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 case CXCursor_CXXTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005327 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 case CXCursor_CXXForRangeStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005329 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 case CXCursor_SEHTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005331 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 case CXCursor_SEHExceptStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005333 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 case CXCursor_SEHFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005335 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00005336 case CXCursor_SEHLeaveStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005337 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 case CXCursor_NullStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005339 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 case CXCursor_InvalidFile:
Michael Kruse7520cf02020-03-25 09:26:14 -05005341 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005343 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 case CXCursor_NoDeclFound:
Michael Kruse7520cf02020-03-25 09:26:14 -05005345 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 case CXCursor_NotImplemented:
Michael Kruse7520cf02020-03-25 09:26:14 -05005347 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 case CXCursor_TranslationUnit:
Michael Kruse7520cf02020-03-25 09:26:14 -05005349 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 case CXCursor_UnexposedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005351 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 case CXCursor_IBActionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005353 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 case CXCursor_IBOutletAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005355 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 case CXCursor_IBOutletCollectionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005357 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 case CXCursor_CXXFinalAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005359 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 case CXCursor_CXXOverrideAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005361 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005363 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005365 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005366 case CXCursor_PackedAttr:
5367 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00005368 case CXCursor_PureAttr:
5369 return cxstring::createRef("attribute(pure)");
5370 case CXCursor_ConstAttr:
5371 return cxstring::createRef("attribute(const)");
5372 case CXCursor_NoDuplicateAttr:
5373 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00005374 case CXCursor_CUDAConstantAttr:
5375 return cxstring::createRef("attribute(constant)");
5376 case CXCursor_CUDADeviceAttr:
5377 return cxstring::createRef("attribute(device)");
5378 case CXCursor_CUDAGlobalAttr:
5379 return cxstring::createRef("attribute(global)");
5380 case CXCursor_CUDAHostAttr:
5381 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00005382 case CXCursor_CUDASharedAttr:
5383 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00005384 case CXCursor_VisibilityAttr:
5385 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00005386 case CXCursor_DLLExport:
5387 return cxstring::createRef("attribute(dllexport)");
5388 case CXCursor_DLLImport:
5389 return cxstring::createRef("attribute(dllimport)");
Michael Wud092d0b2018-08-03 05:03:22 +00005390 case CXCursor_NSReturnsRetained:
5391 return cxstring::createRef("attribute(ns_returns_retained)");
5392 case CXCursor_NSReturnsNotRetained:
5393 return cxstring::createRef("attribute(ns_returns_not_retained)");
5394 case CXCursor_NSReturnsAutoreleased:
5395 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5396 case CXCursor_NSConsumesSelf:
5397 return cxstring::createRef("attribute(ns_consumes_self)");
5398 case CXCursor_NSConsumed:
5399 return cxstring::createRef("attribute(ns_consumed)");
5400 case CXCursor_ObjCException:
5401 return cxstring::createRef("attribute(objc_exception)");
5402 case CXCursor_ObjCNSObject:
5403 return cxstring::createRef("attribute(NSObject)");
5404 case CXCursor_ObjCIndependentClass:
5405 return cxstring::createRef("attribute(objc_independent_class)");
5406 case CXCursor_ObjCPreciseLifetime:
5407 return cxstring::createRef("attribute(objc_precise_lifetime)");
5408 case CXCursor_ObjCReturnsInnerPointer:
5409 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5410 case CXCursor_ObjCRequiresSuper:
5411 return cxstring::createRef("attribute(objc_requires_super)");
5412 case CXCursor_ObjCRootClass:
5413 return cxstring::createRef("attribute(objc_root_class)");
5414 case CXCursor_ObjCSubclassingRestricted:
5415 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5416 case CXCursor_ObjCExplicitProtocolImpl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005417 return cxstring::createRef(
5418 "attribute(objc_protocol_requires_explicit_implementation)");
Michael Wud092d0b2018-08-03 05:03:22 +00005419 case CXCursor_ObjCDesignatedInitializer:
5420 return cxstring::createRef("attribute(objc_designated_initializer)");
5421 case CXCursor_ObjCRuntimeVisible:
5422 return cxstring::createRef("attribute(objc_runtime_visible)");
5423 case CXCursor_ObjCBoxable:
5424 return cxstring::createRef("attribute(objc_boxable)");
Michael Wu58d837d2018-08-03 05:55:40 +00005425 case CXCursor_FlagEnum:
5426 return cxstring::createRef("attribute(flag_enum)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005427 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005428 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005430 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005432 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005434 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005436 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005438 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005440 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005442 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005444 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005446 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005448 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005450 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005452 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005454 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005456 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005458 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005460 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005462 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005464 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005466 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005468 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005470 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005472 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005474 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005475 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00005476 return cxstring::createRef("OMPParallelDirective");
5477 case CXCursor_OMPSimdDirective:
5478 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00005479 case CXCursor_OMPForDirective:
5480 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00005481 case CXCursor_OMPForSimdDirective:
5482 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00005483 case CXCursor_OMPSectionsDirective:
5484 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00005485 case CXCursor_OMPSectionDirective:
5486 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00005487 case CXCursor_OMPSingleDirective:
5488 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00005489 case CXCursor_OMPMasterDirective:
5490 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00005491 case CXCursor_OMPCriticalDirective:
5492 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00005493 case CXCursor_OMPParallelForDirective:
5494 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00005495 case CXCursor_OMPParallelForSimdDirective:
5496 return cxstring::createRef("OMPParallelForSimdDirective");
cchen47d60942019-12-05 13:43:48 -05005497 case CXCursor_OMPParallelMasterDirective:
5498 return cxstring::createRef("OMPParallelMasterDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00005499 case CXCursor_OMPParallelSectionsDirective:
5500 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00005501 case CXCursor_OMPTaskDirective:
5502 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00005503 case CXCursor_OMPTaskyieldDirective:
5504 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00005505 case CXCursor_OMPBarrierDirective:
5506 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00005507 case CXCursor_OMPTaskwaitDirective:
5508 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00005509 case CXCursor_OMPTaskgroupDirective:
5510 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00005511 case CXCursor_OMPFlushDirective:
5512 return cxstring::createRef("OMPFlushDirective");
Alexey Bataevc112e942020-02-28 09:52:15 -05005513 case CXCursor_OMPDepobjDirective:
5514 return cxstring::createRef("OMPDepobjDirective");
Alexey Bataevfcba7c32020-03-20 07:03:01 -04005515 case CXCursor_OMPScanDirective:
5516 return cxstring::createRef("OMPScanDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00005517 case CXCursor_OMPOrderedDirective:
5518 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00005519 case CXCursor_OMPAtomicDirective:
5520 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00005521 case CXCursor_OMPTargetDirective:
5522 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00005523 case CXCursor_OMPTargetDataDirective:
5524 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00005525 case CXCursor_OMPTargetEnterDataDirective:
5526 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00005527 case CXCursor_OMPTargetExitDataDirective:
5528 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00005529 case CXCursor_OMPTargetParallelDirective:
5530 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00005531 case CXCursor_OMPTargetParallelForDirective:
5532 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00005533 case CXCursor_OMPTargetUpdateDirective:
5534 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00005535 case CXCursor_OMPTeamsDirective:
5536 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00005537 case CXCursor_OMPCancellationPointDirective:
5538 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00005539 case CXCursor_OMPCancelDirective:
5540 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00005541 case CXCursor_OMPTaskLoopDirective:
5542 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005543 case CXCursor_OMPTaskLoopSimdDirective:
5544 return cxstring::createRef("OMPTaskLoopSimdDirective");
Alexey Bataev60e51c42019-10-10 20:13:02 +00005545 case CXCursor_OMPMasterTaskLoopDirective:
5546 return cxstring::createRef("OMPMasterTaskLoopDirective");
Alexey Bataevb8552ab2019-10-18 16:47:35 +00005547 case CXCursor_OMPMasterTaskLoopSimdDirective:
5548 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
Alexey Bataev5bbcead2019-10-14 17:17:41 +00005549 case CXCursor_OMPParallelMasterTaskLoopDirective:
5550 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
Alexey Bataev14a388f2019-10-25 10:27:13 -04005551 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5552 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00005553 case CXCursor_OMPDistributeDirective:
5554 return cxstring::createRef("OMPDistributeDirective");
Carlo Bertolli9925f152016-06-27 14:55:37 +00005555 case CXCursor_OMPDistributeParallelForDirective:
5556 return cxstring::createRef("OMPDistributeParallelForDirective");
Kelvin Li4a39add2016-07-05 05:00:15 +00005557 case CXCursor_OMPDistributeParallelForSimdDirective:
5558 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
Kelvin Li787f3fc2016-07-06 04:45:38 +00005559 case CXCursor_OMPDistributeSimdDirective:
5560 return cxstring::createRef("OMPDistributeSimdDirective");
Kelvin Lia579b912016-07-14 02:54:56 +00005561 case CXCursor_OMPTargetParallelForSimdDirective:
5562 return cxstring::createRef("OMPTargetParallelForSimdDirective");
Kelvin Li986330c2016-07-20 22:57:10 +00005563 case CXCursor_OMPTargetSimdDirective:
5564 return cxstring::createRef("OMPTargetSimdDirective");
Kelvin Li02532872016-08-05 14:37:37 +00005565 case CXCursor_OMPTeamsDistributeDirective:
5566 return cxstring::createRef("OMPTeamsDistributeDirective");
Kelvin Li4e325f72016-10-25 12:50:55 +00005567 case CXCursor_OMPTeamsDistributeSimdDirective:
5568 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
Kelvin Li579e41c2016-11-30 23:51:03 +00005569 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5570 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
Kelvin Li7ade93f2016-12-09 03:24:30 +00005571 case CXCursor_OMPTeamsDistributeParallelForDirective:
5572 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
Kelvin Libf594a52016-12-17 05:48:59 +00005573 case CXCursor_OMPTargetTeamsDirective:
5574 return cxstring::createRef("OMPTargetTeamsDirective");
Kelvin Li83c451e2016-12-25 04:52:54 +00005575 case CXCursor_OMPTargetTeamsDistributeDirective:
5576 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
Kelvin Li80e8f562016-12-29 22:16:30 +00005577 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5578 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
Kelvin Li1851df52017-01-03 05:23:48 +00005579 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5580 return cxstring::createRef(
5581 "OMPTargetTeamsDistributeParallelForSimdDirective");
Kelvin Lida681182017-01-10 18:08:18 +00005582 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5583 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00005584 case CXCursor_OverloadCandidate:
Michael Kruse7520cf02020-03-25 09:26:14 -05005585 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00005586 case CXCursor_TypeAliasTemplateDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005587 return cxstring::createRef("TypeAliasTemplateDecl");
Olivier Goffart81978012016-06-09 16:15:55 +00005588 case CXCursor_StaticAssert:
Michael Kruse7520cf02020-03-25 09:26:14 -05005589 return cxstring::createRef("StaticAssert");
Olivier Goffartd211c642016-11-04 06:29:27 +00005590 case CXCursor_FriendDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005591 return cxstring::createRef("FriendDecl");
Sven van Haastregtdc2c9302019-02-11 11:00:56 +00005592 case CXCursor_ConvergentAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005593 return cxstring::createRef("attribute(convergent)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005594 case CXCursor_WarnUnusedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005595 return cxstring::createRef("attribute(warn_unused)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005596 case CXCursor_WarnUnusedResultAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005597 return cxstring::createRef("attribute(warn_unused_result)");
Emilio Cobos Alvarezcd741272019-03-13 16:16:54 +00005598 case CXCursor_AlignedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005599 return cxstring::createRef("attribute(aligned)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005600 }
5601
5602 llvm_unreachable("Unhandled CXCursorKind");
5603}
5604
5605struct GetCursorData {
5606 SourceLocation TokenBeginLoc;
5607 bool PointsAtMacroArgExpansion;
5608 bool VisitedObjCPropertyImplDecl;
5609 SourceLocation VisitedDeclaratorDeclStartLoc;
5610 CXCursor &BestCursor;
5611
Michael Kruse7520cf02020-03-25 09:26:14 -05005612 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5613 CXCursor &outputCursor)
5614 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005615 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5616 VisitedObjCPropertyImplDecl = false;
5617 }
5618};
5619
Michael Kruse7520cf02020-03-25 09:26:14 -05005620static enum CXChildVisitResult
5621GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005622 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5623 CXCursor *BestCursor = &Data->BestCursor;
5624
5625 // If we point inside a macro argument we should provide info of what the
5626 // token is so use the actual cursor, don't replace it with a macro expansion
5627 // cursor.
5628 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5629 return CXChildVisit_Recurse;
Michael Kruse7520cf02020-03-25 09:26:14 -05005630
Guy Benyei11169dd2012-12-18 14:30:41 +00005631 if (clang_isDeclaration(cursor.kind)) {
5632 // Avoid having the implicit methods override the property decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05005633 if (const ObjCMethodDecl *MD =
5634 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 if (MD->isImplicit())
5636 return CXChildVisit_Break;
5637
Michael Kruse7520cf02020-03-25 09:26:14 -05005638 } else if (const ObjCInterfaceDecl *ID =
5639 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 // Check that when we have multiple @class references in the same line,
5641 // that later ones do not override the previous ones.
5642 // If we have:
5643 // @class Foo, Bar;
5644 // source ranges for both start at '@', so 'Bar' will end up overriding
5645 // 'Foo' even though the cursor location was at 'Foo'.
5646 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5647 BestCursor->kind == CXCursor_ObjCClassRef)
Michael Kruse7520cf02020-03-25 09:26:14 -05005648 if (const ObjCInterfaceDecl *PrevID =
5649 dyn_cast_or_null<ObjCInterfaceDecl>(
5650 getCursorDecl(*BestCursor))) {
5651 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5652 !ID->isThisDeclarationADefinition())
5653 return CXChildVisit_Break;
Guy Benyei11169dd2012-12-18 14:30:41 +00005654 }
5655
Michael Kruse7520cf02020-03-25 09:26:14 -05005656 } else if (const DeclaratorDecl *DD =
5657 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005658 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5659 // Check that when we have multiple declarators in the same line,
5660 // that later ones do not override the previous ones.
5661 // If we have:
5662 // int Foo, Bar;
5663 // source ranges for both start at 'int', so 'Bar' will end up overriding
5664 // 'Foo' even though the cursor location was at 'Foo'.
5665 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5666 return CXChildVisit_Break;
5667 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5668
Michael Kruse7520cf02020-03-25 09:26:14 -05005669 } else if (const ObjCPropertyImplDecl *PropImp =
5670 dyn_cast_or_null<ObjCPropertyImplDecl>(
5671 getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005672 (void)PropImp;
5673 // Check that when we have multiple @synthesize in the same line,
5674 // that later ones do not override the previous ones.
5675 // If we have:
5676 // @synthesize Foo, Bar;
5677 // source ranges for both start at '@', so 'Bar' will end up overriding
5678 // 'Foo' even though the cursor location was at 'Foo'.
5679 if (Data->VisitedObjCPropertyImplDecl)
5680 return CXChildVisit_Break;
5681 Data->VisitedObjCPropertyImplDecl = true;
5682 }
5683 }
5684
5685 if (clang_isExpression(cursor.kind) &&
5686 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005687 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 // Avoid having the cursor of an expression replace the declaration cursor
5689 // when the expression source range overlaps the declaration range.
5690 // This can happen for C++ constructor expressions whose range generally
5691 // include the variable declaration, e.g.:
Michael Kruse7520cf02020-03-25 09:26:14 -05005692 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5693 // cursor.
Guy Benyei11169dd2012-12-18 14:30:41 +00005694 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5695 D->getLocation() == Data->TokenBeginLoc)
5696 return CXChildVisit_Break;
5697 }
5698 }
5699
Michael Kruse7520cf02020-03-25 09:26:14 -05005700 // If our current best cursor is the construction of a temporary object,
5701 // don't replace that cursor with a type reference, because we want
Guy Benyei11169dd2012-12-18 14:30:41 +00005702 // clang_getCursor() to point at the constructor.
5703 if (clang_isExpression(BestCursor->kind) &&
5704 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5705 cursor.kind == CXCursor_TypeRef) {
5706 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5707 // as having the actual point on the type reference.
5708 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5709 return CXChildVisit_Recurse;
5710 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005711
5712 // If we already have an Objective-C superclass reference, don't
5713 // update it further.
5714 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5715 return CXChildVisit_Break;
5716
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 *BestCursor = cursor;
5718 return CXChildVisit_Recurse;
5719}
5720
5721CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005722 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005723 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005725 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005726
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005727 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005728 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5729
5730 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5731 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5732
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005733 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 CXFile SearchFile;
5735 unsigned SearchLine, SearchColumn;
5736 CXFile ResultFile;
5737 unsigned ResultLine, ResultColumn;
5738 CXString SearchFileName, ResultFileName, KindSpelling, USR;
Michael Kruse7520cf02020-03-25 09:26:14 -05005739 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005741
5742 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5743 nullptr);
Michael Kruse7520cf02020-03-25 09:26:14 -05005744 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5745 nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 SearchFileName = clang_getFileName(SearchFile);
5747 ResultFileName = clang_getFileName(ResultFile);
5748 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5749 USR = clang_getCursorUSR(Result);
Michael Kruse7520cf02020-03-25 09:26:14 -05005750 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5751 SearchLine, SearchColumn,
5752 clang_getCString(KindSpelling))
5753 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5754 ResultLine, ResultColumn, clang_getCString(USR),
5755 IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005756 clang_disposeString(SearchFileName);
5757 clang_disposeString(ResultFileName);
5758 clang_disposeString(KindSpelling);
5759 clang_disposeString(USR);
Michael Kruse7520cf02020-03-25 09:26:14 -05005760
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 CXCursor Definition = clang_getCursorDefinition(Result);
5762 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5763 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
Michael Kruse7520cf02020-03-25 09:26:14 -05005764 CXString DefinitionKindSpelling =
5765 clang_getCursorKindSpelling(Definition.kind);
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 CXFile DefinitionFile;
5767 unsigned DefinitionLine, DefinitionColumn;
Michael Kruse7520cf02020-03-25 09:26:14 -05005768 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5769 &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005771 *Log << llvm::format(" -> %s(%s:%d:%d)",
Michael Kruse7520cf02020-03-25 09:26:14 -05005772 clang_getCString(DefinitionKindSpelling),
5773 clang_getCString(DefinitionFileName), DefinitionLine,
5774 DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005775 clang_disposeString(DefinitionFileName);
5776 clang_disposeString(DefinitionKindSpelling);
5777 }
5778 }
5779
5780 return Result;
5781}
5782
5783CXCursor clang_getNullCursor(void) {
5784 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5785}
5786
5787unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005788 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5789 // can't set consistently. For example, when visiting a DeclStmt we will set
5790 // it but we don't set it on the result of clang_getCursorDefinition for
5791 // a reference of the same declaration.
5792 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5793 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5794 // to provide that kind of info.
5795 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005796 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005797 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005798 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005799
Guy Benyei11169dd2012-12-18 14:30:41 +00005800 return X == Y;
5801}
5802
5803unsigned clang_hashCursor(CXCursor C) {
5804 unsigned Index = 0;
5805 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5806 Index = 1;
Michael Kruse7520cf02020-03-25 09:26:14 -05005807
5808 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5809 std::make_pair(C.kind, C.data[Index]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005810}
5811
5812unsigned clang_isInvalid(enum CXCursorKind K) {
5813 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5814}
5815
5816unsigned clang_isDeclaration(enum CXCursorKind K) {
5817 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005818 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5819}
5820
Ivan Donchevskii08ff9102018-01-04 10:59:50 +00005821unsigned clang_isInvalidDeclaration(CXCursor C) {
5822 if (clang_isDeclaration(C.kind)) {
5823 if (const Decl *D = getCursorDecl(C))
5824 return D->isInvalidDecl();
5825 }
5826
5827 return 0;
5828}
5829
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005830unsigned clang_isReference(enum CXCursorKind K) {
5831 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5832}
Guy Benyei11169dd2012-12-18 14:30:41 +00005833
5834unsigned clang_isExpression(enum CXCursorKind K) {
5835 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5836}
5837
5838unsigned clang_isStatement(enum CXCursorKind K) {
5839 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5840}
5841
5842unsigned clang_isAttribute(enum CXCursorKind K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005843 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005844}
5845
5846unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5847 return K == CXCursor_TranslationUnit;
5848}
5849
5850unsigned clang_isPreprocessing(enum CXCursorKind K) {
5851 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5852}
Michael Kruse7520cf02020-03-25 09:26:14 -05005853
Guy Benyei11169dd2012-12-18 14:30:41 +00005854unsigned clang_isUnexposed(enum CXCursorKind K) {
5855 switch (K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005856 case CXCursor_UnexposedDecl:
5857 case CXCursor_UnexposedExpr:
5858 case CXCursor_UnexposedStmt:
5859 case CXCursor_UnexposedAttr:
5860 return true;
5861 default:
5862 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005863 }
5864}
5865
Michael Kruse7520cf02020-03-25 09:26:14 -05005866CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005867
5868CXSourceLocation clang_getCursorLocation(CXCursor C) {
5869 if (clang_isReference(C.kind)) {
5870 switch (C.kind) {
5871 case CXCursor_ObjCSuperClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005872 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5873 getCursorObjCSuperClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005874 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5875 }
5876
5877 case CXCursor_ObjCProtocolRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005878 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5879 getCursorObjCProtocolRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005880 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5881 }
5882
5883 case CXCursor_ObjCClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005884 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5885 getCursorObjCClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005886 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5887 }
5888
5889 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005890 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5892 }
5893
5894 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005895 std::pair<const TemplateDecl *, SourceLocation> P =
5896 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005897 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5898 }
5899
5900 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005901 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005902 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5903 }
5904
5905 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005906 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005907 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5908 }
5909
5910 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005911 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005912 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5913 }
5914
5915 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005916 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005917 if (!BaseSpec)
5918 return clang_getNullLocation();
Michael Kruse7520cf02020-03-25 09:26:14 -05005919
Guy Benyei11169dd2012-12-18 14:30:41 +00005920 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
Michael Kruse7520cf02020-03-25 09:26:14 -05005921 return cxloc::translateSourceLocation(
5922 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005923
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005925 BaseSpec->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005926 }
5927
5928 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005929 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005930 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5931 }
5932
5933 case CXCursor_OverloadedDeclRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005934 return cxloc::translateSourceLocation(
5935 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
Guy Benyei11169dd2012-12-18 14:30:41 +00005936
5937 default:
5938 // FIXME: Need a way to enumerate all non-reference cases.
5939 llvm_unreachable("Missed a reference kind");
5940 }
5941 }
5942
5943 if (clang_isExpression(C.kind))
Michael Kruse7520cf02020-03-25 09:26:14 -05005944 return cxloc::translateSourceLocation(
5945 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
Guy Benyei11169dd2012-12-18 14:30:41 +00005946
5947 if (clang_isStatement(C.kind))
5948 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005949 getCursorStmt(C)->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005950
5951 if (C.kind == CXCursor_PreprocessingDirective) {
5952 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5953 return cxloc::translateSourceLocation(getCursorContext(C), L);
5954 }
5955
5956 if (C.kind == CXCursor_MacroExpansion) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005957 SourceLocation L =
5958 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005959 return cxloc::translateSourceLocation(getCursorContext(C), L);
5960 }
5961
5962 if (C.kind == CXCursor_MacroDefinition) {
5963 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5964 return cxloc::translateSourceLocation(getCursorContext(C), L);
5965 }
5966
5967 if (C.kind == CXCursor_InclusionDirective) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005968 SourceLocation L =
5969 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005970 return cxloc::translateSourceLocation(getCursorContext(C), L);
5971 }
5972
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005973 if (clang_isAttribute(C.kind)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005974 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005975 return cxloc::translateSourceLocation(getCursorContext(C), L);
5976 }
5977
Guy Benyei11169dd2012-12-18 14:30:41 +00005978 if (!clang_isDeclaration(C.kind))
5979 return clang_getNullLocation();
5980
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005981 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005982 if (!D)
5983 return clang_getNullLocation();
5984
5985 SourceLocation Loc = D->getLocation();
5986 // FIXME: Multiple variables declared in a single declaration
5987 // currently lack the information needed to correctly determine their
5988 // ranges when accounting for the type-specifier. We use context
5989 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5990 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005991 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005992 if (!cxcursor::isFirstInDeclGroup(C))
5993 Loc = VD->getLocation();
5994 }
5995
5996 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005997 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005998 Loc = MD->getSelectorStartLoc();
5999
6000 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
6001}
6002
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00006003} // end extern "C"
6004
Guy Benyei11169dd2012-12-18 14:30:41 +00006005CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6006 assert(TU);
6007
6008 // Guard against an invalid SourceLocation, or we may assert in one
6009 // of the following calls.
6010 if (SLoc.isInvalid())
6011 return clang_getNullCursor();
6012
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006013 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006014
6015 // Translate the given source location to make it point at the beginning of
6016 // the token under the cursor.
6017 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6018 CXXUnit->getASTContext().getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05006019
Guy Benyei11169dd2012-12-18 14:30:41 +00006020 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6021 if (SLoc.isValid()) {
6022 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6023 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Michael Kruse7520cf02020-03-25 09:26:14 -05006024 /*VisitPreprocessorLast=*/true,
Guy Benyei11169dd2012-12-18 14:30:41 +00006025 /*VisitIncludedEntities=*/false,
6026 SourceLocation(SLoc));
6027 CursorVis.visitFileRegion();
6028 }
6029
6030 return Result;
6031}
6032
6033static SourceRange getRawCursorExtent(CXCursor C) {
6034 if (clang_isReference(C.kind)) {
6035 switch (C.kind) {
6036 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05006037 return getCursorObjCSuperClassRef(C).second;
Guy Benyei11169dd2012-12-18 14:30:41 +00006038
6039 case CXCursor_ObjCProtocolRef:
6040 return getCursorObjCProtocolRef(C).second;
6041
6042 case CXCursor_ObjCClassRef:
6043 return getCursorObjCClassRef(C).second;
6044
6045 case CXCursor_TypeRef:
6046 return getCursorTypeRef(C).second;
6047
6048 case CXCursor_TemplateRef:
6049 return getCursorTemplateRef(C).second;
6050
6051 case CXCursor_NamespaceRef:
6052 return getCursorNamespaceRef(C).second;
6053
6054 case CXCursor_MemberRef:
6055 return getCursorMemberRef(C).second;
6056
6057 case CXCursor_CXXBaseSpecifier:
6058 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6059
6060 case CXCursor_LabelRef:
6061 return getCursorLabelRef(C).second;
6062
6063 case CXCursor_OverloadedDeclRef:
6064 return getCursorOverloadedDeclRef(C).second;
6065
6066 case CXCursor_VariableRef:
6067 return getCursorVariableRef(C).second;
Michael Kruse7520cf02020-03-25 09:26:14 -05006068
Guy Benyei11169dd2012-12-18 14:30:41 +00006069 default:
6070 // FIXME: Need a way to enumerate all non-reference cases.
6071 llvm_unreachable("Missed a reference kind");
6072 }
6073 }
6074
6075 if (clang_isExpression(C.kind))
6076 return getCursorExpr(C)->getSourceRange();
6077
6078 if (clang_isStatement(C.kind))
6079 return getCursorStmt(C)->getSourceRange();
6080
6081 if (clang_isAttribute(C.kind))
6082 return getCursorAttr(C)->getRange();
6083
6084 if (C.kind == CXCursor_PreprocessingDirective)
6085 return cxcursor::getCursorPreprocessingDirective(C);
6086
6087 if (C.kind == CXCursor_MacroExpansion) {
6088 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006089 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 return TU->mapRangeFromPreamble(Range);
6091 }
6092
6093 if (C.kind == CXCursor_MacroDefinition) {
6094 ASTUnit *TU = getCursorASTUnit(C);
6095 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6096 return TU->mapRangeFromPreamble(Range);
6097 }
6098
6099 if (C.kind == CXCursor_InclusionDirective) {
6100 ASTUnit *TU = getCursorASTUnit(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05006101 SourceRange Range =
6102 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006103 return TU->mapRangeFromPreamble(Range);
6104 }
6105
6106 if (C.kind == CXCursor_TranslationUnit) {
6107 ASTUnit *TU = getCursorASTUnit(C);
6108 FileID MainID = TU->getSourceManager().getMainFileID();
6109 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6110 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6111 return SourceRange(Start, End);
6112 }
6113
6114 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006115 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006116 if (!D)
6117 return SourceRange();
6118
6119 SourceRange R = D->getSourceRange();
6120 // FIXME: Multiple variables declared in a single declaration
6121 // currently lack the information needed to correctly determine their
6122 // ranges when accounting for the type-specifier. We use context
6123 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6124 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006125 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 if (!cxcursor::isFirstInDeclGroup(C))
6127 R.setBegin(VD->getLocation());
6128 }
6129 return R;
6130 }
6131 return SourceRange();
6132}
6133
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006134/// Retrieves the "raw" cursor extent, which is then extended to include
Guy Benyei11169dd2012-12-18 14:30:41 +00006135/// the decl-specifier-seq for declarations.
6136static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6137 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006138 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 if (!D)
6140 return SourceRange();
6141
6142 SourceRange R = D->getSourceRange();
6143
6144 // Adjust the start of the location for declarations preceded by
6145 // declaration specifiers.
6146 SourceLocation StartLoc;
6147 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6148 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006149 StartLoc = TI->getTypeLoc().getBeginLoc();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006150 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006151 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006152 StartLoc = TI->getTypeLoc().getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 }
6154
6155 if (StartLoc.isValid() && R.getBegin().isValid() &&
6156 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6157 R.setBegin(StartLoc);
6158
6159 // FIXME: Multiple variables declared in a single declaration
6160 // currently lack the information needed to correctly determine their
6161 // ranges when accounting for the type-specifier. We use context
6162 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6163 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006164 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 if (!cxcursor::isFirstInDeclGroup(C))
6166 R.setBegin(VD->getLocation());
6167 }
6168
Michael Kruse7520cf02020-03-25 09:26:14 -05006169 return R;
Guy Benyei11169dd2012-12-18 14:30:41 +00006170 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006171
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 return getRawCursorExtent(C);
6173}
6174
Guy Benyei11169dd2012-12-18 14:30:41 +00006175CXSourceRange clang_getCursorExtent(CXCursor C) {
6176 SourceRange R = getRawCursorExtent(C);
6177 if (R.isInvalid())
6178 return clang_getNullRange();
6179
6180 return cxloc::translateSourceRange(getCursorContext(C), R);
6181}
6182
6183CXCursor clang_getCursorReferenced(CXCursor C) {
6184 if (clang_isInvalid(C.kind))
6185 return clang_getNullCursor();
6186
6187 CXTranslationUnit tu = getCursorTU(C);
6188 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006189 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 if (!D)
6191 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006192 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006193 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006194 if (const ObjCPropertyImplDecl *PropImpl =
6195 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006196 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6197 return MakeCXCursor(Property, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006198
Guy Benyei11169dd2012-12-18 14:30:41 +00006199 return C;
6200 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006201
Guy Benyei11169dd2012-12-18 14:30:41 +00006202 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006203 const Expr *E = getCursorExpr(C);
6204 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00006205 if (D) {
6206 CXCursor declCursor = MakeCXCursor(D, tu);
6207 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6208 declCursor);
6209 return declCursor;
6210 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006211
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006212 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00006213 return MakeCursorOverloadedDeclRef(Ovl, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006214
Guy Benyei11169dd2012-12-18 14:30:41 +00006215 return clang_getNullCursor();
6216 }
6217
6218 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006219 const Stmt *S = getCursorStmt(C);
6220 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00006221 if (LabelDecl *label = Goto->getLabel())
6222 if (LabelStmt *labelS = label->getStmt())
Michael Kruse7520cf02020-03-25 09:26:14 -05006223 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006224
6225 return clang_getNullCursor();
6226 }
Richard Smith66a81862015-05-04 02:25:31 +00006227
Guy Benyei11169dd2012-12-18 14:30:41 +00006228 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00006229 if (const MacroDefinitionRecord *Def =
6230 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006231 return MakeMacroDefinitionCursor(Def, tu);
6232 }
6233
6234 if (!clang_isReference(C.kind))
6235 return clang_getNullCursor();
6236
6237 switch (C.kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006238 case CXCursor_ObjCSuperClassRef:
6239 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006240
Michael Kruse7520cf02020-03-25 09:26:14 -05006241 case CXCursor_ObjCProtocolRef: {
6242 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6243 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6244 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006245
Michael Kruse7520cf02020-03-25 09:26:14 -05006246 return MakeCXCursor(Prot, tu);
6247 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006248
Michael Kruse7520cf02020-03-25 09:26:14 -05006249 case CXCursor_ObjCClassRef: {
6250 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6251 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6252 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006253
Michael Kruse7520cf02020-03-25 09:26:14 -05006254 return MakeCXCursor(Class, tu);
6255 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006256
Michael Kruse7520cf02020-03-25 09:26:14 -05006257 case CXCursor_TypeRef:
6258 return MakeCXCursor(getCursorTypeRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006259
Michael Kruse7520cf02020-03-25 09:26:14 -05006260 case CXCursor_TemplateRef:
6261 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006262
Michael Kruse7520cf02020-03-25 09:26:14 -05006263 case CXCursor_NamespaceRef:
6264 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006265
Michael Kruse7520cf02020-03-25 09:26:14 -05006266 case CXCursor_MemberRef:
6267 return MakeCXCursor(getCursorMemberRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006268
Michael Kruse7520cf02020-03-25 09:26:14 -05006269 case CXCursor_CXXBaseSpecifier: {
6270 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6271 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6272 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006273
Michael Kruse7520cf02020-03-25 09:26:14 -05006274 case CXCursor_LabelRef:
6275 // FIXME: We end up faking the "parent" declaration here because we
6276 // don't want to make CXCursor larger.
6277 return MakeCXCursor(
6278 getCursorLabelRef(C).first,
6279 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006280
Michael Kruse7520cf02020-03-25 09:26:14 -05006281 case CXCursor_OverloadedDeclRef:
6282 return C;
Guy Benyei11169dd2012-12-18 14:30:41 +00006283
Michael Kruse7520cf02020-03-25 09:26:14 -05006284 case CXCursor_VariableRef:
6285 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6286
6287 default:
6288 // We would prefer to enumerate all non-reference cursor kinds here.
6289 llvm_unreachable("Unhandled reference cursor kind");
Guy Benyei11169dd2012-12-18 14:30:41 +00006290 }
6291}
6292
6293CXCursor clang_getCursorDefinition(CXCursor C) {
6294 if (clang_isInvalid(C.kind))
6295 return clang_getNullCursor();
6296
6297 CXTranslationUnit TU = getCursorTU(C);
6298
6299 bool WasReference = false;
6300 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6301 C = clang_getCursorReferenced(C);
6302 WasReference = true;
6303 }
6304
6305 if (C.kind == CXCursor_MacroExpansion)
6306 return clang_getCursorReferenced(C);
6307
6308 if (!clang_isDeclaration(C.kind))
6309 return clang_getNullCursor();
6310
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006311 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006312 if (!D)
6313 return clang_getNullCursor();
6314
6315 switch (D->getKind()) {
6316 // Declaration kinds that don't really separate the notions of
6317 // declaration and definition.
6318 case Decl::Namespace:
6319 case Decl::Typedef:
6320 case Decl::TypeAlias:
6321 case Decl::TypeAliasTemplate:
6322 case Decl::TemplateTypeParm:
6323 case Decl::EnumConstant:
6324 case Decl::Field:
Richard Smithbdb84f32016-07-22 23:36:59 +00006325 case Decl::Binding:
John McCall5e77d762013-04-16 07:28:30 +00006326 case Decl::MSProperty:
Richard Smithbab6df82020-04-11 22:15:29 -07006327 case Decl::MSGuid:
Guy Benyei11169dd2012-12-18 14:30:41 +00006328 case Decl::IndirectField:
6329 case Decl::ObjCIvar:
6330 case Decl::ObjCAtDefsField:
6331 case Decl::ImplicitParam:
6332 case Decl::ParmVar:
6333 case Decl::NonTypeTemplateParm:
6334 case Decl::TemplateTemplateParm:
6335 case Decl::ObjCCategoryImpl:
6336 case Decl::ObjCImplementation:
6337 case Decl::AccessSpec:
6338 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006339 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006340 case Decl::ObjCPropertyImpl:
6341 case Decl::FileScopeAsm:
6342 case Decl::StaticAssert:
6343 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006344 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006345 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006346 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006347 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006348 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006349 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006350 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006351 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006352 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006353 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006354 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006355 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006356 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006357 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006358 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006359 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006360 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006361 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006362 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006363 return C;
6364
6365 // Declaration kinds that don't make any sense here, but are
6366 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006367 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006368 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006369 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006370 break;
6371
6372 // Declaration kinds for which the definition is not resolvable.
6373 case Decl::UnresolvedUsingTypename:
6374 case Decl::UnresolvedUsingValue:
6375 break;
6376
6377 case Decl::UsingDirective:
6378 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6379 TU);
6380
6381 case Decl::NamespaceAlias:
6382 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6383
6384 case Decl::Enum:
6385 case Decl::Record:
6386 case Decl::CXXRecord:
6387 case Decl::ClassTemplateSpecialization:
6388 case Decl::ClassTemplatePartialSpecialization:
6389 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6390 return MakeCXCursor(Def, TU);
6391 return clang_getNullCursor();
6392
6393 case Decl::Function:
6394 case Decl::CXXMethod:
6395 case Decl::CXXConstructor:
6396 case Decl::CXXDestructor:
6397 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006398 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006399 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006400 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006401 return clang_getNullCursor();
6402 }
6403
Larisse Voufo39a1e502013-08-06 01:03:05 +00006404 case Decl::Var:
6405 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006406 case Decl::VarTemplatePartialSpecialization:
6407 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006408 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006409 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006410 return MakeCXCursor(Def, TU);
6411 return clang_getNullCursor();
6412 }
6413
6414 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006415 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006416 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6417 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6418 return clang_getNullCursor();
6419 }
6420
6421 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006422 if (RecordDecl *Def =
6423 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006424 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6425 TU);
6426 return clang_getNullCursor();
6427 }
6428
Larisse Voufo39a1e502013-08-06 01:03:05 +00006429 case Decl::VarTemplate: {
6430 if (VarDecl *Def =
6431 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6432 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6433 return clang_getNullCursor();
6434 }
6435
Guy Benyei11169dd2012-12-18 14:30:41 +00006436 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006437 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6438 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006439
6440 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006441 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006442 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006443 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006444
6445 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006446 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006447 if (Method->isThisDeclarationADefinition())
6448 return C;
6449
6450 // Dig out the method definition in the associated
6451 // @implementation, if we have it.
6452 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006453 if (const ObjCInterfaceDecl *Class =
6454 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006455 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006456 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6457 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006458 if (Def->isThisDeclarationADefinition())
6459 return MakeCXCursor(Def, TU);
6460
6461 return clang_getNullCursor();
6462 }
6463
6464 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006465 if (ObjCCategoryImplDecl *Impl =
6466 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006467 return MakeCXCursor(Impl, TU);
6468 return clang_getNullCursor();
6469
6470 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006471 if (const ObjCProtocolDecl *Def =
6472 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006473 return MakeCXCursor(Def, TU);
6474 return clang_getNullCursor();
6475
6476 case Decl::ObjCInterface: {
6477 // There are two notions of a "definition" for an Objective-C
6478 // class: the interface and its implementation. When we resolved a
6479 // reference to an Objective-C class, produce the @interface as
6480 // the definition; when we were provided with the interface,
6481 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006482 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006483 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006484 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006485 return MakeCXCursor(Def, TU);
6486 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6487 return MakeCXCursor(Impl, TU);
6488 return clang_getNullCursor();
6489 }
6490
6491 case Decl::ObjCProperty:
6492 // FIXME: We don't really know where to find the
6493 // ObjCPropertyImplDecls that implement this property.
6494 return clang_getNullCursor();
6495
6496 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006497 if (const ObjCInterfaceDecl *Class =
6498 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006499 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006500 return MakeCXCursor(Def, TU);
6501
6502 return clang_getNullCursor();
6503
6504 case Decl::Friend:
6505 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6506 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6507 return clang_getNullCursor();
6508
6509 case Decl::FriendTemplate:
6510 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6511 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6512 return clang_getNullCursor();
6513 }
6514
6515 return clang_getNullCursor();
6516}
6517
6518unsigned clang_isCursorDefinition(CXCursor C) {
6519 if (!clang_isDeclaration(C.kind))
6520 return 0;
6521
6522 return clang_getCursorDefinition(C) == C;
6523}
6524
6525CXCursor clang_getCanonicalCursor(CXCursor C) {
6526 if (!clang_isDeclaration(C.kind))
6527 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006528
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006529 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006530 if (const ObjCCategoryImplDecl *CatImplD =
6531 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006532 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6533 return MakeCXCursor(CatD, getCursorTU(C));
6534
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006535 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6536 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006537 return MakeCXCursor(IFD, getCursorTU(C));
6538
6539 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6540 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006541
Guy Benyei11169dd2012-12-18 14:30:41 +00006542 return C;
6543}
6544
6545int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6546 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6547}
Michael Kruse7520cf02020-03-25 09:26:14 -05006548
Guy Benyei11169dd2012-12-18 14:30:41 +00006549unsigned clang_getNumOverloadedDecls(CXCursor C) {
6550 if (C.kind != CXCursor_OverloadedDeclRef)
6551 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006552
Guy Benyei11169dd2012-12-18 14:30:41 +00006553 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006554 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006555 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006556
6557 if (OverloadedTemplateStorage *S =
6558 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006559 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006560
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006561 const Decl *D = Storage.get<const Decl *>();
6562 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006563 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006564
Guy Benyei11169dd2012-12-18 14:30:41 +00006565 return 0;
6566}
6567
6568CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6569 if (cursor.kind != CXCursor_OverloadedDeclRef)
6570 return clang_getNullCursor();
6571
6572 if (index >= clang_getNumOverloadedDecls(cursor))
6573 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006574
Guy Benyei11169dd2012-12-18 14:30:41 +00006575 CXTranslationUnit TU = getCursorTU(cursor);
6576 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006577 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006578 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006579
6580 if (OverloadedTemplateStorage *S =
6581 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006582 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006583
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006584 const Decl *D = Storage.get<const Decl *>();
6585 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006586 // FIXME: This is, unfortunately, linear time.
6587 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6588 std::advance(Pos, index);
6589 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6590 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006591
Guy Benyei11169dd2012-12-18 14:30:41 +00006592 return clang_getNullCursor();
6593}
Michael Kruse7520cf02020-03-25 09:26:14 -05006594
6595void clang_getDefinitionSpellingAndExtent(
6596 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6597 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006598 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006599 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006600 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6601
6602 SourceManager &SM = FD->getASTContext().getSourceManager();
6603 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6604 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6605 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6606 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6607 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6608 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6609}
6610
Guy Benyei11169dd2012-12-18 14:30:41 +00006611CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6612 unsigned PieceIndex) {
6613 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006614
Guy Benyei11169dd2012-12-18 14:30:41 +00006615 switch (C.kind) {
6616 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006617 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006618 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6619 E->getQualifierLoc().getSourceRange());
6620 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006621
Guy Benyei11169dd2012-12-18 14:30:41 +00006622 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006623 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6624 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6625 Pieces =
6626 buildPieces(NameFlags, false, E->getNameInfo(),
6627 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6628 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006629 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006630
Guy Benyei11169dd2012-12-18 14:30:41 +00006631 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006632 if (const CXXOperatorCallExpr *OCE =
6633 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006634 const Expr *Callee = OCE->getCallee();
6635 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006636 Callee = ICE->getSubExpr();
6637
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006638 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006639 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6640 DRE->getQualifierLoc().getSourceRange());
6641 }
6642 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006643
Guy Benyei11169dd2012-12-18 14:30:41 +00006644 default:
6645 break;
6646 }
6647
6648 if (Pieces.empty()) {
6649 if (PieceIndex == 0)
6650 return clang_getCursorExtent(C);
6651 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006652 SourceRange R = Pieces[PieceIndex];
6653 if (R.isValid())
6654 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006655 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006656
Guy Benyei11169dd2012-12-18 14:30:41 +00006657 return clang_getNullRange();
6658}
6659
6660void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006661 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6662 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006663}
6664
Michael Kruse7520cf02020-03-25 09:26:14 -05006665void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006666 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006667 llvm::llvm_execute_on_thread(fn, user_data,
6668 stack_size == 0
6669 ? clang::DesiredStackSize
6670 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006671}
6672
Guy Benyei11169dd2012-12-18 14:30:41 +00006673//===----------------------------------------------------------------------===//
6674// Token-based Operations.
6675//===----------------------------------------------------------------------===//
6676
6677/* CXToken layout:
6678 * int_data[0]: a CXTokenKind
6679 * int_data[1]: starting token location
6680 * int_data[2]: token length
6681 * int_data[3]: reserved
6682 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6683 * otherwise unused.
6684 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006685CXTokenKind clang_getTokenKind(CXToken CXTok) {
6686 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6687}
6688
6689CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6690 switch (clang_getTokenKind(CXTok)) {
6691 case CXToken_Identifier:
6692 case CXToken_Keyword:
6693 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006694 return cxstring::createRef(
6695 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006696
6697 case CXToken_Literal: {
6698 // We have stashed the starting pointer in the ptr_data field. Use it.
6699 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006700 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006701 }
6702
6703 case CXToken_Punctuation:
6704 case CXToken_Comment:
6705 break;
6706 }
6707
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006708 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006709 LOG_BAD_TU(TU);
6710 return cxstring::createEmpty();
6711 }
6712
Guy Benyei11169dd2012-12-18 14:30:41 +00006713 // We have to find the starting buffer pointer the hard way, by
6714 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006715 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006716 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006717 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006718
6719 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006720 std::pair<FileID, unsigned> LocInfo =
6721 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006722 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006723 StringRef Buffer =
6724 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006725 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006726 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006727
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006728 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006729}
6730
6731CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006732 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006733 LOG_BAD_TU(TU);
6734 return clang_getNullLocation();
6735 }
6736
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006737 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006738 if (!CXXUnit)
6739 return clang_getNullLocation();
6740
Michael Kruse7520cf02020-03-25 09:26:14 -05006741 return cxloc::translateSourceLocation(
6742 CXXUnit->getASTContext(),
6743 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006744}
6745
6746CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006747 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006748 LOG_BAD_TU(TU);
6749 return clang_getNullRange();
6750 }
6751
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006752 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006753 if (!CXXUnit)
6754 return clang_getNullRange();
6755
Michael Kruse7520cf02020-03-25 09:26:14 -05006756 return cxloc::translateSourceRange(
6757 CXXUnit->getASTContext(),
6758 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006759}
6760
6761static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6762 SmallVectorImpl<CXToken> &CXTokens) {
6763 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006764 std::pair<FileID, unsigned> BeginLocInfo =
6765 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6766 std::pair<FileID, unsigned> EndLocInfo =
6767 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006768
6769 // Cannot tokenize across files.
6770 if (BeginLocInfo.first != EndLocInfo.first)
6771 return;
6772
6773 // Create a lexer
6774 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006775 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006776 if (Invalid)
6777 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006778
Guy Benyei11169dd2012-12-18 14:30:41 +00006779 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006780 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6781 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006782 Lex.SetCommentRetentionState(true);
6783
6784 // Lex tokens until we hit the end of the range.
6785 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6786 Token Tok;
6787 bool previousWasAt = false;
6788 do {
6789 // Lex the next token
6790 Lex.LexFromRawLexer(Tok);
6791 if (Tok.is(tok::eof))
6792 break;
6793
6794 // Initialize the CXToken.
6795 CXToken CXTok;
6796
6797 // - Common fields
6798 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6799 CXTok.int_data[2] = Tok.getLength();
6800 CXTok.int_data[3] = 0;
6801
6802 // - Kind-specific fields
6803 if (Tok.isLiteral()) {
6804 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006805 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006806 } else if (Tok.is(tok::raw_identifier)) {
6807 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006808 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006809
6810 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6811 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006812 } else {
6813 CXTok.int_data[0] =
6814 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006815 }
6816 CXTok.ptr_data = II;
6817 } else if (Tok.is(tok::comment)) {
6818 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006819 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006820 } else {
6821 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006822 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006823 }
6824 CXTokens.push_back(CXTok);
6825 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006826 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006827}
6828
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006829CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006830 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006831
6832 if (isNotUsableTU(TU)) {
6833 LOG_BAD_TU(TU);
6834 return NULL;
6835 }
6836
6837 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6838 if (!CXXUnit)
6839 return NULL;
6840
6841 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6842 if (Begin.isInvalid())
6843 return NULL;
6844 SourceManager &SM = CXXUnit->getSourceManager();
6845 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006846 DecomposedEnd.second +=
6847 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006848
Michael Kruse7520cf02020-03-25 09:26:14 -05006849 SourceLocation End =
6850 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006851
6852 SmallVector<CXToken, 32> CXTokens;
6853 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6854
6855 if (CXTokens.empty())
6856 return NULL;
6857
6858 CXTokens.resize(1);
6859 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6860
6861 memmove(Token, CXTokens.data(), sizeof(CXToken));
6862 return Token;
6863}
6864
Michael Kruse7520cf02020-03-25 09:26:14 -05006865void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6866 unsigned *NumTokens) {
6867 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006868
Guy Benyei11169dd2012-12-18 14:30:41 +00006869 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006870 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006871 if (NumTokens)
6872 *NumTokens = 0;
6873
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006874 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006875 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006876 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006877 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006878
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006879 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006880 if (!CXXUnit || !Tokens || !NumTokens)
6881 return;
6882
6883 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006884
Guy Benyei11169dd2012-12-18 14:30:41 +00006885 SourceRange R = cxloc::translateCXSourceRange(Range);
6886 if (R.isInvalid())
6887 return;
6888
6889 SmallVector<CXToken, 32> CXTokens;
6890 getTokens(CXXUnit, R, CXTokens);
6891
6892 if (CXTokens.empty())
6893 return;
6894
Serge Pavlov52525732018-02-21 02:02:39 +00006895 *Tokens = static_cast<CXToken *>(
6896 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006897 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6898 *NumTokens = CXTokens.size();
6899}
6900
Michael Kruse7520cf02020-03-25 09:26:14 -05006901void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6902 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006903 free(Tokens);
6904}
6905
Guy Benyei11169dd2012-12-18 14:30:41 +00006906//===----------------------------------------------------------------------===//
6907// Token annotation APIs.
6908//===----------------------------------------------------------------------===//
6909
Guy Benyei11169dd2012-12-18 14:30:41 +00006910static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6911 CXCursor parent,
6912 CXClientData client_data);
6913static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6914 CXClientData client_data);
6915
6916namespace {
6917class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006918 CXToken *Tokens;
6919 CXCursor *Cursors;
6920 unsigned NumTokens;
6921 unsigned TokIdx;
6922 unsigned PreprocessingTokIdx;
6923 CursorVisitor AnnotateVis;
6924 SourceManager &SrcMgr;
6925 bool HasContextSensitiveKeywords;
6926
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006927 struct PostChildrenAction {
6928 CXCursor cursor;
6929 enum Action { Invalid, Ignore, Postpone } action;
6930 };
6931 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6932
Guy Benyei11169dd2012-12-18 14:30:41 +00006933 struct PostChildrenInfo {
6934 CXCursor Cursor;
6935 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006936 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006937 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006938 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006939 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006940 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006941
6942 CXToken &getTok(unsigned Idx) {
6943 assert(Idx < NumTokens);
6944 return Tokens[Idx];
6945 }
6946 const CXToken &getTok(unsigned Idx) const {
6947 assert(Idx < NumTokens);
6948 return Tokens[Idx];
6949 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006950 bool MoreTokens() const { return TokIdx < NumTokens; }
6951 unsigned NextToken() const { return TokIdx; }
6952 void AdvanceToken() { ++TokIdx; }
6953 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006954 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006955 }
6956 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006957 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006958 }
6959 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006960 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006961 }
6962
6963 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006964 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006965 SourceRange);
6966
6967public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006968 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006969 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05006970 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
6971 PreprocessingTokIdx(0),
6972 AnnotateVis(TU, AnnotateTokensVisitor, this,
6973 /*VisitPreprocessorLast=*/true,
6974 /*VisitIncludedEntities=*/false, RegionOfInterest,
6975 /*VisitDeclsOnly=*/false,
6976 AnnotateTokensPostChildrenVisitor),
6977 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
6978 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00006979
6980 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6981 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006982 bool IsIgnoredChildCursor(CXCursor cursor) const;
6983 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
6984
Guy Benyei11169dd2012-12-18 14:30:41 +00006985 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006986 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
6987 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
6988
Guy Benyei11169dd2012-12-18 14:30:41 +00006989 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05006990
6991 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00006992 /// context-sensitive keywords.
6993 bool hasContextSensitiveKeywords() const {
6994 return HasContextSensitiveKeywords;
6995 }
6996
Michael Kruse7520cf02020-03-25 09:26:14 -05006997 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00006998};
Michael Kruse7520cf02020-03-25 09:26:14 -05006999} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00007000
7001void AnnotateTokensWorker::AnnotateTokens() {
7002 // Walk the AST within the region of interest, annotating tokens
7003 // along the way.
7004 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007005}
Guy Benyei11169dd2012-12-18 14:30:41 +00007006
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007007bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7008 if (PostChildrenInfos.empty())
7009 return false;
7010
7011 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7012 if (ChildAction.cursor == cursor &&
7013 ChildAction.action == PostChildrenAction::Ignore) {
7014 return true;
7015 }
7016 }
7017
7018 return false;
7019}
7020
7021const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7022 if (!clang_isExpression(Cursor.kind))
7023 return nullptr;
7024
7025 const Expr *E = getCursorExpr(Cursor);
7026 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7027 const OverloadedOperatorKind Kind = OCE->getOperator();
7028 if (Kind == OO_Call || Kind == OO_Subscript)
7029 return OCE;
7030 }
7031
7032 return nullptr;
7033}
7034
7035AnnotateTokensWorker::PostChildrenActions
7036AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7037 PostChildrenActions actions;
7038
7039 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7040 // visited before the arguments to the operator call. For the Call and
7041 // Subscript operator the range of this DeclRefExpr includes the whole call
7042 // expression, so that all tokens in that range would be mapped to the
7043 // operator function, including the tokens of the arguments. To avoid that,
7044 // ensure to visit this DeclRefExpr as last node.
7045 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7046 const Expr *Callee = OCE->getCallee();
7047 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7048 const Expr *SubExpr = ICE->getSubExpr();
7049 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007050 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007051 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7052
7053 // Visit the DeclRefExpr as last.
7054 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7055 actions.push_back({cxChild, PostChildrenAction::Postpone});
7056
7057 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7058 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7059 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7060 actions.push_back({cxChild, PostChildrenAction::Ignore});
7061 }
7062 }
7063 }
7064
7065 return actions;
7066}
7067
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007068static inline void updateCursorAnnotation(CXCursor &Cursor,
7069 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007070 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007071 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007072 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007073}
7074
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007075/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007076//// between the cursor location and the source range is the same as
7077/// \arg compResult.
7078///
7079/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7080/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007081void AnnotateTokensWorker::annotateAndAdvanceTokens(
7082 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007083 while (MoreTokens()) {
7084 const unsigned I = NextToken();
7085 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007086 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7087 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007088
7089 SourceLocation TokLoc = GetTokenLoc(I);
7090 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007091 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007092 AdvanceToken();
7093 continue;
7094 }
7095 break;
7096 }
7097}
7098
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007099/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007100/// \returns true if it advanced beyond all macro tokens, false otherwise.
7101bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007102 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007103 assert(MoreTokens());
7104 assert(isFunctionMacroToken(NextToken()) &&
7105 "Should be called only for macro arg tokens");
7106
7107 // This works differently than annotateAndAdvanceTokens; because expanded
7108 // macro arguments can have arbitrary translation-unit source order, we do not
7109 // advance the token index one by one until a token fails the range test.
7110 // We only advance once past all of the macro arg tokens if all of them
7111 // pass the range test. If one of them fails we keep the token index pointing
7112 // at the start of the macro arg tokens so that the failing token will be
7113 // annotated by a subsequent annotation try.
7114
7115 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007116
Guy Benyei11169dd2012-12-18 14:30:41 +00007117 unsigned I = NextToken();
7118 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7119 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7120 if (TokLoc.isFileID())
7121 continue; // not macro arg token, it's parens or comma.
7122 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7123 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7124 Cursors[I] = updateC;
7125 } else
7126 atLeastOneCompFail = true;
7127 }
7128
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007129 if (atLeastOneCompFail)
7130 return false;
7131
7132 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7133 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007134}
7135
Michael Kruse7520cf02020-03-25 09:26:14 -05007136enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7137 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007138 SourceRange cursorRange = getRawCursorExtent(cursor);
7139 if (cursorRange.isInvalid())
7140 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007141
7142 if (IsIgnoredChildCursor(cursor))
7143 return CXChildVisit_Continue;
7144
Guy Benyei11169dd2012-12-18 14:30:41 +00007145 if (!HasContextSensitiveKeywords) {
7146 // Objective-C properties can have context-sensitive keywords.
7147 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007148 if (const ObjCPropertyDecl *Property =
7149 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7150 HasContextSensitiveKeywords =
7151 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007152 }
7153 // Objective-C methods can have context-sensitive keywords.
7154 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7155 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007156 if (const ObjCMethodDecl *Method =
7157 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007158 if (Method->getObjCDeclQualifier())
7159 HasContextSensitiveKeywords = true;
7160 else {
David Majnemer59f77922016-06-24 04:05:48 +00007161 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007162 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007163 HasContextSensitiveKeywords = true;
7164 break;
7165 }
7166 }
7167 }
7168 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007169 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007170 // C++ methods can have context-sensitive keywords.
7171 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007172 if (const CXXMethodDecl *Method =
7173 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007174 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7175 HasContextSensitiveKeywords = true;
7176 }
7177 }
7178 // C++ classes can have context-sensitive keywords.
7179 else if (cursor.kind == CXCursor_StructDecl ||
7180 cursor.kind == CXCursor_ClassDecl ||
7181 cursor.kind == CXCursor_ClassTemplate ||
7182 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007183 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007184 if (D->hasAttr<FinalAttr>())
7185 HasContextSensitiveKeywords = true;
7186 }
7187 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007188
7189 // Don't override a property annotation with its getter/setter method.
7190 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7191 parent.kind == CXCursor_ObjCPropertyDecl)
7192 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007193
7194 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007195 // Items in the preprocessing record are kept separate from items in
7196 // declarations, so we keep a separate token index.
7197 unsigned SavedTokIdx = TokIdx;
7198 TokIdx = PreprocessingTokIdx;
7199
7200 // Skip tokens up until we catch up to the beginning of the preprocessing
7201 // entry.
7202 while (MoreTokens()) {
7203 const unsigned I = NextToken();
7204 SourceLocation TokLoc = GetTokenLoc(I);
7205 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7206 case RangeBefore:
7207 AdvanceToken();
7208 continue;
7209 case RangeAfter:
7210 case RangeOverlap:
7211 break;
7212 }
7213 break;
7214 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007215
Guy Benyei11169dd2012-12-18 14:30:41 +00007216 // Look at all of the tokens within this range.
7217 while (MoreTokens()) {
7218 const unsigned I = NextToken();
7219 SourceLocation TokLoc = GetTokenLoc(I);
7220 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7221 case RangeBefore:
7222 llvm_unreachable("Infeasible");
7223 case RangeAfter:
7224 break;
7225 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007226 // For macro expansions, just note where the beginning of the macro
7227 // expansion occurs.
7228 if (cursor.kind == CXCursor_MacroExpansion) {
7229 if (TokLoc == cursorRange.getBegin())
7230 Cursors[I] = cursor;
7231 AdvanceToken();
7232 break;
7233 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007234 // We may have already annotated macro names inside macro definitions.
7235 if (Cursors[I].kind != CXCursor_MacroExpansion)
7236 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007237 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007238 continue;
7239 }
7240 break;
7241 }
7242
7243 // Save the preprocessing token index; restore the non-preprocessing
7244 // token index.
7245 PreprocessingTokIdx = TokIdx;
7246 TokIdx = SavedTokIdx;
7247 return CXChildVisit_Recurse;
7248 }
7249
7250 if (cursorRange.isInvalid())
7251 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007252
7253 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007254 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007255 const enum CXCursorKind K = clang_getCursorKind(parent);
7256 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007257 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7258 // Attributes are annotated out-of-order, skip tokens until we reach it.
7259 clang_isAttribute(cursor.kind))
7260 ? clang_getNullCursor()
7261 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007262
7263 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7264
7265 // Avoid having the cursor of an expression "overwrite" the annotation of the
7266 // variable declaration that it belongs to.
7267 // This can happen for C++ constructor expressions whose range generally
7268 // include the variable declaration, e.g.:
7269 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007270 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007271 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007272 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007273 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007274 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7275 E->getBeginLoc() == D->getLocation() &&
7276 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007277 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007278 AdvanceToken();
7279 }
7280 }
7281 }
7282
7283 // Before recursing into the children keep some state that we are going
7284 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7285 // extra work after the child nodes are visited.
7286 // Note that we don't call VisitChildren here to avoid traversing statements
7287 // code-recursively which can blow the stack.
7288
7289 PostChildrenInfo Info;
7290 Info.Cursor = cursor;
7291 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007292 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007293 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007294 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007295 PostChildrenInfos.push_back(Info);
7296
7297 return CXChildVisit_Recurse;
7298}
7299
7300bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7301 if (PostChildrenInfos.empty())
7302 return false;
7303 const PostChildrenInfo &Info = PostChildrenInfos.back();
7304 if (!clang_equalCursors(Info.Cursor, cursor))
7305 return false;
7306
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007307 HandlePostPonedChildCursors(Info);
7308
Guy Benyei11169dd2012-12-18 14:30:41 +00007309 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7310 const unsigned AfterChildren = NextToken();
7311 SourceRange cursorRange = Info.CursorRange;
7312
7313 // Scan the tokens that are at the end of the cursor, but are not captured
7314 // but the child cursors.
7315 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7316
7317 // Scan the tokens that are at the beginning of the cursor, but are not
7318 // capture by the child cursors.
7319 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7320 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7321 break;
7322
7323 Cursors[I] = cursor;
7324 }
7325
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007326 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7327 // encountered the attribute cursor.
7328 if (clang_isAttribute(cursor.kind))
7329 TokIdx = Info.BeforeReachingCursorIdx;
7330
Guy Benyei11169dd2012-12-18 14:30:41 +00007331 PostChildrenInfos.pop_back();
7332 return false;
7333}
7334
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007335void AnnotateTokensWorker::HandlePostPonedChildCursors(
7336 const PostChildrenInfo &Info) {
7337 for (const auto &ChildAction : Info.ChildActions) {
7338 if (ChildAction.action == PostChildrenAction::Postpone) {
7339 HandlePostPonedChildCursor(ChildAction.cursor,
7340 Info.BeforeChildrenTokenIdx);
7341 }
7342 }
7343}
7344
7345void AnnotateTokensWorker::HandlePostPonedChildCursor(
7346 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007347 unsigned I = StartTokenIndex;
7348
7349 // The bracket tokens of a Call or Subscript operator are mapped to
7350 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7351 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7352 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007353 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7354 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007355 if (clang_Range_isNull(CXRefNameRange))
7356 break; // All ranges handled.
7357
7358 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7359 while (I < NumTokens) {
7360 const SourceLocation TokenLocation = GetTokenLoc(I);
7361 if (!TokenLocation.isValid())
7362 break;
7363
7364 // Adapt the end range, because LocationCompare() reports
7365 // RangeOverlap even for the not-inclusive end location.
7366 const SourceLocation fixedEnd =
7367 RefNameRange.getEnd().getLocWithOffset(-1);
7368 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7369
7370 const RangeComparisonResult ComparisonResult =
7371 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7372
7373 if (ComparisonResult == RangeOverlap) {
7374 Cursors[I++] = Cursor;
7375 } else if (ComparisonResult == RangeBefore) {
7376 ++I; // Not relevant token, check next one.
7377 } else if (ComparisonResult == RangeAfter) {
7378 break; // All tokens updated for current range, check next.
7379 }
7380 }
7381 }
7382}
7383
Guy Benyei11169dd2012-12-18 14:30:41 +00007384static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7385 CXCursor parent,
7386 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007387 return static_cast<AnnotateTokensWorker *>(client_data)
7388 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007389}
7390
7391static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7392 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007393 return static_cast<AnnotateTokensWorker *>(client_data)
7394 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007395}
7396
7397namespace {
7398
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007399/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007400/// and mark tokens that are macro arguments. This info is used by the
7401/// AnnotateTokensWorker.
7402class MarkMacroArgTokensVisitor {
7403 SourceManager &SM;
7404 CXToken *Tokens;
7405 unsigned NumTokens;
7406 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007407
Guy Benyei11169dd2012-12-18 14:30:41 +00007408public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007409 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7410 unsigned numTokens)
7411 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007412
7413 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7414 if (cursor.kind != CXCursor_MacroExpansion)
7415 return CXChildVisit_Continue;
7416
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007417 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007418 if (macroRange.getBegin() == macroRange.getEnd())
7419 return CXChildVisit_Continue; // it's not a function macro.
7420
7421 for (; CurIdx < NumTokens; ++CurIdx) {
7422 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7423 macroRange.getBegin()))
7424 break;
7425 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007426
Guy Benyei11169dd2012-12-18 14:30:41 +00007427 if (CurIdx == NumTokens)
7428 return CXChildVisit_Break;
7429
7430 for (; CurIdx < NumTokens; ++CurIdx) {
7431 SourceLocation tokLoc = getTokenLoc(CurIdx);
7432 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7433 break;
7434
7435 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7436 }
7437
7438 if (CurIdx == NumTokens)
7439 return CXChildVisit_Break;
7440
7441 return CXChildVisit_Continue;
7442 }
7443
7444private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007445 CXToken &getTok(unsigned Idx) {
7446 assert(Idx < NumTokens);
7447 return Tokens[Idx];
7448 }
7449 const CXToken &getTok(unsigned Idx) const {
7450 assert(Idx < NumTokens);
7451 return Tokens[Idx];
7452 }
7453
Guy Benyei11169dd2012-12-18 14:30:41 +00007454 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007455 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007456 }
7457
7458 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7459 // The third field is reserved and currently not used. Use it here
7460 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007461 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007462 }
7463};
7464
7465} // end anonymous namespace
7466
7467static CXChildVisitResult
7468MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7469 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007470 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7471 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007472}
7473
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007474/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007475/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007476static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7477 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007478 if (NextIdx >= NumTokens)
7479 return true;
7480
7481 ++NextIdx;
7482 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007483 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007484}
7485
Guy Benyei11169dd2012-12-18 14:30:41 +00007486static void annotatePreprocessorTokens(CXTranslationUnit TU,
7487 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007488 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007489 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007490 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007491
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007492 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007493 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007494 std::pair<FileID, unsigned> BeginLocInfo =
7495 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7496 std::pair<FileID, unsigned> EndLocInfo =
7497 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007498
7499 if (BeginLocInfo.first != EndLocInfo.first)
7500 return;
7501
7502 StringRef Buffer;
7503 bool Invalid = false;
7504 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7505 if (Buffer.empty() || Invalid)
7506 return;
7507
7508 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007509 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7510 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007511 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007512
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007513 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007514 // Lex tokens in raw mode until we hit the end of the range, to avoid
7515 // entering #includes or expanding macros.
7516 while (true) {
7517 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007518 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7519 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007520 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007521 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007522 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7523
Guy Benyei11169dd2012-12-18 14:30:41 +00007524 reprocess:
7525 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007526 // We have found a preprocessing directive. Annotate the tokens
7527 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007528 //
7529 // FIXME: Some simple tests here could identify macro definitions and
7530 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007531
7532 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007533 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7534 break;
7535
Craig Topper69186e72014-06-08 08:38:04 +00007536 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007537 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007538 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7539 break;
7540
7541 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007542 IdentifierInfo &II =
7543 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007544 SourceLocation MappedTokLoc =
7545 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7546 MI = getMacroInfo(II, MappedTokLoc, TU);
7547 }
7548 }
7549
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007550 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007551 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007552 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7553 finished = true;
7554 break;
7555 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007556 // If we are in a macro definition, check if the token was ever a
7557 // macro name and annotate it if that's the case.
7558 if (MI) {
7559 SourceLocation SaveLoc = Tok.getLocation();
7560 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007561 MacroDefinitionRecord *MacroDef =
7562 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007563 Tok.setLocation(SaveLoc);
7564 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007565 Cursors[NextIdx - 1] =
7566 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007567 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007568 } while (!Tok.isAtStartOfLine());
7569
Michael Kruse7520cf02020-03-25 09:26:14 -05007570 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007571 assert(TokIdx <= LastIdx);
7572 SourceLocation EndLoc =
7573 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7574 CXCursor Cursor =
7575 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7576
7577 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007578 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007579
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007580 if (finished)
7581 break;
7582 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007583 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007584 }
7585}
7586
7587// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007588static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7589 CXToken *Tokens, unsigned NumTokens,
7590 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007591 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007592 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7593 setThreadBackgroundPriority();
7594
7595 // Determine the region of interest, which contains all of the tokens.
7596 SourceRange RegionOfInterest;
7597 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007598 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7599 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7600 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007601
Guy Benyei11169dd2012-12-18 14:30:41 +00007602 // Relex the tokens within the source range to look for preprocessing
7603 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007604 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007605
7606 // If begin location points inside a macro argument, set it to the expansion
7607 // location so we can have the full context when annotating semantically.
7608 {
7609 SourceManager &SM = CXXUnit->getSourceManager();
7610 SourceLocation Loc =
7611 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7612 if (Loc.isMacroID())
7613 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7614 }
7615
Guy Benyei11169dd2012-12-18 14:30:41 +00007616 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7617 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007618 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7619 NumTokens);
7620 CursorVisitor MacroArgMarker(
7621 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7622 /*VisitPreprocessorLast=*/true,
7623 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007624 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7625 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007626
Guy Benyei11169dd2012-12-18 14:30:41 +00007627 // Annotate all of the source locations in the region of interest that map to
7628 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007629 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007630
Guy Benyei11169dd2012-12-18 14:30:41 +00007631 // FIXME: We use a ridiculous stack size here because the data-recursion
7632 // algorithm uses a large stack frame than the non-data recursive version,
7633 // and AnnotationTokensWorker currently transforms the data-recursion
7634 // algorithm back into a traditional recursion by explicitly calling
7635 // VisitChildren(). We will need to remove this explicit recursive call.
7636 W.AnnotateTokens();
7637
7638 // If we ran into any entities that involve context-sensitive keywords,
7639 // take another pass through the tokens to mark them as such.
7640 if (W.hasContextSensitiveKeywords()) {
7641 for (unsigned I = 0; I != NumTokens; ++I) {
7642 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7643 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007644
Guy Benyei11169dd2012-12-18 14:30:41 +00007645 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7646 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007647 if (const ObjCPropertyDecl *Property =
7648 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007649 if (Property->getPropertyAttributesAsWritten() != 0 &&
7650 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007651 .Case("readonly", true)
7652 .Case("assign", true)
7653 .Case("unsafe_unretained", true)
7654 .Case("readwrite", true)
7655 .Case("retain", true)
7656 .Case("copy", true)
7657 .Case("nonatomic", true)
7658 .Case("atomic", true)
7659 .Case("getter", true)
7660 .Case("setter", true)
7661 .Case("strong", true)
7662 .Case("weak", true)
7663 .Case("class", true)
7664 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007665 Tokens[I].int_data[0] = CXToken_Keyword;
7666 }
7667 continue;
7668 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007669
Guy Benyei11169dd2012-12-18 14:30:41 +00007670 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7671 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7672 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7673 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007674 .Case("in", true)
7675 .Case("out", true)
7676 .Case("inout", true)
7677 .Case("oneway", true)
7678 .Case("bycopy", true)
7679 .Case("byref", true)
7680 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007681 Tokens[I].int_data[0] = CXToken_Keyword;
7682 continue;
7683 }
7684
7685 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7686 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7687 Tokens[I].int_data[0] = CXToken_Keyword;
7688 continue;
7689 }
7690 }
7691 }
7692}
7693
Michael Kruse7520cf02020-03-25 09:26:14 -05007694void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7695 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007696 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007697 LOG_BAD_TU(TU);
7698 return;
7699 }
7700 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007701 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007702 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007703 }
7704
7705 LOG_FUNC_SECTION {
7706 *Log << TU << ' ';
7707 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007708 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007709 *Log << clang_getRange(bloc, eloc);
7710 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007711
7712 // Any token we don't specifically annotate will have a NULL cursor.
7713 CXCursor C = clang_getNullCursor();
7714 for (unsigned I = 0; I != NumTokens; ++I)
7715 Cursors[I] = C;
7716
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007717 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007718 if (!CXXUnit)
7719 return;
7720
7721 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007722
7723 auto AnnotateTokensImpl = [=]() {
7724 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7725 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007726 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007727 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007728 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7729 }
7730}
7731
Guy Benyei11169dd2012-12-18 14:30:41 +00007732//===----------------------------------------------------------------------===//
7733// Operations for querying linkage of a cursor.
7734//===----------------------------------------------------------------------===//
7735
Guy Benyei11169dd2012-12-18 14:30:41 +00007736CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7737 if (!clang_isDeclaration(cursor.kind))
7738 return CXLinkage_Invalid;
7739
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007740 const Decl *D = cxcursor::getCursorDecl(cursor);
7741 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007742 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007743 case NoLinkage:
7744 case VisibleNoLinkage:
7745 return CXLinkage_NoLinkage;
7746 case ModuleInternalLinkage:
7747 case InternalLinkage:
7748 return CXLinkage_Internal;
7749 case UniqueExternalLinkage:
7750 return CXLinkage_UniqueExternal;
7751 case ModuleLinkage:
7752 case ExternalLinkage:
7753 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007754 };
7755
7756 return CXLinkage_Invalid;
7757}
Guy Benyei11169dd2012-12-18 14:30:41 +00007758
7759//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007760// Operations for querying visibility of a cursor.
7761//===----------------------------------------------------------------------===//
7762
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007763CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7764 if (!clang_isDeclaration(cursor.kind))
7765 return CXVisibility_Invalid;
7766
7767 const Decl *D = cxcursor::getCursorDecl(cursor);
7768 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7769 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007770 case HiddenVisibility:
7771 return CXVisibility_Hidden;
7772 case ProtectedVisibility:
7773 return CXVisibility_Protected;
7774 case DefaultVisibility:
7775 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007776 };
7777
7778 return CXVisibility_Invalid;
7779}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007780
7781//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007782// Operations for querying language of a cursor.
7783//===----------------------------------------------------------------------===//
7784
7785static CXLanguageKind getDeclLanguage(const Decl *D) {
7786 if (!D)
7787 return CXLanguage_C;
7788
7789 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007790 default:
7791 break;
7792 case Decl::ImplicitParam:
7793 case Decl::ObjCAtDefsField:
7794 case Decl::ObjCCategory:
7795 case Decl::ObjCCategoryImpl:
7796 case Decl::ObjCCompatibleAlias:
7797 case Decl::ObjCImplementation:
7798 case Decl::ObjCInterface:
7799 case Decl::ObjCIvar:
7800 case Decl::ObjCMethod:
7801 case Decl::ObjCProperty:
7802 case Decl::ObjCPropertyImpl:
7803 case Decl::ObjCProtocol:
7804 case Decl::ObjCTypeParam:
7805 return CXLanguage_ObjC;
7806 case Decl::CXXConstructor:
7807 case Decl::CXXConversion:
7808 case Decl::CXXDestructor:
7809 case Decl::CXXMethod:
7810 case Decl::CXXRecord:
7811 case Decl::ClassTemplate:
7812 case Decl::ClassTemplatePartialSpecialization:
7813 case Decl::ClassTemplateSpecialization:
7814 case Decl::Friend:
7815 case Decl::FriendTemplate:
7816 case Decl::FunctionTemplate:
7817 case Decl::LinkageSpec:
7818 case Decl::Namespace:
7819 case Decl::NamespaceAlias:
7820 case Decl::NonTypeTemplateParm:
7821 case Decl::StaticAssert:
7822 case Decl::TemplateTemplateParm:
7823 case Decl::TemplateTypeParm:
7824 case Decl::UnresolvedUsingTypename:
7825 case Decl::UnresolvedUsingValue:
7826 case Decl::Using:
7827 case Decl::UsingDirective:
7828 case Decl::UsingShadow:
7829 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007830 }
7831
7832 return CXLanguage_C;
7833}
7834
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007835static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7836 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007837 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007838
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007839 switch (D->getAvailability()) {
7840 case AR_Available:
7841 case AR_NotYetIntroduced:
7842 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007843 return getCursorAvailabilityForDecl(
7844 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007845 return CXAvailability_Available;
7846
7847 case AR_Deprecated:
7848 return CXAvailability_Deprecated;
7849
7850 case AR_Unavailable:
7851 return CXAvailability_NotAvailable;
7852 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007853
7854 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007855}
7856
Guy Benyei11169dd2012-12-18 14:30:41 +00007857enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7858 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007859 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7860 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007861
7862 return CXAvailability_Available;
7863}
7864
7865static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007866 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007867 if (In.empty())
7868 return Out;
7869
7870 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007871
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007872 Optional<unsigned> Minor = In.getMinor();
7873 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007874 Out.Minor = *Minor;
7875 else
7876 return Out;
7877
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007878 Optional<unsigned> Subminor = In.getSubminor();
7879 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007880 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007881
Guy Benyei11169dd2012-12-18 14:30:41 +00007882 return Out;
7883}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007884
Alex Lorenz1345ea22017-06-12 19:06:30 +00007885static void getCursorPlatformAvailabilityForDecl(
7886 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7887 int *always_unavailable, CXString *unavailable_message,
7888 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007889 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007890 for (auto A : D->attrs()) {
7891 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007892 HadAvailAttr = true;
7893 if (always_deprecated)
7894 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007895 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007896 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007897 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007898 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007899 continue;
7900 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007901
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007902 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007903 HadAvailAttr = true;
7904 if (always_unavailable)
7905 *always_unavailable = 1;
7906 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007907 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007908 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7909 }
7910 continue;
7911 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007912
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007913 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007914 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007915 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007916 }
7917 }
7918
7919 if (!HadAvailAttr)
7920 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7921 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007922 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7923 deprecated_message, always_unavailable, unavailable_message,
7924 AvailabilityAttrs);
7925
7926 if (AvailabilityAttrs.empty())
7927 return;
7928
Michael Kruse7520cf02020-03-25 09:26:14 -05007929 llvm::sort(
7930 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7931 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7932 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007933 ASTContext &Ctx = D->getASTContext();
7934 auto It = std::unique(
7935 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7936 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7937 if (LHS->getPlatform() != RHS->getPlatform())
7938 return false;
7939
7940 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7941 LHS->getDeprecated() == RHS->getDeprecated() &&
7942 LHS->getObsoleted() == RHS->getObsoleted() &&
7943 LHS->getMessage() == RHS->getMessage() &&
7944 LHS->getReplacement() == RHS->getReplacement())
7945 return true;
7946
7947 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
7948 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
7949 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
7950 return false;
7951
7952 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
7953 LHS->setIntroduced(Ctx, RHS->getIntroduced());
7954
7955 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
7956 LHS->setDeprecated(Ctx, RHS->getDeprecated());
7957 if (LHS->getMessage().empty())
7958 LHS->setMessage(Ctx, RHS->getMessage());
7959 if (LHS->getReplacement().empty())
7960 LHS->setReplacement(Ctx, RHS->getReplacement());
7961 }
7962
7963 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
7964 LHS->setObsoleted(Ctx, RHS->getObsoleted());
7965 if (LHS->getMessage().empty())
7966 LHS->setMessage(Ctx, RHS->getMessage());
7967 if (LHS->getReplacement().empty())
7968 LHS->setReplacement(Ctx, RHS->getReplacement());
7969 }
7970
7971 return true;
7972 });
7973 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007974}
7975
Alex Lorenz1345ea22017-06-12 19:06:30 +00007976int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00007977 CXString *deprecated_message,
7978 int *always_unavailable,
7979 CXString *unavailable_message,
7980 CXPlatformAvailability *availability,
7981 int availability_size) {
7982 if (always_deprecated)
7983 *always_deprecated = 0;
7984 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007985 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007986 if (always_unavailable)
7987 *always_unavailable = 0;
7988 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007989 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007990
Guy Benyei11169dd2012-12-18 14:30:41 +00007991 if (!clang_isDeclaration(cursor.kind))
7992 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007993
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007994 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007995 if (!D)
7996 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007997
Alex Lorenz1345ea22017-06-12 19:06:30 +00007998 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
7999 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8000 always_unavailable, unavailable_message,
8001 AvailabilityAttrs);
8002 for (const auto &Avail :
8003 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8004 .take_front(availability_size))) {
8005 availability[Avail.index()].Platform =
8006 cxstring::createDup(Avail.value()->getPlatform()->getName());
8007 availability[Avail.index()].Introduced =
8008 convertVersion(Avail.value()->getIntroduced());
8009 availability[Avail.index()].Deprecated =
8010 convertVersion(Avail.value()->getDeprecated());
8011 availability[Avail.index()].Obsoleted =
8012 convertVersion(Avail.value()->getObsoleted());
8013 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8014 availability[Avail.index()].Message =
8015 cxstring::createDup(Avail.value()->getMessage());
8016 }
8017
8018 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008019}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008020
Guy Benyei11169dd2012-12-18 14:30:41 +00008021void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8022 clang_disposeString(availability->Platform);
8023 clang_disposeString(availability->Message);
8024}
8025
8026CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8027 if (clang_isDeclaration(cursor.kind))
8028 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8029
8030 return CXLanguage_Invalid;
8031}
8032
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008033CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8034 const Decl *D = cxcursor::getCursorDecl(cursor);
8035 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8036 switch (VD->getTLSKind()) {
8037 case VarDecl::TLS_None:
8038 return CXTLS_None;
8039 case VarDecl::TLS_Dynamic:
8040 return CXTLS_Dynamic;
8041 case VarDecl::TLS_Static:
8042 return CXTLS_Static;
8043 }
8044 }
8045
8046 return CXTLS_None;
8047}
8048
Michael Kruse7520cf02020-03-25 09:26:14 -05008049/// If the given cursor is the "templated" declaration
8050/// describing a class or function template, return the class or
8051/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008052static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008053 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008054 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008055
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008056 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008057 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8058 return FunTmpl;
8059
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008060 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008061 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8062 return ClassTmpl;
8063
8064 return D;
8065}
8066
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008067enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8068 StorageClass sc = SC_None;
8069 const Decl *D = getCursorDecl(C);
8070 if (D) {
8071 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8072 sc = FD->getStorageClass();
8073 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8074 sc = VD->getStorageClass();
8075 } else {
8076 return CX_SC_Invalid;
8077 }
8078 } else {
8079 return CX_SC_Invalid;
8080 }
8081 switch (sc) {
8082 case SC_None:
8083 return CX_SC_None;
8084 case SC_Extern:
8085 return CX_SC_Extern;
8086 case SC_Static:
8087 return CX_SC_Static;
8088 case SC_PrivateExtern:
8089 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008090 case SC_Auto:
8091 return CX_SC_Auto;
8092 case SC_Register:
8093 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008094 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008095 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008096}
8097
Guy Benyei11169dd2012-12-18 14:30:41 +00008098CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8099 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008100 if (const Decl *D = getCursorDecl(cursor)) {
8101 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008102 if (!DC)
8103 return clang_getNullCursor();
8104
Michael Kruse7520cf02020-03-25 09:26:14 -05008105 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008106 getCursorTU(cursor));
8107 }
8108 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008109
Guy Benyei11169dd2012-12-18 14:30:41 +00008110 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008111 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008112 return MakeCXCursor(D, getCursorTU(cursor));
8113 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008114
Guy Benyei11169dd2012-12-18 14:30:41 +00008115 return clang_getNullCursor();
8116}
8117
8118CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8119 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008120 if (const Decl *D = getCursorDecl(cursor)) {
8121 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008122 if (!DC)
8123 return clang_getNullCursor();
8124
Michael Kruse7520cf02020-03-25 09:26:14 -05008125 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008126 getCursorTU(cursor));
8127 }
8128 }
8129
Michael Kruse7520cf02020-03-25 09:26:14 -05008130 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008131 // statement or expression, so we return nothing.
8132 return clang_getNullCursor();
8133}
8134
8135CXFile clang_getIncludedFile(CXCursor cursor) {
8136 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008137 return nullptr;
8138
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008139 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008140 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008141}
8142
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008143unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8144 if (C.kind != CXCursor_ObjCPropertyDecl)
8145 return CXObjCPropertyAttr_noattr;
8146
8147 unsigned Result = CXObjCPropertyAttr_noattr;
8148 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8149 ObjCPropertyDecl::PropertyAttributeKind Attr =
8150 PD->getPropertyAttributesAsWritten();
8151
Michael Kruse7520cf02020-03-25 09:26:14 -05008152#define SET_CXOBJCPROP_ATTR(A) \
8153 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
8154 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008155 SET_CXOBJCPROP_ATTR(readonly);
8156 SET_CXOBJCPROP_ATTR(getter);
8157 SET_CXOBJCPROP_ATTR(assign);
8158 SET_CXOBJCPROP_ATTR(readwrite);
8159 SET_CXOBJCPROP_ATTR(retain);
8160 SET_CXOBJCPROP_ATTR(copy);
8161 SET_CXOBJCPROP_ATTR(nonatomic);
8162 SET_CXOBJCPROP_ATTR(setter);
8163 SET_CXOBJCPROP_ATTR(atomic);
8164 SET_CXOBJCPROP_ATTR(weak);
8165 SET_CXOBJCPROP_ATTR(strong);
8166 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008167 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008168#undef SET_CXOBJCPROP_ATTR
8169
8170 return Result;
8171}
8172
Michael Wu6e88f532018-08-03 05:38:29 +00008173CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8174 if (C.kind != CXCursor_ObjCPropertyDecl)
8175 return cxstring::createNull();
8176
8177 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8178 Selector sel = PD->getGetterName();
8179 if (sel.isNull())
8180 return cxstring::createNull();
8181
8182 return cxstring::createDup(sel.getAsString());
8183}
8184
8185CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8186 if (C.kind != CXCursor_ObjCPropertyDecl)
8187 return cxstring::createNull();
8188
8189 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8190 Selector sel = PD->getSetterName();
8191 if (sel.isNull())
8192 return cxstring::createNull();
8193
8194 return cxstring::createDup(sel.getAsString());
8195}
8196
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008197unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8198 if (!clang_isDeclaration(C.kind))
8199 return CXObjCDeclQualifier_None;
8200
8201 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8202 const Decl *D = getCursorDecl(C);
8203 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8204 QT = MD->getObjCDeclQualifier();
8205 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8206 QT = PD->getObjCDeclQualifier();
8207 if (QT == Decl::OBJC_TQ_None)
8208 return CXObjCDeclQualifier_None;
8209
8210 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008211 if (QT & Decl::OBJC_TQ_In)
8212 Result |= CXObjCDeclQualifier_In;
8213 if (QT & Decl::OBJC_TQ_Inout)
8214 Result |= CXObjCDeclQualifier_Inout;
8215 if (QT & Decl::OBJC_TQ_Out)
8216 Result |= CXObjCDeclQualifier_Out;
8217 if (QT & Decl::OBJC_TQ_Bycopy)
8218 Result |= CXObjCDeclQualifier_Bycopy;
8219 if (QT & Decl::OBJC_TQ_Byref)
8220 Result |= CXObjCDeclQualifier_Byref;
8221 if (QT & Decl::OBJC_TQ_Oneway)
8222 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008223
8224 return Result;
8225}
8226
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008227unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8228 if (!clang_isDeclaration(C.kind))
8229 return 0;
8230
8231 const Decl *D = getCursorDecl(C);
8232 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8233 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8234 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8235 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8236
8237 return 0;
8238}
8239
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008240unsigned clang_Cursor_isVariadic(CXCursor C) {
8241 if (!clang_isDeclaration(C.kind))
8242 return 0;
8243
8244 const Decl *D = getCursorDecl(C);
8245 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8246 return FD->isVariadic();
8247 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8248 return MD->isVariadic();
8249
8250 return 0;
8251}
8252
Michael Kruse7520cf02020-03-25 09:26:14 -05008253unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8254 CXString *definedIn,
8255 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008256 if (!clang_isDeclaration(C.kind))
8257 return 0;
8258
8259 const Decl *D = getCursorDecl(C);
8260
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008261 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008262 if (language)
8263 *language = cxstring::createDup(attr->getLanguage());
8264 if (definedIn)
8265 *definedIn = cxstring::createDup(attr->getDefinedIn());
8266 if (isGenerated)
8267 *isGenerated = attr->getGeneratedDeclaration();
8268 return 1;
8269 }
8270 return 0;
8271}
8272
Guy Benyei11169dd2012-12-18 14:30:41 +00008273CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8274 if (!clang_isDeclaration(C.kind))
8275 return clang_getNullRange();
8276
8277 const Decl *D = getCursorDecl(C);
8278 ASTContext &Context = getCursorContext(C);
8279 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8280 if (!RC)
8281 return clang_getNullRange();
8282
8283 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8284}
8285
8286CXString clang_Cursor_getRawCommentText(CXCursor C) {
8287 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008288 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008289
8290 const Decl *D = getCursorDecl(C);
8291 ASTContext &Context = getCursorContext(C);
8292 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008293 StringRef RawText =
8294 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008295
8296 // Don't duplicate the string because RawText points directly into source
8297 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008298 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008299}
8300
8301CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8302 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008303 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008304
8305 const Decl *D = getCursorDecl(C);
8306 const ASTContext &Context = getCursorContext(C);
8307 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8308
8309 if (RC) {
8310 StringRef BriefText = RC->getBriefText(Context);
8311
8312 // Don't duplicate the string because RawComment ensures that this memory
8313 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008314 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008315 }
8316
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008317 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008318}
8319
Guy Benyei11169dd2012-12-18 14:30:41 +00008320CXModule clang_Cursor_getModule(CXCursor C) {
8321 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008322 if (const ImportDecl *ImportD =
8323 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008324 return ImportD->getImportedModule();
8325 }
8326
Craig Topper69186e72014-06-08 08:38:04 +00008327 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008328}
8329
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008330CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8331 if (isNotUsableTU(TU)) {
8332 LOG_BAD_TU(TU);
8333 return nullptr;
8334 }
8335 if (!File)
8336 return nullptr;
8337 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008338
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008339 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8340 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8341 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008342
Richard Smithfeb54b62014-10-23 02:01:19 +00008343 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008344}
8345
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008346CXFile clang_Module_getASTFile(CXModule CXMod) {
8347 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008348 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008349 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008350 return const_cast<FileEntry *>(Mod->getASTFile());
8351}
8352
Guy Benyei11169dd2012-12-18 14:30:41 +00008353CXModule clang_Module_getParent(CXModule CXMod) {
8354 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008355 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008356 Module *Mod = static_cast<Module *>(CXMod);
Guy Benyei11169dd2012-12-18 14:30:41 +00008357 return Mod->Parent;
8358}
8359
8360CXString clang_Module_getName(CXModule CXMod) {
8361 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008362 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008363 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008364 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008365}
8366
8367CXString clang_Module_getFullName(CXModule CXMod) {
8368 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008369 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008370 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008371 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008372}
8373
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008374int clang_Module_isSystem(CXModule CXMod) {
8375 if (!CXMod)
8376 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008377 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008378 return Mod->IsSystem;
8379}
8380
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008381unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8382 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008383 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008384 LOG_BAD_TU(TU);
8385 return 0;
8386 }
8387 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008388 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008389 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008390 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8391 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8392 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008393}
8394
Michael Kruse7520cf02020-03-25 09:26:14 -05008395CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8396 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008397 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008398 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008399 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008400 }
8401 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008402 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008403 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008404 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008405
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008406 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8407 if (Index < TopHeaders.size())
8408 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008409
Craig Topper69186e72014-06-08 08:38:04 +00008410 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008411}
8412
Guy Benyei11169dd2012-12-18 14:30:41 +00008413//===----------------------------------------------------------------------===//
8414// C++ AST instrospection.
8415//===----------------------------------------------------------------------===//
8416
Jonathan Coe29565352016-04-27 12:48:25 +00008417unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8418 if (!clang_isDeclaration(C.kind))
8419 return 0;
8420
8421 const Decl *D = cxcursor::getCursorDecl(C);
8422 const CXXConstructorDecl *Constructor =
8423 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8424 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8425}
8426
8427unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8428 if (!clang_isDeclaration(C.kind))
8429 return 0;
8430
8431 const Decl *D = cxcursor::getCursorDecl(C);
8432 const CXXConstructorDecl *Constructor =
8433 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8434 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8435}
8436
8437unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8438 if (!clang_isDeclaration(C.kind))
8439 return 0;
8440
8441 const Decl *D = cxcursor::getCursorDecl(C);
8442 const CXXConstructorDecl *Constructor =
8443 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8444 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8445}
8446
8447unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8448 if (!clang_isDeclaration(C.kind))
8449 return 0;
8450
8451 const Decl *D = cxcursor::getCursorDecl(C);
8452 const CXXConstructorDecl *Constructor =
8453 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8454 // Passing 'false' excludes constructors marked 'explicit'.
8455 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8456}
8457
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008458unsigned clang_CXXField_isMutable(CXCursor C) {
8459 if (!clang_isDeclaration(C.kind))
8460 return 0;
8461
8462 if (const auto D = cxcursor::getCursorDecl(C))
8463 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8464 return FD->isMutable() ? 1 : 0;
8465 return 0;
8466}
8467
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008468unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8469 if (!clang_isDeclaration(C.kind))
8470 return 0;
8471
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008472 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008473 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008474 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008475 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8476}
8477
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008478unsigned clang_CXXMethod_isConst(CXCursor C) {
8479 if (!clang_isDeclaration(C.kind))
8480 return 0;
8481
8482 const Decl *D = cxcursor::getCursorDecl(C);
8483 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008484 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008485 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008486}
8487
Jonathan Coe29565352016-04-27 12:48:25 +00008488unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8489 if (!clang_isDeclaration(C.kind))
8490 return 0;
8491
8492 const Decl *D = cxcursor::getCursorDecl(C);
8493 const CXXMethodDecl *Method =
8494 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8495 return (Method && Method->isDefaulted()) ? 1 : 0;
8496}
8497
Guy Benyei11169dd2012-12-18 14:30:41 +00008498unsigned clang_CXXMethod_isStatic(CXCursor C) {
8499 if (!clang_isDeclaration(C.kind))
8500 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008501
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008502 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008503 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008504 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008505 return (Method && Method->isStatic()) ? 1 : 0;
8506}
8507
8508unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8509 if (!clang_isDeclaration(C.kind))
8510 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008511
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008512 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008513 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008514 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008515 return (Method && Method->isVirtual()) ? 1 : 0;
8516}
Guy Benyei11169dd2012-12-18 14:30:41 +00008517
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008518unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8519 if (!clang_isDeclaration(C.kind))
8520 return 0;
8521
8522 const auto *D = cxcursor::getCursorDecl(C);
8523 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8524 if (RD)
8525 RD = RD->getDefinition();
8526 return (RD && RD->isAbstract()) ? 1 : 0;
8527}
8528
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008529unsigned clang_EnumDecl_isScoped(CXCursor C) {
8530 if (!clang_isDeclaration(C.kind))
8531 return 0;
8532
8533 const Decl *D = cxcursor::getCursorDecl(C);
8534 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8535 return (Enum && Enum->isScoped()) ? 1 : 0;
8536}
8537
Guy Benyei11169dd2012-12-18 14:30:41 +00008538//===----------------------------------------------------------------------===//
8539// Attribute introspection.
8540//===----------------------------------------------------------------------===//
8541
Guy Benyei11169dd2012-12-18 14:30:41 +00008542CXType clang_getIBOutletCollectionType(CXCursor C) {
8543 if (C.kind != CXCursor_IBOutletCollectionAttr)
8544 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008545
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008546 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008547 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8548
8549 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008550}
Guy Benyei11169dd2012-12-18 14:30:41 +00008551
8552//===----------------------------------------------------------------------===//
8553// Inspecting memory usage.
8554//===----------------------------------------------------------------------===//
8555
8556typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8557
8558static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008559 enum CXTUResourceUsageKind k,
8560 unsigned long amount) {
8561 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008562 entries.push_back(entry);
8563}
8564
Guy Benyei11169dd2012-12-18 14:30:41 +00008565const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8566 const char *str = "";
8567 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008568 case CXTUResourceUsage_AST:
8569 str = "ASTContext: expressions, declarations, and types";
8570 break;
8571 case CXTUResourceUsage_Identifiers:
8572 str = "ASTContext: identifiers";
8573 break;
8574 case CXTUResourceUsage_Selectors:
8575 str = "ASTContext: selectors";
8576 break;
8577 case CXTUResourceUsage_GlobalCompletionResults:
8578 str = "Code completion: cached global results";
8579 break;
8580 case CXTUResourceUsage_SourceManagerContentCache:
8581 str = "SourceManager: content cache allocator";
8582 break;
8583 case CXTUResourceUsage_AST_SideTables:
8584 str = "ASTContext: side tables";
8585 break;
8586 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8587 str = "SourceManager: malloc'ed memory buffers";
8588 break;
8589 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8590 str = "SourceManager: mmap'ed memory buffers";
8591 break;
8592 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8593 str = "ExternalASTSource: malloc'ed memory buffers";
8594 break;
8595 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8596 str = "ExternalASTSource: mmap'ed memory buffers";
8597 break;
8598 case CXTUResourceUsage_Preprocessor:
8599 str = "Preprocessor: malloc'ed memory";
8600 break;
8601 case CXTUResourceUsage_PreprocessingRecord:
8602 str = "Preprocessor: PreprocessingRecord";
8603 break;
8604 case CXTUResourceUsage_SourceManager_DataStructures:
8605 str = "SourceManager: data structures and tables";
8606 break;
8607 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8608 str = "Preprocessor: header search tables";
8609 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008610 }
8611 return str;
8612}
8613
8614CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008615 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008616 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008617 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008618 return usage;
8619 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008620
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008621 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008622 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008623 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008624
Guy Benyei11169dd2012-12-18 14:30:41 +00008625 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008626 createCXTUResourceUsageEntry(
8627 *entries, CXTUResourceUsage_AST,
8628 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008629
8630 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008631 createCXTUResourceUsageEntry(
8632 *entries, CXTUResourceUsage_Identifiers,
8633 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008634
8635 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008636 createCXTUResourceUsageEntry(
8637 *entries, CXTUResourceUsage_Selectors,
8638 (unsigned long)astContext.Selectors.getTotalMemory());
8639
Guy Benyei11169dd2012-12-18 14:30:41 +00008640 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008641 createCXTUResourceUsageEntry(
8642 *entries, CXTUResourceUsage_AST_SideTables,
8643 (unsigned long)astContext.getSideTableAllocatedMemory());
8644
Guy Benyei11169dd2012-12-18 14:30:41 +00008645 // How much memory is used for caching global code completion results?
8646 unsigned long completionBytes = 0;
8647 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008648 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008649 completionBytes = completionAllocator->getTotalMemory();
8650 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008651 createCXTUResourceUsageEntry(
8652 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8653
Guy Benyei11169dd2012-12-18 14:30:41 +00008654 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008655 createCXTUResourceUsageEntry(
8656 *entries, CXTUResourceUsage_SourceManagerContentCache,
8657 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8658
Guy Benyei11169dd2012-12-18 14:30:41 +00008659 // How much memory is being used by the MemoryBuffer's in SourceManager?
8660 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008661 astUnit->getSourceManager().getMemoryBufferSizes();
8662
Guy Benyei11169dd2012-12-18 14:30:41 +00008663 createCXTUResourceUsageEntry(*entries,
8664 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008665 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008666 createCXTUResourceUsageEntry(*entries,
8667 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008668 (unsigned long)srcBufs.mmap_bytes);
8669 createCXTUResourceUsageEntry(
8670 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8671 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8672
Guy Benyei11169dd2012-12-18 14:30:41 +00008673 // How much memory is being used by the ExternalASTSource?
8674 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8675 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008676 esrc->getMemoryBufferSizes();
8677
8678 createCXTUResourceUsageEntry(
8679 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8680 (unsigned long)sizes.malloc_bytes);
8681 createCXTUResourceUsageEntry(
8682 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8683 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008684 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008685
Guy Benyei11169dd2012-12-18 14:30:41 +00008686 // How much memory is being used by the Preprocessor?
8687 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008688 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008689 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008690
Guy Benyei11169dd2012-12-18 14:30:41 +00008691 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8692 createCXTUResourceUsageEntry(*entries,
8693 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008694 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008695 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008696
Guy Benyei11169dd2012-12-18 14:30:41 +00008697 createCXTUResourceUsageEntry(*entries,
8698 CXTUResourceUsage_Preprocessor_HeaderSearch,
8699 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008700
Michael Kruse7520cf02020-03-25 09:26:14 -05008701 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8702 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008703 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008704 return usage;
8705}
8706
8707void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8708 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008709 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008710}
8711
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008712CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8713 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008714 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008715 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008716
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008717 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008718 LOG_BAD_TU(TU);
8719 return skipped;
8720 }
8721
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008722 if (!file)
8723 return skipped;
8724
8725 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008726 PreprocessingRecord *ppRec =
8727 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008728 if (!ppRec)
8729 return skipped;
8730
8731 ASTContext &Ctx = astUnit->getASTContext();
8732 SourceManager &sm = Ctx.getSourceManager();
8733 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8734 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008735 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008736
8737 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8738 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008739 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8740 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008741 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008742 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8743 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008744 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008745 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8746 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008747 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008748 }
8749
8750 skipped->count = wantedRanges.size();
8751 skipped->ranges = new CXSourceRange[skipped->count];
8752 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8753 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8754
8755 return skipped;
8756}
8757
Cameron Desrochersd8091282016-08-18 15:43:55 +00008758CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8759 CXSourceRangeList *skipped = new CXSourceRangeList;
8760 skipped->count = 0;
8761 skipped->ranges = nullptr;
8762
8763 if (isNotUsableTU(TU)) {
8764 LOG_BAD_TU(TU);
8765 return skipped;
8766 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008767
Cameron Desrochersd8091282016-08-18 15:43:55 +00008768 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008769 PreprocessingRecord *ppRec =
8770 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008771 if (!ppRec)
8772 return skipped;
8773
8774 ASTContext &Ctx = astUnit->getASTContext();
8775
8776 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8777
8778 skipped->count = SkippedRanges.size();
8779 skipped->ranges = new CXSourceRange[skipped->count];
8780 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8781 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8782
8783 return skipped;
8784}
8785
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008786void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8787 if (ranges) {
8788 delete[] ranges->ranges;
8789 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008790 }
8791}
8792
Guy Benyei11169dd2012-12-18 14:30:41 +00008793void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8794 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8795 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008796 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008797 clang_getTUResourceUsageName(Usage.entries[I].kind),
8798 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008799
Guy Benyei11169dd2012-12-18 14:30:41 +00008800 clang_disposeCXTUResourceUsage(Usage);
8801}
8802
8803//===----------------------------------------------------------------------===//
8804// Misc. utility functions.
8805//===----------------------------------------------------------------------===//
8806
Richard Smith0a7b2972018-07-03 21:34:13 +00008807/// Default to using our desired 8 MB stack size on "safety" threads.
8808static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008809
8810namespace clang {
8811
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008812bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008813 unsigned Size) {
8814 if (!Size)
8815 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008816 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008817 return CRC.RunSafelyOnThread(Fn, Size);
8818 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008819}
8820
Michael Kruse7520cf02020-03-25 09:26:14 -05008821unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008822
Michael Kruse7520cf02020-03-25 09:26:14 -05008823void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008824
Michael Kruse7520cf02020-03-25 09:26:14 -05008825} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008826
8827void clang::setThreadBackgroundPriority() {
8828 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8829 return;
8830
Nico Weber18cfd9f2019-04-21 19:18:41 +00008831#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008832 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008833#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008834}
8835
8836void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8837 if (!Unit)
8838 return;
8839
Michael Kruse7520cf02020-03-25 09:26:14 -05008840 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8841 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008842 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008843 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008844 CXString Msg =
8845 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008846 fprintf(stderr, "%s\n", clang_getCString(Msg));
8847 clang_disposeString(Msg);
8848 }
Nico Weber1865df42018-04-27 19:11:14 +00008849#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008850 // On Windows, force a flush, since there may be multiple copies of
8851 // stderr and stdout in the file system, all with different buffers
8852 // but writing to the same device.
8853 fflush(stderr);
8854#endif
8855}
8856
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008857MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8858 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008859 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008860 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008861 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008862 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008863 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008864
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008865 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008866 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008867 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008868 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008869 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8870 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008871 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8872 return Def.getMacroInfo();
8873 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008874 }
8875
Craig Topper69186e72014-06-08 08:38:04 +00008876 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008877}
8878
Richard Smith66a81862015-05-04 02:25:31 +00008879const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008880 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008881 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008882 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008883 const IdentifierInfo *II = MacroDef->getName();
8884 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008885 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008886
8887 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8888}
8889
Richard Smith66a81862015-05-04 02:25:31 +00008890MacroDefinitionRecord *
8891cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8892 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008893 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008894 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008895 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008896 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008897
8898 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008899 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008900 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8901 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008902 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008903
8904 // Check that the token is inside the definition and not its argument list.
8905 SourceManager &SM = Unit->getSourceManager();
8906 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008907 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008908 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00008909 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008910
8911 Preprocessor &PP = Unit->getPreprocessor();
8912 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
8913 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00008914 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008915
Alp Toker2d57cea2014-05-17 04:53:25 +00008916 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008917 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008918 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008919
8920 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00008921 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00008922 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008923
Richard Smith20e883e2015-04-29 23:20:19 +00008924 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00008925 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00008926 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008927
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008928 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008929}
8930
Richard Smith66a81862015-05-04 02:25:31 +00008931MacroDefinitionRecord *
8932cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
8933 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008934 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008935 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008936
8937 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008938 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008939 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008940 Preprocessor &PP = Unit->getPreprocessor();
8941 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00008942 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008943 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
8944 Token Tok;
8945 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00008946 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008947
8948 return checkForMacroInMacroDefinition(MI, Tok, TU);
8949}
8950
Guy Benyei11169dd2012-12-18 14:30:41 +00008951CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008952 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00008953}
8954
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008955Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
8956 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008957 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008958 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00008959 if (Unit->isMainFileAST())
8960 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008961 return *this;
8962 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00008963 } else {
8964 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008965 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008966 return *this;
8967}
8968
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00008969Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
8970 *this << FE->getName();
8971 return *this;
8972}
8973
8974Logger &cxindex::Logger::operator<<(CXCursor cursor) {
8975 CXString cursorName = clang_getCursorDisplayName(cursor);
8976 *this << cursorName << "@" << clang_getCursorLocation(cursor);
8977 clang_disposeString(cursorName);
8978 return *this;
8979}
8980
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008981Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
8982 CXFile File;
8983 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00008984 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008985 CXString FileName = clang_getFileName(File);
8986 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
8987 clang_disposeString(FileName);
8988 return *this;
8989}
8990
8991Logger &cxindex::Logger::operator<<(CXSourceRange range) {
8992 CXSourceLocation BLoc = clang_getRangeStart(range);
8993 CXSourceLocation ELoc = clang_getRangeEnd(range);
8994
8995 CXFile BFile;
8996 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00008997 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008998
8999 CXFile EFile;
9000 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009001 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009002
9003 CXString BFileName = clang_getFileName(BFile);
9004 if (BFile == EFile) {
9005 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05009006 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009007 } else {
9008 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009009 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9010 BColumn)
9011 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9012 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009013 clang_disposeString(EFileName);
9014 }
9015 clang_disposeString(BFileName);
9016 return *this;
9017}
9018
9019Logger &cxindex::Logger::operator<<(CXString Str) {
9020 *this << clang_getCString(Str);
9021 return *this;
9022}
9023
9024Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9025 LogOS << Fmt;
9026 return *this;
9027}
9028
Benjamin Kramer762bc332019-08-07 14:44:40 +00009029static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009030
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009031cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009032 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009033
9034 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9035
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009036 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009037 OS << "[libclang:" << Name << ':';
9038
Alp Toker1a86ad22014-07-06 06:24:00 +00009039#ifdef USE_DARWIN_THREADS
9040 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009041 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9042 OS << tid << ':';
9043#endif
9044
9045 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9046 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009047 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009048
9049 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009050 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009051 OS << "--------------------------------------------------\n";
9052 }
9053}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009054
9055#ifdef CLANG_TOOL_EXTRA_BUILD
9056// This anchor is used to force the linker to link the clang-tidy plugin.
9057extern volatile int ClangTidyPluginAnchorSource;
9058static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9059 ClangTidyPluginAnchorSource;
9060
9061// This anchor is used to force the linker to link the clang-include-fixer
9062// plugin.
9063extern volatile int ClangIncludeFixerPluginAnchorSource;
9064static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9065 ClangIncludeFixerPluginAnchorSource;
9066#endif