blob: c878f454aad0dd2da3e5b5e9abfe81772d998036 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Guy Benyei11169dd2012-12-18 14:30:41 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the main API hooks in the Clang-C Source Indexing
10// library.
11//
12//===----------------------------------------------------------------------===//
13
Guy Benyei11169dd2012-12-18 14:30:41 +000014#include "CIndexDiagnostic.h"
Mehdi Amini9670f842016-07-18 19:02:11 +000015#include "CIndexer.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000016#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000017#include "CXCursor.h"
18#include "CXSourceLocation.h"
19#include "CXString.h"
20#include "CXTranslationUnit.h"
21#include "CXType.h"
22#include "CursorVisitor.h"
Jan Korousf7d23762019-09-12 22:55:55 +000023#include "clang-c/FatalErrorHandler.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Jan Korous7e36ecd2019-09-05 20:33:52 +000025#include "clang/AST/Mangle.h"
Alexey Bataev95598342020-02-10 15:49:05 -050026#include "clang/AST/OpenMPClause.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000027#include "clang/AST/StmtVisitor.h"
28#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000029#include "clang/Basic/DiagnosticCategories.h"
30#include "clang/Basic/DiagnosticIDs.h"
Richard Smith0a7b2972018-07-03 21:34:13 +000031#include "clang/Basic/Stack.h"
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +000032#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000033#include "clang/Basic/Version.h"
34#include "clang/Frontend/ASTUnit.h"
35#include "clang/Frontend/CompilerInstance.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000036#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000037#include "clang/Lex/HeaderSearch.h"
38#include "clang/Lex/Lexer.h"
39#include "clang/Lex/PreprocessingRecord.h"
40#include "clang/Lex/Preprocessor.h"
41#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000045#include "llvm/Support/Compiler.h"
46#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000047#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000048#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/MemoryBuffer.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000050#include "llvm/Support/Program.h"
51#include "llvm/Support/SaveAndRestore.h"
52#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000053#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000054#include "llvm/Support/Threading.h"
55#include "llvm/Support/Timer.h"
56#include "llvm/Support/raw_ostream.h"
Benjamin Kramer762bc332019-08-07 14:44:40 +000057#include <mutex>
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000058
Alp Toker1a86ad22014-07-06 06:24:00 +000059#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
60#define USE_DARWIN_THREADS
61#endif
62
63#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000064#include <pthread.h>
65#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000066
67using namespace clang;
68using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000069using namespace clang::cxtu;
70using namespace clang::cxindex;
71
David Blaikieea4395e2017-01-06 19:49:01 +000072CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,
73 std::unique_ptr<ASTUnit> AU) {
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000075 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000076 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000077 CXTranslationUnit D = new CXTranslationUnitImpl();
78 D->CIdx = CIdx;
David Blaikieea4395e2017-01-06 19:49:01 +000079 D->TheASTUnit = AU.release();
Dmitri Gribenko74895212013-02-03 13:52:47 +000080 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000081 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000082 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000083 D->CommentToXML = nullptr;
Alex Lorenz690f0e22017-12-07 20:37:50 +000084 D->ParsingOptions = 0;
85 D->Arguments = {};
Guy Benyei11169dd2012-12-18 14:30:41 +000086 return D;
87}
88
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000089bool cxtu::isASTReadError(ASTUnit *AU) {
90 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
91 DEnd = AU->stored_diag_end();
92 D != DEnd; ++D) {
93 if (D->getLevel() >= DiagnosticsEngine::Error &&
94 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
95 diag::DiagCat_AST_Deserialization_Issue)
96 return true;
97 }
98 return false;
99}
100
Guy Benyei11169dd2012-12-18 14:30:41 +0000101cxtu::CXTUOwner::~CXTUOwner() {
102 if (TU)
103 clang_disposeTranslationUnit(TU);
104}
105
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000106/// Compare two source ranges to determine their relative position in
Guy Benyei11169dd2012-12-18 14:30:41 +0000107/// the translation unit.
Michael Kruse7520cf02020-03-25 09:26:14 -0500108static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1,
Guy Benyei11169dd2012-12-18 14:30:41 +0000109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000121/// Determine if a source location falls within, before, or after a
Guy Benyei11169dd2012-12-18 14:30:41 +0000122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000136/// Translate a Clang source range into a CIndex source range.
Guy Benyei11169dd2012-12-18 14:30:41 +0000137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
Richard Smithb5f81712018-04-30 05:25:48 +0000148 bool IsTokenRange = R.isTokenRange();
Michael Kruse7520cf02020-03-25 09:26:14 -0500149 if (EndLoc.isValid() && EndLoc.isMacroID() &&
150 !SM.isMacroArgExpansion(EndLoc)) {
Richard Smithb5f81712018-04-30 05:25:48 +0000151 CharSourceRange Expansion = SM.getExpansionRange(EndLoc);
152 EndLoc = Expansion.getEnd();
153 IsTokenRange = Expansion.isTokenRange();
154 }
155 if (IsTokenRange && EndLoc.isValid()) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500156 unsigned Length =
157 Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);
Guy Benyei11169dd2012-12-18 14:30:41 +0000158 EndLoc = EndLoc.getLocWithOffset(Length);
159 }
160
Bill Wendlingeade3622013-01-23 08:25:41 +0000161 CXSourceRange Result = {
Michael Kruse7520cf02020-03-25 09:26:14 -0500162 {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};
Guy Benyei11169dd2012-12-18 14:30:41 +0000163 return Result;
164}
165
166//===----------------------------------------------------------------------===//
167// Cursor visitor.
168//===----------------------------------------------------------------------===//
169
170static SourceRange getRawCursorExtent(CXCursor C);
171static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
172
Guy Benyei11169dd2012-12-18 14:30:41 +0000173RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
174 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
175}
176
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000177/// Visit the given cursor and, if requested by the visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +0000178/// its children.
179///
180/// \param Cursor the cursor to visit.
181///
182/// \param CheckedRegionOfInterest if true, then the caller already checked
183/// that this cursor is within the region of interest.
184///
185/// \returns true if the visitation should be aborted, false if it
186/// should continue.
187bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
188 if (clang_isInvalid(Cursor.kind))
189 return false;
190
191 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000192 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000193 if (!D) {
194 assert(0 && "Invalid declaration cursor");
195 return true; // abort.
196 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500197
Guy Benyei11169dd2012-12-18 14:30:41 +0000198 // Ignore implicit declarations, unless it's an objc method because
199 // currently we should report implicit methods for properties when indexing.
200 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
201 return false;
202 }
203
204 // If we have a range of interest, and this cursor doesn't intersect with it,
205 // we're done.
206 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
207 SourceRange Range = getRawCursorExtent(Cursor);
208 if (Range.isInvalid() || CompareRegionOfInterest(Range))
209 return false;
210 }
211
212 switch (Visitor(Cursor, Parent, ClientData)) {
213 case CXChildVisit_Break:
214 return true;
215
216 case CXChildVisit_Continue:
217 return false;
218
219 case CXChildVisit_Recurse: {
220 bool ret = VisitChildren(Cursor);
221 if (PostChildrenVisitor)
222 if (PostChildrenVisitor(Cursor, ClientData))
223 return true;
224 return ret;
225 }
226 }
227
228 llvm_unreachable("Invalid CXChildVisitResult!");
229}
230
231static bool visitPreprocessedEntitiesInRange(SourceRange R,
232 PreprocessingRecord &PPRec,
233 CursorVisitor &Visitor) {
234 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
235 FileID FID;
Michael Kruse7520cf02020-03-25 09:26:14 -0500236
Guy Benyei11169dd2012-12-18 14:30:41 +0000237 if (!Visitor.shouldVisitIncludedEntities()) {
238 // If the begin/end of the range lie in the same FileID, do the optimization
Michael Kruse7520cf02020-03-25 09:26:14 -0500239 // where we skip preprocessed entities that do not come from the same
240 // FileID.
Guy Benyei11169dd2012-12-18 14:30:41 +0000241 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
242 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
243 FID = FileID();
244 }
245
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000246 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
247 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000248 PPRec, FID);
249}
250
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000252 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000253 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000254
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000255 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000256 SourceManager &SM = Unit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -0500257
258 std::pair<FileID, unsigned> Begin = SM.getDecomposedLoc(
259 SM.getFileLoc(RegionOfInterest.getBegin())),
260 End = SM.getDecomposedLoc(
261 SM.getFileLoc(RegionOfInterest.getEnd()));
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 if (End.first != Begin.first) {
264 // If the end does not reside in the same file, try to recover by
265 // picking the end of the file of begin location.
266 End.first = Begin.first;
267 End.second = SM.getFileIDSize(Begin.first);
268 }
269
270 assert(Begin.first == End.first);
271 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000272 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -0500273
Guy Benyei11169dd2012-12-18 14:30:41 +0000274 FileID File = Begin.first;
275 unsigned Offset = Begin.second;
276 unsigned Length = End.second - Begin.second;
277
278 if (!VisitDeclsOnly && !VisitPreprocessorLast)
279 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000282 if (visitDeclsFromFileRegion(File, Offset, Length))
283 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000284
285 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000286 return visitPreprocessedEntitiesInRegion();
287
288 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000289}
290
291static bool isInLexicalContext(Decl *D, DeclContext *DC) {
292 if (!DC)
293 return false;
294
Michael Kruse7520cf02020-03-25 09:26:14 -0500295 for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;
296 DeclDC = DeclDC->getLexicalParent()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000297 if (DeclDC == DC)
298 return true;
299 }
300 return false;
301}
302
Michael Kruse7520cf02020-03-25 09:26:14 -0500303bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,
304 unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000305 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000306 SourceManager &SM = Unit->getSourceManager();
307 SourceRange Range = RegionOfInterest;
308
309 SmallVector<Decl *, 16> Decls;
310 Unit->findFileRegionDecls(File, Offset, Length, Decls);
311
312 // If we didn't find any file level decls for the file, try looking at the
313 // file that it was included from.
314 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
315 bool Invalid = false;
316 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
317 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000318 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000319
320 SourceLocation Outer;
321 if (SLEntry.isFile())
322 Outer = SLEntry.getFile().getIncludeLoc();
323 else
324 Outer = SLEntry.getExpansion().getExpansionLocStart();
325 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000326 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000327
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000328 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000329 Length = 0;
330 Unit->findFileRegionDecls(File, Offset, Length, Decls);
331 }
332
333 assert(!Decls.empty());
334
335 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000336 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000337 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
338 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000339 Decl *D = *DIt;
340 if (D->getSourceRange().isInvalid())
341 continue;
342
343 if (isInLexicalContext(D, CurDC))
344 continue;
345
346 CurDC = dyn_cast<DeclContext>(D);
347
348 if (TagDecl *TD = dyn_cast<TagDecl>(D))
349 if (!TD->isFreeStanding())
350 continue;
351
Michael Kruse7520cf02020-03-25 09:26:14 -0500352 RangeComparisonResult CompRes =
353 RangeCompare(SM, D->getSourceRange(), Range);
Guy Benyei11169dd2012-12-18 14:30:41 +0000354 if (CompRes == RangeBefore)
355 continue;
356 if (CompRes == RangeAfter)
357 break;
358
359 assert(CompRes == RangeOverlap);
360 VisitedAtLeastOnce = true;
361
362 if (isa<ObjCContainerDecl>(D)) {
363 FileDI_current = &DIt;
364 FileDE_current = DE;
365 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000366 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000371 }
372
373 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000374 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000375
376 // No Decls overlapped with the range. Move up the lexical context until there
377 // is a context that contains the range or we reach the translation unit
378 // level.
Michael Kruse7520cf02020-03-25 09:26:14 -0500379 DeclContext *DC = DIt == Decls.begin()
380 ? (*DIt)->getLexicalDeclContext()
381 : (*(DIt - 1))->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +0000382
383 while (DC && !DC->isTranslationUnit()) {
384 Decl *D = cast<Decl>(DC);
385 SourceRange CurDeclRange = D->getSourceRange();
386 if (CurDeclRange.isInvalid())
387 break;
388
389 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000390 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
391 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000392 }
393
394 DC = D->getLexicalDeclContext();
395 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000396
397 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000398}
399
400bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
401 if (!AU->getPreprocessor().getPreprocessingRecord())
402 return false;
403
Michael Kruse7520cf02020-03-25 09:26:14 -0500404 PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();
Guy Benyei11169dd2012-12-18 14:30:41 +0000405 SourceManager &SM = AU->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -0500406
Guy Benyei11169dd2012-12-18 14:30:41 +0000407 if (RegionOfInterest.isValid()) {
408 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
409 SourceLocation B = MappedRange.getBegin();
410 SourceLocation E = MappedRange.getEnd();
411
412 if (AU->isInPreambleFileID(B)) {
413 if (SM.isLoadedSourceLocation(E))
Michael Kruse7520cf02020-03-25 09:26:14 -0500414 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,
415 *this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000416
417 // Beginning of range lies in the preamble but it also extends beyond
418 // it into the main file. Split the range into 2 parts, one covering
419 // the preamble and another covering the main file. This allows subsequent
420 // calls to visitPreprocessedEntitiesInRange to accept a source range that
421 // lies in the same FileID, allowing it to skip preprocessed entities that
422 // do not come from the same FileID.
Michael Kruse7520cf02020-03-25 09:26:14 -0500423 bool breaked = visitPreprocessedEntitiesInRange(
424 SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);
425 if (breaked)
426 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000427 return visitPreprocessedEntitiesInRange(
Michael Kruse7520cf02020-03-25 09:26:14 -0500428 SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000429 }
430
431 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
432 }
433
Michael Kruse7520cf02020-03-25 09:26:14 -0500434 bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
435
Guy Benyei11169dd2012-12-18 14:30:41 +0000436 if (OnlyLocalDecls)
437 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
438 PPRec);
439
440 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
441}
442
Michael Kruse7520cf02020-03-25 09:26:14 -0500443template <typename InputIterator>
Guy Benyei11169dd2012-12-18 14:30:41 +0000444bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
445 InputIterator Last,
446 PreprocessingRecord &PPRec,
447 FileID FID) {
448 for (; First != Last; ++First) {
449 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
450 continue;
451
452 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000453 if (!PPE)
454 continue;
455
Guy Benyei11169dd2012-12-18 14:30:41 +0000456 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
457 if (Visit(MakeMacroExpansionCursor(ME, TU)))
458 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000459
Guy Benyei11169dd2012-12-18 14:30:41 +0000460 continue;
461 }
Richard Smith66a81862015-05-04 02:25:31 +0000462
463 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000464 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
465 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000466
Guy Benyei11169dd2012-12-18 14:30:41 +0000467 continue;
468 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500469
Guy Benyei11169dd2012-12-18 14:30:41 +0000470 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
471 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
472 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500473
Guy Benyei11169dd2012-12-18 14:30:41 +0000474 continue;
475 }
476 }
477
478 return false;
479}
480
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000481/// Visit the children of the given cursor.
Michael Kruse7520cf02020-03-25 09:26:14 -0500482///
Guy Benyei11169dd2012-12-18 14:30:41 +0000483/// \returns true if the visitation should be aborted, false if it
484/// should continue.
485bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500486 if (clang_isReference(Cursor.kind) &&
Guy Benyei11169dd2012-12-18 14:30:41 +0000487 Cursor.kind != CXCursor_CXXBaseSpecifier) {
488 // By definition, references have no children.
489 return false;
490 }
491
492 // Set the Parent field to Cursor, then back to its old value once we're
493 // done.
494 SetParentRAII SetParent(Parent, StmtParent, Cursor);
495
496 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000497 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000498 if (!D)
499 return false;
500
501 return VisitAttributes(D) || Visit(D);
502 }
503
504 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000505 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000506 return Visit(S);
507
508 return false;
509 }
510
511 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000512 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000513 return Visit(E);
514
515 return false;
516 }
517
518 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000519 CXTranslationUnit TU = getCursorTU(Cursor);
520 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -0500521
522 int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
Guy Benyei11169dd2012-12-18 14:30:41 +0000523 for (unsigned I = 0; I != 2; ++I) {
524 if (VisitOrder[I]) {
525 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
526 RegionOfInterest.isInvalid()) {
527 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -0500528 TLEnd = CXXUnit->top_level_end();
Guy Benyei11169dd2012-12-18 14:30:41 +0000529 TL != TLEnd; ++TL) {
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000530 const Optional<bool> V = handleDeclForVisitation(*TL);
531 if (!V.hasValue())
532 continue;
533 return V.getValue();
Guy Benyei11169dd2012-12-18 14:30:41 +0000534 }
535 } else if (VisitDeclContext(
Michael Kruse7520cf02020-03-25 09:26:14 -0500536 CXXUnit->getASTContext().getTranslationUnitDecl()))
Guy Benyei11169dd2012-12-18 14:30:41 +0000537 return true;
538 continue;
539 }
540
541 // Walk the preprocessing record.
542 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
543 visitPreprocessedEntitiesInRegion();
544 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500545
Guy Benyei11169dd2012-12-18 14:30:41 +0000546 return false;
547 }
548
549 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000550 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000551 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
552 return Visit(BaseTSInfo->getTypeLoc());
553 }
554 }
555 }
556
557 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000558 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -0500559 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000560 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000561 return Visit(cxcursor::MakeCursorObjCClassRef(
562 ObjT->getInterface(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000563 A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000564 }
565
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000566 // If pointing inside a macro definition, check if the token is an identifier
567 // that was ever defined as a macro. In such a case, create a "pseudo" macro
568 // expansion cursor for that token.
569 SourceLocation BeginLoc = RegionOfInterest.getBegin();
570 if (Cursor.kind == CXCursor_MacroDefinition &&
571 BeginLoc == RegionOfInterest.getEnd()) {
572 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000573 const MacroInfo *MI =
574 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000575 if (MacroDefinitionRecord *MacroDef =
576 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000577 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
578 }
579
Guy Benyei11169dd2012-12-18 14:30:41 +0000580 // Nothing to visit at the moment.
581 return false;
582}
583
584bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
585 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
586 if (Visit(TSInfo->getTypeLoc()))
Michael Kruse7520cf02020-03-25 09:26:14 -0500587 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000588
589 if (Stmt *Body = B->getBody())
590 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
591
592 return false;
593}
594
Ted Kremenek03325582013-02-21 01:29:01 +0000595Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000596 if (RegionOfInterest.isValid()) {
597 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
598 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000599 return None;
Michael Kruse7520cf02020-03-25 09:26:14 -0500600
Guy Benyei11169dd2012-12-18 14:30:41 +0000601 switch (CompareRegionOfInterest(Range)) {
602 case RangeBefore:
603 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000604 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000605
606 case RangeAfter:
607 // This declaration comes after the region of interest; we're done.
608 return false;
609
610 case RangeOverlap:
611 // This declaration overlaps the region of interest; visit it.
612 break;
613 }
614 }
615 return true;
616}
617
618bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
619 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
620
621 // FIXME: Eventually remove. This part of a hack to support proper
622 // iteration over all Decls contained lexically within an ObjC container.
Michael Kruse7520cf02020-03-25 09:26:14 -0500623 SaveAndRestore<DeclContext::decl_iterator *> DI_saved(DI_current, &I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000624 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
625
Michael Kruse7520cf02020-03-25 09:26:14 -0500626 for (; I != E; ++I) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000627 Decl *D = *I;
628 if (D->getLexicalDeclContext() != DC)
629 continue;
Adrian Prantl2073dd22019-11-04 14:28:14 -0800630 // Filter out synthesized property accessor redeclarations.
631 if (isa<ObjCImplDecl>(DC))
632 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
633 if (OMD->isSynthesizedAccessorStub())
634 continue;
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000635 const Optional<bool> V = handleDeclForVisitation(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000636 if (!V.hasValue())
637 continue;
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000638 return V.getValue();
Guy Benyei11169dd2012-12-18 14:30:41 +0000639 }
640 return false;
641}
642
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000643Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
644 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
645
646 // Ignore synthesized ivars here, otherwise if we have something like:
647 // @synthesize prop = _prop;
648 // and '_prop' is not declared, we will encounter a '_prop' ivar before
649 // encountering the 'prop' synthesize declaration and we will think that
650 // we passed the region-of-interest.
651 if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
652 if (ivarD->getSynthesize())
653 return None;
654 }
655
656 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
657 // declarations is a mismatch with the compiler semantics.
658 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
659 auto *ID = cast<ObjCInterfaceDecl>(D);
660 if (!ID->isThisDeclarationADefinition())
661 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
662
663 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
664 auto *PD = cast<ObjCProtocolDecl>(D);
665 if (!PD->isThisDeclarationADefinition())
666 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
667 }
668
669 const Optional<bool> V = shouldVisitCursor(Cursor);
670 if (!V.hasValue())
671 return None;
672 if (!V.getValue())
673 return false;
674 if (Visit(Cursor, true))
675 return true;
676 return None;
677}
678
Guy Benyei11169dd2012-12-18 14:30:41 +0000679bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
680 llvm_unreachable("Translation units are visited directly by Visit()");
681}
682
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000683bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500684 if (VisitTemplateParameters(D->getTemplateParameters()))
685 return true;
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000686
Michael Kruse7520cf02020-03-25 09:26:14 -0500687 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000688}
689
Guy Benyei11169dd2012-12-18 14:30:41 +0000690bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
691 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
692 return Visit(TSInfo->getTypeLoc());
693
694 return false;
695}
696
697bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
698 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
699 return Visit(TSInfo->getTypeLoc());
700
701 return false;
702}
703
Michael Kruse7520cf02020-03-25 09:26:14 -0500704bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }
Guy Benyei11169dd2012-12-18 14:30:41 +0000705
706bool CursorVisitor::VisitClassTemplateSpecializationDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -0500707 ClassTemplateSpecializationDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000708 bool ShouldVisitBody = false;
709 switch (D->getSpecializationKind()) {
710 case TSK_Undeclared:
711 case TSK_ImplicitInstantiation:
712 // Nothing to visit
713 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -0500714
Guy Benyei11169dd2012-12-18 14:30:41 +0000715 case TSK_ExplicitInstantiationDeclaration:
716 case TSK_ExplicitInstantiationDefinition:
717 break;
Michael Kruse7520cf02020-03-25 09:26:14 -0500718
Guy Benyei11169dd2012-12-18 14:30:41 +0000719 case TSK_ExplicitSpecialization:
720 ShouldVisitBody = true;
721 break;
722 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500723
Guy Benyei11169dd2012-12-18 14:30:41 +0000724 // Visit the template arguments used in the specialization.
725 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
726 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000727 if (TemplateSpecializationTypeLoc TSTLoc =
728 TL.getAs<TemplateSpecializationTypeLoc>()) {
729 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
730 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 return true;
732 }
733 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000734
735 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000736}
737
738bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -0500739 ClassTemplatePartialSpecializationDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000740 // FIXME: Visit the "outer" template parameter lists on the TagDecl
741 // before visiting these template parameters.
742 if (VisitTemplateParameters(D->getTemplateParameters()))
743 return true;
744
745 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000746 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
747 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
748 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000749 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
750 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500751
Guy Benyei11169dd2012-12-18 14:30:41 +0000752 return VisitCXXRecordDecl(D);
753}
754
755bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Saar Razff1e0fc2020-01-15 02:48:42 +0200756 if (const auto *TC = D->getTypeConstraint())
757 if (Visit(MakeCXCursor(TC->getImmediatelyDeclaredConstraint(), StmtParent,
758 TU, RegionOfInterest)))
759 return true;
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 // Visit the default argument.
762 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
763 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
764 if (Visit(DefArg->getTypeLoc()))
765 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500766
Guy Benyei11169dd2012-12-18 14:30:41 +0000767 return false;
768}
769
770bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
771 if (Expr *Init = D->getInitExpr())
772 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
773 return false;
774}
775
776bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000777 unsigned NumParamList = DD->getNumTemplateParameterLists();
778 for (unsigned i = 0; i < NumParamList; i++) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500779 TemplateParameterList *Params = DD->getTemplateParameterList(i);
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 if (VisitTemplateParameters(Params))
781 return true;
782 }
783
Guy Benyei11169dd2012-12-18 14:30:41 +0000784 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
785 if (Visit(TSInfo->getTypeLoc()))
786 return true;
787
788 // Visit the nested-name-specifier, if present.
789 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
790 if (VisitNestedNameSpecifierLoc(QualifierLoc))
791 return true;
792
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000793 return false;
794}
795
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000796static bool HasTrailingReturnType(FunctionDecl *ND) {
797 const QualType Ty = ND->getType();
798 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
799 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
800 return FT->hasTrailingReturn();
801 }
802
803 return false;
804}
805
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000806/// Compare two base or member initializers based on their source order.
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000807static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
808 CXXCtorInitializer *const *Y) {
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000809 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
810}
811
Guy Benyei11169dd2012-12-18 14:30:41 +0000812bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000813 unsigned NumParamList = ND->getNumTemplateParameterLists();
814 for (unsigned i = 0; i < NumParamList; i++) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500815 TemplateParameterList *Params = ND->getTemplateParameterList(i);
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000816 if (VisitTemplateParameters(Params))
817 return true;
818 }
819
Guy Benyei11169dd2012-12-18 14:30:41 +0000820 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
821 // Visit the function declaration's syntactic components in the order
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000822 // written. This requires a bit of work.
823 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
824 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000825 const bool HasTrailingRT = HasTrailingReturnType(ND);
Michael Kruse7520cf02020-03-25 09:26:14 -0500826
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000827 // If we have a function declared directly (without the use of a typedef),
828 // visit just the return type. Otherwise, just visit the function's type
829 // now.
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000830 if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
831 Visit(FTL.getReturnLoc())) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000832 (!FTL && Visit(TL)))
833 return true;
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000834
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000835 // Visit the nested-name-specifier, if present.
836 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
837 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +0000838 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500839
Guy Benyei11169dd2012-12-18 14:30:41 +0000840 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000841 if (!isa<CXXDestructorDecl>(ND))
842 if (VisitDeclarationNameInfo(ND->getNameInfo()))
843 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500844
Guy Benyei11169dd2012-12-18 14:30:41 +0000845 // FIXME: Visit explicitly-specified template arguments!
Michael Kruse7520cf02020-03-25 09:26:14 -0500846
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000847 // Visit the function parameters, if we have a function type.
848 if (FTL && VisitFunctionTypeLoc(FTL, true))
849 return true;
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000850
851 // Visit the function's trailing return type.
852 if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
853 return true;
854
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000855 // FIXME: Attributes?
856 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500857
Guy Benyei11169dd2012-12-18 14:30:41 +0000858 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
859 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
860 // Find the initializers that were written in the source.
861 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000862 for (auto *I : Constructor->inits()) {
863 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000864 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -0500865
Aaron Ballman0ad78302014-03-13 17:34:31 +0000866 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000867 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500868
Guy Benyei11169dd2012-12-18 14:30:41 +0000869 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000870 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
871 &CompareCXXCtorInitializers);
Michael Kruse7520cf02020-03-25 09:26:14 -0500872
Guy Benyei11169dd2012-12-18 14:30:41 +0000873 // Visit the initializers in source order
874 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
875 CXXCtorInitializer *Init = WrittenInits[I];
876 if (Init->isAnyMemberInitializer()) {
877 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
878 Init->getMemberLocation(), TU)))
879 return true;
880 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
881 if (Visit(TInfo->getTypeLoc()))
882 return true;
883 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500884
Guy Benyei11169dd2012-12-18 14:30:41 +0000885 // Visit the initializer value.
886 if (Expr *Initializer = Init->getInit())
887 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
888 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500889 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000890 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500891
Guy Benyei11169dd2012-12-18 14:30:41 +0000892 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
893 return true;
894 }
895
896 return false;
897}
898
899bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
900 if (VisitDeclaratorDecl(D))
901 return true;
902
903 if (Expr *BitWidth = D->getBitWidth())
904 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
905
Benjamin Kramer99f97592017-11-15 12:20:41 +0000906 if (Expr *Init = D->getInClassInitializer())
907 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
908
Guy Benyei11169dd2012-12-18 14:30:41 +0000909 return false;
910}
911
912bool CursorVisitor::VisitVarDecl(VarDecl *D) {
913 if (VisitDeclaratorDecl(D))
914 return true;
915
916 if (Expr *Init = D->getInit())
917 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
918
919 return false;
920}
921
922bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
923 if (VisitDeclaratorDecl(D))
924 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500925
Guy Benyei11169dd2012-12-18 14:30:41 +0000926 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
927 if (Expr *DefArg = D->getDefaultArgument())
928 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
Michael Kruse7520cf02020-03-25 09:26:14 -0500929
930 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000931}
932
933bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
934 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
935 // before visiting these template parameters.
936 if (VisitTemplateParameters(D->getTemplateParameters()))
937 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500938
939 auto *FD = D->getTemplatedDecl();
Jonathan Coe578ac7a2017-10-16 23:43:02 +0000940 return VisitAttributes(FD) || VisitFunctionDecl(FD);
Guy Benyei11169dd2012-12-18 14:30:41 +0000941}
942
943bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
944 // FIXME: Visit the "outer" template parameter lists on the TagDecl
945 // before visiting these template parameters.
946 if (VisitTemplateParameters(D->getTemplateParameters()))
947 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500948
949 auto *CD = D->getTemplatedDecl();
Jonathan Coe578ac7a2017-10-16 23:43:02 +0000950 return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
Guy Benyei11169dd2012-12-18 14:30:41 +0000951}
952
953bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
954 if (VisitTemplateParameters(D->getTemplateParameters()))
955 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500956
Guy Benyei11169dd2012-12-18 14:30:41 +0000957 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
958 VisitTemplateArgumentLoc(D->getDefaultArgument()))
959 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500960
Guy Benyei11169dd2012-12-18 14:30:41 +0000961 return false;
962}
963
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000964bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
965 // Visit the bound, if it's explicit.
966 if (D->hasExplicitBound()) {
967 if (auto TInfo = D->getTypeSourceInfo()) {
968 if (Visit(TInfo->getTypeLoc()))
969 return true;
970 }
971 }
972
973 return false;
974}
975
Guy Benyei11169dd2012-12-18 14:30:41 +0000976bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000977 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000978 if (Visit(TSInfo->getTypeLoc()))
979 return true;
980
David Majnemer59f77922016-06-24 04:05:48 +0000981 for (const auto *P : ND->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +0000982 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000983 return true;
984 }
985
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000986 return ND->isThisDeclarationADefinition() &&
987 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000988}
989
990template <typename DeclIt>
991static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
992 SourceManager &SM, SourceLocation EndLoc,
993 SmallVectorImpl<Decl *> &Decls) {
994 DeclIt next = *DI_current;
995 while (++next != DE_current) {
996 Decl *D_next = *next;
997 if (!D_next)
998 break;
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000999 SourceLocation L = D_next->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00001000 if (!L.isValid())
1001 break;
1002 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
1003 *DI_current = next;
1004 Decls.push_back(D_next);
1005 continue;
1006 }
1007 break;
1008 }
1009}
1010
Guy Benyei11169dd2012-12-18 14:30:41 +00001011bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
1012 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
1013 // an @implementation can lexically contain Decls that are not properly
1014 // nested in the AST. When we identify such cases, we need to retrofit
1015 // this nesting here.
1016 if (!DI_current && !FileDI_current)
1017 return VisitDeclContext(D);
1018
1019 // Scan the Decls that immediately come after the container
1020 // in the current DeclContext. If any fall within the
1021 // container's lexical region, stash them into a vector
1022 // for later processing.
1023 SmallVector<Decl *, 24> DeclsInContainer;
1024 SourceLocation EndLoc = D->getSourceRange().getEnd();
1025 SourceManager &SM = AU->getSourceManager();
1026 if (EndLoc.isValid()) {
1027 if (DI_current) {
1028 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
1029 DeclsInContainer);
1030 } else {
1031 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
1032 DeclsInContainer);
1033 }
1034 }
1035
1036 // The common case.
1037 if (DeclsInContainer.empty())
1038 return VisitDeclContext(D);
1039
1040 // Get all the Decls in the DeclContext, and sort them with the
1041 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001042 for (auto *SubDecl : D->decls()) {
1043 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001044 SubDecl->getBeginLoc().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001045 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001046 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001047 }
1048
1049 // Now sort the Decls so that they appear in lexical order.
Michael Kruse7520cf02020-03-25 09:26:14 -05001050 llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {
1051 SourceLocation L_A = A->getBeginLoc();
1052 SourceLocation L_B = B->getBeginLoc();
1053 return L_A != L_B
1054 ? SM.isBeforeInTranslationUnit(L_A, L_B)
1055 : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());
1056 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001057
1058 // Now visit the decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05001059 for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),
1060 E = DeclsInContainer.end();
1061 I != E; ++I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001062 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001063 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001064 if (!V.hasValue())
1065 continue;
1066 if (!V.getValue())
1067 return false;
1068 if (Visit(Cursor, true))
1069 return true;
1070 }
1071 return false;
1072}
1073
1074bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1075 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1076 TU)))
1077 return true;
1078
Douglas Gregore9d95f12015-07-07 03:57:35 +00001079 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1080 return true;
1081
Guy Benyei11169dd2012-12-18 14:30:41 +00001082 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1083 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001084 E = ND->protocol_end();
1085 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001086 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1087 return true;
1088
1089 return VisitObjCContainerDecl(ND);
1090}
1091
1092bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1093 if (!PID->isThisDeclarationADefinition())
1094 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001095
Guy Benyei11169dd2012-12-18 14:30:41 +00001096 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1097 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001098 E = PID->protocol_end();
1099 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001100 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1101 return true;
1102
1103 return VisitObjCContainerDecl(PID);
1104}
1105
1106bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1107 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1108 return true;
1109
1110 // FIXME: This implements a workaround with @property declarations also being
1111 // installed in the DeclContext for the @interface. Eventually this code
1112 // should be removed.
1113 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1114 if (!CDecl || !CDecl->IsClassExtension())
1115 return false;
1116
1117 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1118 if (!ID)
1119 return false;
1120
1121 IdentifierInfo *PropertyId = PD->getIdentifier();
Michael Kruse7520cf02020-03-25 09:26:14 -05001122 ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
1123 cast<DeclContext>(ID), PropertyId, PD->getQueryKind());
Guy Benyei11169dd2012-12-18 14:30:41 +00001124
1125 if (!prevDecl)
1126 return false;
1127
1128 // Visit synthesized methods since they will be skipped when visiting
1129 // the @interface.
1130 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1131 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1132 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1133 return true;
1134
1135 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1136 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1137 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1138 return true;
1139
1140 return false;
1141}
1142
Douglas Gregore9d95f12015-07-07 03:57:35 +00001143bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1144 if (!typeParamList)
1145 return false;
1146
1147 for (auto *typeParam : *typeParamList) {
1148 // Visit the type parameter.
1149 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1150 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001151 }
1152
1153 return false;
1154}
1155
Guy Benyei11169dd2012-12-18 14:30:41 +00001156bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1157 if (!D->isThisDeclarationADefinition()) {
1158 // Forward declaration is treated like a reference.
1159 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1160 }
1161
Douglas Gregore9d95f12015-07-07 03:57:35 +00001162 // Objective-C type parameters.
1163 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1164 return true;
1165
Guy Benyei11169dd2012-12-18 14:30:41 +00001166 // Issue callbacks for super class.
Michael Kruse7520cf02020-03-25 09:26:14 -05001167 if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
1168 D->getSuperClass(), D->getSuperClassLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001169 return true;
1170
Douglas Gregore9d95f12015-07-07 03:57:35 +00001171 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1172 if (Visit(SuperClassTInfo->getTypeLoc()))
1173 return true;
1174
Guy Benyei11169dd2012-12-18 14:30:41 +00001175 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1176 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001177 E = D->protocol_end();
1178 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001179 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1180 return true;
1181
1182 return VisitObjCContainerDecl(D);
1183}
1184
1185bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1186 return VisitObjCContainerDecl(D);
1187}
1188
1189bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1190 // 'ID' could be null when dealing with invalid code.
1191 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1192 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1193 return true;
1194
1195 return VisitObjCImplDecl(D);
1196}
1197
1198bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1199#if 0
1200 // Issue callbacks for super class.
1201 // FIXME: No source location information!
1202 if (D->getSuperClass() &&
1203 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1204 D->getSuperClassLoc(),
1205 TU)))
1206 return true;
1207#endif
1208
1209 return VisitObjCImplDecl(D);
1210}
1211
1212bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1213 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1214 if (PD->isIvarNameSpecified())
1215 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001216
Guy Benyei11169dd2012-12-18 14:30:41 +00001217 return false;
1218}
1219
1220bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1221 return VisitDeclContext(D);
1222}
1223
1224bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1225 // Visit nested-name-specifier.
1226 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1227 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1228 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001229
1230 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001231 D->getTargetNameLoc(), TU));
1232}
1233
1234bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1235 // Visit nested-name-specifier.
1236 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1237 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1238 return true;
1239 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001240
Guy Benyei11169dd2012-12-18 14:30:41 +00001241 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1242 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001243
Guy Benyei11169dd2012-12-18 14:30:41 +00001244 return VisitDeclarationNameInfo(D->getNameInfo());
1245}
1246
1247bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1248 // Visit nested-name-specifier.
1249 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1250 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1251 return true;
1252
1253 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1254 D->getIdentLocation(), TU));
1255}
1256
1257bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1258 // Visit nested-name-specifier.
1259 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1260 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1261 return true;
1262 }
1263
1264 return VisitDeclarationNameInfo(D->getNameInfo());
1265}
1266
1267bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -05001268 UnresolvedUsingTypenameDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001269 // Visit nested-name-specifier.
1270 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1271 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1272 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001273
Guy Benyei11169dd2012-12-18 14:30:41 +00001274 return false;
1275}
1276
Olivier Goffart81978012016-06-09 16:15:55 +00001277bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
1278 if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
1279 return true;
Richard Trieuf3b77662016-09-13 01:37:01 +00001280 if (StringLiteral *Message = D->getMessage())
1281 if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
1282 return true;
Olivier Goffart81978012016-06-09 16:15:55 +00001283 return false;
1284}
1285
Olivier Goffartd211c642016-11-04 06:29:27 +00001286bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {
1287 if (NamedDecl *FriendD = D->getFriendDecl()) {
1288 if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))
1289 return true;
1290 } else if (TypeSourceInfo *TI = D->getFriendType()) {
1291 if (Visit(TI->getTypeLoc()))
1292 return true;
1293 }
1294 return false;
1295}
1296
Guy Benyei11169dd2012-12-18 14:30:41 +00001297bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1298 switch (Name.getName().getNameKind()) {
1299 case clang::DeclarationName::Identifier:
1300 case clang::DeclarationName::CXXLiteralOperatorName:
Richard Smith35845152017-02-07 01:37:30 +00001301 case clang::DeclarationName::CXXDeductionGuideName:
Guy Benyei11169dd2012-12-18 14:30:41 +00001302 case clang::DeclarationName::CXXOperatorName:
1303 case clang::DeclarationName::CXXUsingDirective:
1304 return false;
Richard Smith35845152017-02-07 01:37:30 +00001305
Guy Benyei11169dd2012-12-18 14:30:41 +00001306 case clang::DeclarationName::CXXConstructorName:
1307 case clang::DeclarationName::CXXDestructorName:
1308 case clang::DeclarationName::CXXConversionFunctionName:
1309 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1310 return Visit(TSInfo->getTypeLoc());
1311 return false;
1312
1313 case clang::DeclarationName::ObjCZeroArgSelector:
1314 case clang::DeclarationName::ObjCOneArgSelector:
1315 case clang::DeclarationName::ObjCMultiArgSelector:
1316 // FIXME: Per-identifier location info?
1317 return false;
1318 }
1319
1320 llvm_unreachable("Invalid DeclarationName::Kind!");
1321}
1322
Michael Kruse7520cf02020-03-25 09:26:14 -05001323bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
Guy Benyei11169dd2012-12-18 14:30:41 +00001324 SourceRange Range) {
1325 // FIXME: This whole routine is a hack to work around the lack of proper
1326 // source information in nested-name-specifiers (PR5791). Since we do have
1327 // a beginning source location, we can visit the first component of the
1328 // nested-name-specifier, if it's a single-token component.
1329 if (!NNS)
1330 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001331
Guy Benyei11169dd2012-12-18 14:30:41 +00001332 // Get the first component in the nested-name-specifier.
1333 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1334 NNS = Prefix;
Michael Kruse7520cf02020-03-25 09:26:14 -05001335
Guy Benyei11169dd2012-12-18 14:30:41 +00001336 switch (NNS->getKind()) {
1337 case NestedNameSpecifier::Namespace:
Michael Kruse7520cf02020-03-25 09:26:14 -05001338 return Visit(
1339 MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001340
1341 case NestedNameSpecifier::NamespaceAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05001342 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001343 Range.getBegin(), TU));
1344
1345 case NestedNameSpecifier::TypeSpec: {
1346 // If the type has a form where we know that the beginning of the source
1347 // range matches up with a reference cursor. Visit the appropriate reference
1348 // cursor.
1349 const Type *T = NNS->getAsType();
1350 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1351 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1352 if (const TagType *Tag = dyn_cast<TagType>(T))
1353 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001354 if (const TemplateSpecializationType *TST =
1355 dyn_cast<TemplateSpecializationType>(T))
Guy Benyei11169dd2012-12-18 14:30:41 +00001356 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1357 break;
1358 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001359
Guy Benyei11169dd2012-12-18 14:30:41 +00001360 case NestedNameSpecifier::TypeSpecWithTemplate:
1361 case NestedNameSpecifier::Global:
1362 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001363 case NestedNameSpecifier::Super:
Michael Kruse7520cf02020-03-25 09:26:14 -05001364 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001365 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001366
Guy Benyei11169dd2012-12-18 14:30:41 +00001367 return false;
1368}
1369
Michael Kruse7520cf02020-03-25 09:26:14 -05001370bool CursorVisitor::VisitNestedNameSpecifierLoc(
1371 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001372 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1373 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1374 Qualifiers.push_back(Qualifier);
Michael Kruse7520cf02020-03-25 09:26:14 -05001375
Guy Benyei11169dd2012-12-18 14:30:41 +00001376 while (!Qualifiers.empty()) {
1377 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1378 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1379 switch (NNS->getKind()) {
1380 case NestedNameSpecifier::Namespace:
Michael Kruse7520cf02020-03-25 09:26:14 -05001381 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1382 Q.getLocalBeginLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001383 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001384
Guy Benyei11169dd2012-12-18 14:30:41 +00001385 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001386
Guy Benyei11169dd2012-12-18 14:30:41 +00001387 case NestedNameSpecifier::NamespaceAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05001388 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1389 Q.getLocalBeginLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001390 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001391
Guy Benyei11169dd2012-12-18 14:30:41 +00001392 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001393
Guy Benyei11169dd2012-12-18 14:30:41 +00001394 case NestedNameSpecifier::TypeSpec:
1395 case NestedNameSpecifier::TypeSpecWithTemplate:
1396 if (Visit(Q.getTypeLoc()))
1397 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001398
Guy Benyei11169dd2012-12-18 14:30:41 +00001399 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001400
Guy Benyei11169dd2012-12-18 14:30:41 +00001401 case NestedNameSpecifier::Global:
1402 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001403 case NestedNameSpecifier::Super:
Michael Kruse7520cf02020-03-25 09:26:14 -05001404 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001405 }
1406 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001407
Guy Benyei11169dd2012-12-18 14:30:41 +00001408 return false;
1409}
1410
1411bool CursorVisitor::VisitTemplateParameters(
Michael Kruse7520cf02020-03-25 09:26:14 -05001412 const TemplateParameterList *Params) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001413 if (!Params)
1414 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001415
Guy Benyei11169dd2012-12-18 14:30:41 +00001416 for (TemplateParameterList::const_iterator P = Params->begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001417 PEnd = Params->end();
Guy Benyei11169dd2012-12-18 14:30:41 +00001418 P != PEnd; ++P) {
1419 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1420 return true;
1421 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001422
Guy Benyei11169dd2012-12-18 14:30:41 +00001423 return false;
1424}
1425
1426bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1427 switch (Name.getKind()) {
1428 case TemplateName::Template:
1429 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1430
1431 case TemplateName::OverloadedTemplate:
1432 // Visit the overloaded template set.
1433 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1434 return true;
1435
1436 return false;
1437
Richard Smithb23c5e82019-05-09 03:31:27 +00001438 case TemplateName::AssumedTemplate:
1439 // FIXME: Visit DeclarationName?
1440 return false;
1441
Guy Benyei11169dd2012-12-18 14:30:41 +00001442 case TemplateName::DependentTemplate:
1443 // FIXME: Visit nested-name-specifier.
1444 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001445
Guy Benyei11169dd2012-12-18 14:30:41 +00001446 case TemplateName::QualifiedTemplate:
1447 // FIXME: Visit nested-name-specifier.
1448 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001449 Name.getAsQualifiedTemplateName()->getDecl(), Loc, TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001450
1451 case TemplateName::SubstTemplateTemplateParm:
1452 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001453 Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));
1454
Guy Benyei11169dd2012-12-18 14:30:41 +00001455 case TemplateName::SubstTemplateTemplateParmPack:
1456 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001457 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
1458 TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001459 }
1460
1461 llvm_unreachable("Invalid TemplateName::Kind!");
1462}
1463
1464bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1465 switch (TAL.getArgument().getKind()) {
1466 case TemplateArgument::Null:
1467 case TemplateArgument::Integral:
1468 case TemplateArgument::Pack:
1469 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001470
Guy Benyei11169dd2012-12-18 14:30:41 +00001471 case TemplateArgument::Type:
1472 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1473 return Visit(TSInfo->getTypeLoc());
1474 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001475
Guy Benyei11169dd2012-12-18 14:30:41 +00001476 case TemplateArgument::Declaration:
1477 if (Expr *E = TAL.getSourceDeclExpression())
1478 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1479 return false;
1480
1481 case TemplateArgument::NullPtr:
1482 if (Expr *E = TAL.getSourceNullPtrExpression())
1483 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1484 return false;
1485
1486 case TemplateArgument::Expression:
1487 if (Expr *E = TAL.getSourceExpression())
1488 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1489 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001490
Guy Benyei11169dd2012-12-18 14:30:41 +00001491 case TemplateArgument::Template:
1492 case TemplateArgument::TemplateExpansion:
1493 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1494 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001495
1496 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001497 TAL.getTemplateNameLoc());
1498 }
1499
1500 llvm_unreachable("Invalid TemplateArgument::Kind!");
1501}
1502
1503bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1504 return VisitDeclContext(D);
1505}
1506
1507bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1508 return Visit(TL.getUnqualifiedLoc());
1509}
1510
1511bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1512 ASTContext &Context = AU->getASTContext();
1513
1514 // Some builtin types (such as Objective-C's "id", "sel", and
1515 // "Class") have associated declarations. Create cursors for those.
1516 QualType VisitType;
1517 switch (TL.getTypePtr()->getKind()) {
1518
1519 case BuiltinType::Void:
1520 case BuiltinType::NullPtr:
1521 case BuiltinType::Dependent:
Michael Kruse7520cf02020-03-25 09:26:14 -05001522#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
Alexey Bader954ba212016-04-08 13:40:33 +00001523 case BuiltinType::Id:
Alexey Baderb62f1442016-04-13 08:33:41 +00001524#include "clang/Basic/OpenCLImageTypes.def"
Michael Kruse7520cf02020-03-25 09:26:14 -05001525#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
Andrew Savonichev3fee3512018-11-08 11:25:41 +00001526#include "clang/Basic/OpenCLExtensionTypes.def"
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001527 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001528 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001529 case BuiltinType::OCLClkEvent:
1530 case BuiltinType::OCLQueue:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001531 case BuiltinType::OCLReserveID:
Michael Kruse7520cf02020-03-25 09:26:14 -05001532#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
Richard Sandifordeb485fb2019-08-09 08:52:54 +00001533#include "clang/Basic/AArch64SVEACLETypes.def"
Guy Benyei11169dd2012-12-18 14:30:41 +00001534#define BUILTIN_TYPE(Id, SingletonId)
1535#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1536#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1537#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1538#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1539#include "clang/AST/BuiltinTypes.def"
1540 break;
1541
1542 case BuiltinType::ObjCId:
1543 VisitType = Context.getObjCIdType();
1544 break;
1545
1546 case BuiltinType::ObjCClass:
1547 VisitType = Context.getObjCClassType();
1548 break;
1549
1550 case BuiltinType::ObjCSel:
1551 VisitType = Context.getObjCSelType();
1552 break;
1553 }
1554
1555 if (!VisitType.isNull()) {
1556 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Michael Kruse7520cf02020-03-25 09:26:14 -05001557 return Visit(
1558 MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001559 }
1560
1561 return false;
1562}
1563
1564bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1565 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1566}
1567
1568bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1569 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1570}
1571
1572bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1573 if (TL.isDefinition())
1574 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1575
1576 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1577}
1578
1579bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1580 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1581}
1582
1583bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001584 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001585}
1586
Manman Rene6be26c2016-09-13 17:25:08 +00001587bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001588 if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
Manman Rene6be26c2016-09-13 17:25:08 +00001589 return true;
1590 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1591 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1592 TU)))
1593 return true;
1594 }
1595
1596 return false;
1597}
1598
Guy Benyei11169dd2012-12-18 14:30:41 +00001599bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1600 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1601 return true;
1602
Douglas Gregore9d95f12015-07-07 03:57:35 +00001603 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1604 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1605 return true;
1606 }
1607
Guy Benyei11169dd2012-12-18 14:30:41 +00001608 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1609 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1610 TU)))
1611 return true;
1612 }
1613
1614 return false;
1615}
1616
1617bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1618 return Visit(TL.getPointeeLoc());
1619}
1620
1621bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1622 return Visit(TL.getInnerLoc());
1623}
1624
Leonard Chanc72aaf62019-05-07 03:20:17 +00001625bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
1626 return Visit(TL.getInnerLoc());
1627}
1628
Guy Benyei11169dd2012-12-18 14:30:41 +00001629bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1630 return Visit(TL.getPointeeLoc());
1631}
1632
1633bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1634 return Visit(TL.getPointeeLoc());
1635}
1636
1637bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1638 return Visit(TL.getPointeeLoc());
1639}
1640
1641bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1642 return Visit(TL.getPointeeLoc());
1643}
1644
1645bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1646 return Visit(TL.getPointeeLoc());
1647}
1648
1649bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1650 return Visit(TL.getModifiedLoc());
1651}
1652
Michael Kruse7520cf02020-03-25 09:26:14 -05001653bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
Guy Benyei11169dd2012-12-18 14:30:41 +00001654 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001655 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001656 return true;
1657
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001658 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1659 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001660 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1661 return true;
1662
1663 return false;
1664}
1665
1666bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1667 if (Visit(TL.getElementLoc()))
1668 return true;
1669
1670 if (Expr *Size = TL.getSizeExpr())
1671 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1672
1673 return false;
1674}
1675
Reid Kleckner8a365022013-06-24 17:51:48 +00001676bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1677 return Visit(TL.getOriginalLoc());
1678}
1679
Reid Kleckner0503a872013-12-05 01:23:43 +00001680bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1681 return Visit(TL.getOriginalLoc());
1682}
1683
Richard Smith600b5262017-01-26 20:40:47 +00001684bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
1685 DeducedTemplateSpecializationTypeLoc TL) {
Michael Kruse7520cf02020-03-25 09:26:14 -05001686 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Richard Smith600b5262017-01-26 20:40:47 +00001687 TL.getTemplateNameLoc()))
1688 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001689
Richard Smith600b5262017-01-26 20:40:47 +00001690 return false;
1691}
1692
Guy Benyei11169dd2012-12-18 14:30:41 +00001693bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001694 TemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001695 // Visit the template name.
Michael Kruse7520cf02020-03-25 09:26:14 -05001696 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001697 TL.getTemplateNameLoc()))
1698 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001699
Guy Benyei11169dd2012-12-18 14:30:41 +00001700 // Visit the template arguments.
1701 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1702 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1703 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001704
Guy Benyei11169dd2012-12-18 14:30:41 +00001705 return false;
1706}
1707
1708bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1709 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1710}
1711
1712bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1713 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1714 return Visit(TSInfo->getTypeLoc());
1715
1716 return false;
1717}
1718
1719bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1720 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1721 return Visit(TSInfo->getTypeLoc());
1722
1723 return false;
1724}
1725
1726bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001727 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001728}
1729
1730bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001731 DependentTemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001732 // Visit the nested-name-specifier, if there is one.
Michael Kruse7520cf02020-03-25 09:26:14 -05001733 if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001734 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001735
Guy Benyei11169dd2012-12-18 14:30:41 +00001736 // Visit the template arguments.
1737 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1738 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1739 return true;
1740
1741 return false;
1742}
1743
1744bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1745 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1746 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001747
Guy Benyei11169dd2012-12-18 14:30:41 +00001748 return Visit(TL.getNamedTypeLoc());
1749}
1750
1751bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1752 return Visit(TL.getPatternLoc());
1753}
1754
1755bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1756 if (Expr *E = TL.getUnderlyingExpr())
1757 return Visit(MakeCXCursor(E, StmtParent, TU));
1758
1759 return false;
1760}
1761
1762bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1763 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1764}
1765
1766bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1767 return Visit(TL.getValueLoc());
1768}
1769
Xiuli Pan9c14e282016-01-09 12:53:17 +00001770bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1771 return Visit(TL.getValueLoc());
1772}
1773
Michael Kruse7520cf02020-03-25 09:26:14 -05001774#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1775 bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1776 return Visit##PARENT##Loc(TL); \
1777 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001778
1779DEFAULT_TYPELOC_IMPL(Complex, Type)
1780DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1781DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1782DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1783DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
Andrew Gozillon572bbb02017-10-02 06:25:51 +00001784DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
Erich Keanef702b022018-07-13 19:46:04 +00001785DEFAULT_TYPELOC_IMPL(DependentVector, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001786DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1787DEFAULT_TYPELOC_IMPL(Vector, Type)
1788DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1789DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1790DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1791DEFAULT_TYPELOC_IMPL(Record, TagType)
1792DEFAULT_TYPELOC_IMPL(Enum, TagType)
1793DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1794DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1795DEFAULT_TYPELOC_IMPL(Auto, Type)
1796
1797bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1798 // Visit the nested-name-specifier, if present.
1799 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1800 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1801 return true;
1802
1803 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001804 for (const auto &I : D->bases()) {
1805 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001806 return true;
1807 }
1808 }
1809
1810 return VisitTagDecl(D);
1811}
1812
1813bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001814 for (const auto *I : D->attrs())
Michael Wu40ff1052018-08-03 05:20:23 +00001815 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1816 !I->isImplicit()) &&
1817 Visit(MakeCXCursor(I, D, TU)))
Michael Kruse7520cf02020-03-25 09:26:14 -05001818 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00001819
1820 return false;
1821}
1822
1823//===----------------------------------------------------------------------===//
1824// Data-recursive visitor methods.
1825//===----------------------------------------------------------------------===//
1826
1827namespace {
Michael Kruse7520cf02020-03-25 09:26:14 -05001828#define DEF_JOB(NAME, DATA, KIND) \
1829 class NAME : public VisitorJob { \
1830 public: \
1831 NAME(const DATA *d, CXCursor parent) \
1832 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1833 static bool classof(const VisitorJob *VJ) { \
1834 return VJ->getKind() == KIND; \
1835 } \
1836 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1837 };
Guy Benyei11169dd2012-12-18 14:30:41 +00001838
1839DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1840DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1841DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1842DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001843DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1844DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1845DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1846#undef DEF_JOB
1847
James Y Knight04ec5bf2015-12-24 02:59:37 +00001848class ExplicitTemplateArgsVisit : public VisitorJob {
1849public:
1850 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1851 const TemplateArgumentLoc *End, CXCursor parent)
1852 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1853 End) {}
1854 static bool classof(const VisitorJob *VJ) {
1855 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1856 }
1857 const TemplateArgumentLoc *begin() const {
1858 return static_cast<const TemplateArgumentLoc *>(data[0]);
1859 }
1860 const TemplateArgumentLoc *end() {
1861 return static_cast<const TemplateArgumentLoc *>(data[1]);
1862 }
1863};
Guy Benyei11169dd2012-12-18 14:30:41 +00001864class DeclVisit : public VisitorJob {
1865public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001866 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1867 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1868 isFirst ? (void *)1 : (void *)nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001869 static bool classof(const VisitorJob *VJ) {
1870 return VJ->getKind() == DeclVisitKind;
1871 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001873 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001874};
1875class TypeLocVisit : public VisitorJob {
1876public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001877 TypeLocVisit(TypeLoc tl, CXCursor parent)
1878 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1879 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001880
1881 static bool classof(const VisitorJob *VJ) {
1882 return VJ->getKind() == TypeLocVisitKind;
1883 }
1884
Michael Kruse7520cf02020-03-25 09:26:14 -05001885 TypeLoc get() const {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001888 }
1889};
1890
1891class LabelRefVisit : public VisitorJob {
1892public:
1893 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001894 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1895 labelLoc.getPtrEncoding()) {}
1896
Guy Benyei11169dd2012-12-18 14:30:41 +00001897 static bool classof(const VisitorJob *VJ) {
1898 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1899 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 const LabelDecl *get() const {
1901 return static_cast<const LabelDecl *>(data[0]);
1902 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001903 SourceLocation getLoc() const {
1904 return SourceLocation::getFromPtrEncoding(data[1]);
1905 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001906};
Michael Kruse7520cf02020-03-25 09:26:14 -05001907
Guy Benyei11169dd2012-12-18 14:30:41 +00001908class NestedNameSpecifierLocVisit : public VisitorJob {
1909public:
1910 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001911 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1912 Qualifier.getNestedNameSpecifier(),
1913 Qualifier.getOpaqueData()) {}
1914
Guy Benyei11169dd2012-12-18 14:30:41 +00001915 static bool classof(const VisitorJob *VJ) {
1916 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1917 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001918
Guy Benyei11169dd2012-12-18 14:30:41 +00001919 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001920 return NestedNameSpecifierLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001921 const_cast<NestedNameSpecifier *>(
1922 static_cast<const NestedNameSpecifier *>(data[0])),
1923 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001924 }
1925};
Michael Kruse7520cf02020-03-25 09:26:14 -05001926
Guy Benyei11169dd2012-12-18 14:30:41 +00001927class DeclarationNameInfoVisit : public VisitorJob {
1928public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001929 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001930 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001931 static bool classof(const VisitorJob *VJ) {
1932 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1933 }
1934 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001935 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001936 switch (S->getStmtClass()) {
1937 default:
1938 llvm_unreachable("Unhandled Stmt");
1939 case clang::Stmt::MSDependentExistsStmtClass:
1940 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1941 case Stmt::CXXDependentScopeMemberExprClass:
1942 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1943 case Stmt::DependentScopeDeclRefExprClass:
1944 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001945 case Stmt::OMPCriticalDirectiveClass:
1946 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001947 }
1948 }
1949};
1950class MemberRefVisit : public VisitorJob {
1951public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001952 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001953 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1954 L.getPtrEncoding()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001955 static bool classof(const VisitorJob *VJ) {
1956 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1957 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001958 const FieldDecl *get() const {
1959 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001960 }
1961 SourceLocation getLoc() const {
Michael Kruse7520cf02020-03-25 09:26:14 -05001962 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001963 }
1964};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001966 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001967 VisitorWorkList &WL;
1968 CXCursor Parent;
Michael Kruse7520cf02020-03-25 09:26:14 -05001969
Guy Benyei11169dd2012-12-18 14:30:41 +00001970public:
1971 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001972 : WL(wl), Parent(parent) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001973
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1975 void VisitBlockExpr(const BlockExpr *B);
1976 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1977 void VisitCompoundStmt(const CompoundStmt *S);
Michael Kruse7520cf02020-03-25 09:26:14 -05001978 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
1979 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001980 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1981 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1982 void VisitCXXNewExpr(const CXXNewExpr *E);
1983 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1984 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1985 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1986 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1987 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1988 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1989 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1990 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001991 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001992 void VisitDeclRefExpr(const DeclRefExpr *D);
1993 void VisitDeclStmt(const DeclStmt *S);
1994 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1995 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1996 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1997 void VisitForStmt(const ForStmt *FS);
1998 void VisitGotoStmt(const GotoStmt *GS);
1999 void VisitIfStmt(const IfStmt *If);
2000 void VisitInitListExpr(const InitListExpr *IE);
2001 void VisitMemberExpr(const MemberExpr *M);
2002 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2003 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2004 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2005 void VisitOverloadExpr(const OverloadExpr *E);
2006 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2007 void VisitStmt(const Stmt *S);
2008 void VisitSwitchStmt(const SwitchStmt *S);
2009 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2011 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2012 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2013 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2014 void VisitVAArgExpr(const VAArgExpr *E);
2015 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2016 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2017 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2018 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002019 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00002020 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002021 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002022 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002023 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00002024 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002025 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002026 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002027 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00002028 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002029 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002030 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002031 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
cchen47d60942019-12-05 13:43:48 -05002032 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002033 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002034 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00002035 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002036 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00002037 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002038 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002039 void
2040 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00002041 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00002042 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataevc112e942020-02-28 09:52:15 -05002043 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002044 void VisitOMPScanDirective(const OMPScanDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002045 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00002046 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002047 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00002048 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00002049 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00002050 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002051 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002052 void
2053 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00002054 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00002055 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002056 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Alexey Bataev60e51c42019-10-10 20:13:02 +00002057 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002058 void
2059 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002060 void VisitOMPParallelMasterTaskLoopDirective(
2061 const OMPParallelMasterTaskLoopDirective *D);
Alexey Bataev14a388f2019-10-25 10:27:13 -04002062 void VisitOMPParallelMasterTaskLoopSimdDirective(
2063 const OMPParallelMasterTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002064 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002065 void VisitOMPDistributeParallelForDirective(
2066 const OMPDistributeParallelForDirective *D);
Kelvin Li4a39add2016-07-05 05:00:15 +00002067 void VisitOMPDistributeParallelForSimdDirective(
2068 const OMPDistributeParallelForSimdDirective *D);
Kelvin Li787f3fc2016-07-06 04:45:38 +00002069 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
Kelvin Lia579b912016-07-14 02:54:56 +00002070 void VisitOMPTargetParallelForSimdDirective(
2071 const OMPTargetParallelForSimdDirective *D);
Kelvin Li986330c2016-07-20 22:57:10 +00002072 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
Kelvin Li02532872016-08-05 14:37:37 +00002073 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
Kelvin Li4e325f72016-10-25 12:50:55 +00002074 void VisitOMPTeamsDistributeSimdDirective(
2075 const OMPTeamsDistributeSimdDirective *D);
Kelvin Li579e41c2016-11-30 23:51:03 +00002076 void VisitOMPTeamsDistributeParallelForSimdDirective(
2077 const OMPTeamsDistributeParallelForSimdDirective *D);
Kelvin Li7ade93f2016-12-09 03:24:30 +00002078 void VisitOMPTeamsDistributeParallelForDirective(
2079 const OMPTeamsDistributeParallelForDirective *D);
Kelvin Libf594a52016-12-17 05:48:59 +00002080 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
Kelvin Li83c451e2016-12-25 04:52:54 +00002081 void VisitOMPTargetTeamsDistributeDirective(
2082 const OMPTargetTeamsDistributeDirective *D);
Kelvin Li80e8f562016-12-29 22:16:30 +00002083 void VisitOMPTargetTeamsDistributeParallelForDirective(
2084 const OMPTargetTeamsDistributeParallelForDirective *D);
Kelvin Li1851df52017-01-03 05:23:48 +00002085 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2086 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
Kelvin Lida681182017-01-10 18:08:18 +00002087 void VisitOMPTargetTeamsDistributeSimdDirective(
2088 const OMPTargetTeamsDistributeSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002089
Guy Benyei11169dd2012-12-18 14:30:41 +00002090private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002091 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002092 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00002093 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2094 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2096 void AddStmt(const Stmt *S);
2097 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002100 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002101};
Michael Kruse7520cf02020-03-25 09:26:14 -05002102} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00002103
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 // 'S' should always be non-null, since it comes from the
2106 // statement we are visiting.
2107 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2108}
2109
Michael Kruse7520cf02020-03-25 09:26:14 -05002110void EnqueueVisitor::AddNestedNameSpecifierLoc(
2111 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 if (Qualifier)
2113 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2114}
2115
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 if (S)
2118 WL.push_back(StmtVisit(S, Parent));
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 if (D)
2122 WL.push_back(DeclVisit(D, Parent, isFirst));
2123}
James Y Knight04ec5bf2015-12-24 02:59:37 +00002124void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2125 unsigned NumTemplateArgs) {
2126 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002127}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002128void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 if (D)
2130 WL.push_back(MemberRefVisit(D, L, Parent));
2131}
2132void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2133 if (TI)
2134 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002138 for (const Stmt *SubStmt : S->children()) {
2139 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 }
2141 if (size == WL.size())
2142 return;
2143 // Now reverse the entries we just added. This will match the DFS
2144 // ordering performed by the worklist.
2145 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2146 std::reverse(I, E);
2147}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002148namespace {
2149class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2150 EnqueueVisitor *Visitor;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002151 /// Process clauses with list of variables.
Michael Kruse7520cf02020-03-25 09:26:14 -05002152 template <typename T> void VisitOMPClauseList(T *Node);
2153
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002154public:
Michael Kruse7520cf02020-03-25 09:26:14 -05002155 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
2156#define OPENMP_CLAUSE(Name, Class) void Visit##Class(const Class *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002157#include "clang/Basic/OpenMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002158 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002159 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002160};
2161
Alexey Bataev3392d762016-02-16 11:18:12 +00002162void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2163 const OMPClauseWithPreInit *C) {
2164 Visitor->AddStmt(C->getPreInitStmt());
2165}
2166
Alexey Bataev005248a2016-02-25 05:25:57 +00002167void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2168 const OMPClauseWithPostUpdate *C) {
Alexey Bataev37e594c2016-03-04 07:21:16 +00002169 VisitOMPClauseWithPreInit(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002170 Visitor->AddStmt(C->getPostUpdateExpr());
2171}
2172
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002173void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00002174 VisitOMPClauseWithPreInit(C);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002175 Visitor->AddStmt(C->getCondition());
2176}
2177
Alexey Bataev3778b602014-07-17 07:32:53 +00002178void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2179 Visitor->AddStmt(C->getCondition());
2180}
2181
Alexey Bataev568a8332014-03-06 06:15:19 +00002182void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00002183 VisitOMPClauseWithPreInit(C);
Alexey Bataev568a8332014-03-06 06:15:19 +00002184 Visitor->AddStmt(C->getNumThreads());
2185}
2186
Alexey Bataev62c87d22014-03-21 04:51:18 +00002187void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2188 Visitor->AddStmt(C->getSafelen());
2189}
2190
Alexey Bataev66b15b52015-08-21 11:14:16 +00002191void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2192 Visitor->AddStmt(C->getSimdlen());
2193}
2194
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002195void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2196 Visitor->AddStmt(C->getAllocator());
2197}
2198
Alexander Musman8bd31e62014-05-27 15:12:19 +00002199void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2200 Visitor->AddStmt(C->getNumForLoops());
2201}
2202
Michael Kruse7520cf02020-03-25 09:26:14 -05002203void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
Alexey Bataev756c1962013-09-24 03:17:45 +00002204
Michael Kruse7520cf02020-03-25 09:26:14 -05002205void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002206
Alexey Bataev56dafe82014-06-20 07:16:17 +00002207void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002208 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002209 Visitor->AddStmt(C->getChunkSize());
2210}
2211
Alexey Bataev10e775f2015-07-30 11:36:16 +00002212void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2213 Visitor->AddStmt(C->getNumForLoops());
2214}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002215
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002216void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2217 Visitor->AddStmt(C->getEventHandler());
2218}
2219
Alexey Bataev236070f2014-06-20 11:19:47 +00002220void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2221
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002222void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2223
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002224void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2225
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002226void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2227
Alexey Bataevdea47612014-07-23 07:46:59 +00002228void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2229
Alexey Bataev67a4f222014-07-23 10:25:33 +00002230void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2231
Alexey Bataev459dec02014-07-24 06:46:57 +00002232void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2233
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002234void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2235
Alexey Bataevea9166b2020-02-06 16:30:23 -05002236void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2237
Alexey Bataev04a830f2020-02-10 14:30:39 -05002238void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2239
Alexey Bataev95598342020-02-10 15:49:05 -05002240void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2241
Alexey Bataev9a8defc2020-02-11 11:10:43 -05002242void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2243
Alexey Bataev346265e2015-09-25 10:37:12 +00002244void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2245
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002246void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2247
Alexey Bataevb825de12015-12-07 10:51:44 +00002248void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2249
Alexey Bataev375437a2020-03-02 14:21:20 -05002250void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {}
2251
Kelvin Li1408f912018-09-26 04:28:39 +00002252void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2253 const OMPUnifiedAddressClause *) {}
2254
Patrick Lyster4a370b92018-10-01 13:47:43 +00002255void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2256 const OMPUnifiedSharedMemoryClause *) {}
2257
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00002258void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2259 const OMPReverseOffloadClause *) {}
2260
Patrick Lyster3fe9e392018-10-11 14:41:10 +00002261void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2262 const OMPDynamicAllocatorsClause *) {}
2263
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002264void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2265 const OMPAtomicDefaultMemOrderClause *) {}
2266
Michael Wonge710d542015-08-07 16:16:36 +00002267void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2268 Visitor->AddStmt(C->getDevice());
2269}
2270
Kelvin Li099bb8c2015-11-24 20:50:12 +00002271void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00002272 VisitOMPClauseWithPreInit(C);
Kelvin Li099bb8c2015-11-24 20:50:12 +00002273 Visitor->AddStmt(C->getNumTeams());
2274}
2275
Michael Kruse7520cf02020-03-25 09:26:14 -05002276void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2277 const OMPThreadLimitClause *C) {
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00002278 VisitOMPClauseWithPreInit(C);
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002279 Visitor->AddStmt(C->getThreadLimit());
2280}
2281
Alexey Bataeva0569352015-12-01 10:17:31 +00002282void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2283 Visitor->AddStmt(C->getPriority());
2284}
2285
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002286void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2287 Visitor->AddStmt(C->getGrainsize());
2288}
2289
Alexey Bataev382967a2015-12-08 12:06:20 +00002290void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2291 Visitor->AddStmt(C->getNumTasks());
2292}
2293
Alexey Bataev28c75412015-12-15 08:19:24 +00002294void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2295 Visitor->AddStmt(C->getHint());
2296}
2297
Michael Kruse7520cf02020-03-25 09:26:14 -05002298template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002299 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002300 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002301 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002302}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002303
Alexey Bataev06dea732020-03-20 09:41:22 -04002304void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2305 VisitOMPClauseList(C);
2306}
Alexey Bataev63828a32020-03-23 10:41:08 -04002307void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2308 VisitOMPClauseList(C);
2309}
Alexey Bataeve04483e2019-03-27 14:14:31 +00002310void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2311 VisitOMPClauseList(C);
2312 Visitor->AddStmt(C->getAllocator());
2313}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002314void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002315 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002316 for (const auto *E : C->private_copies()) {
2317 Visitor->AddStmt(E);
2318 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002319}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002320void OMPClauseEnqueue::VisitOMPFirstprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002321 const OMPFirstprivateClause *C) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002322 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002323 VisitOMPClauseWithPreInit(C);
2324 for (const auto *E : C->private_copies()) {
2325 Visitor->AddStmt(E);
2326 }
2327 for (const auto *E : C->inits()) {
2328 Visitor->AddStmt(E);
2329 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002330}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002331void OMPClauseEnqueue::VisitOMPLastprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002332 const OMPLastprivateClause *C) {
Alexander Musman1bb328c2014-06-04 13:06:39 +00002333 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002334 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002335 for (auto *E : C->private_copies()) {
2336 Visitor->AddStmt(E);
2337 }
2338 for (auto *E : C->source_exprs()) {
2339 Visitor->AddStmt(E);
2340 }
2341 for (auto *E : C->destination_exprs()) {
2342 Visitor->AddStmt(E);
2343 }
2344 for (auto *E : C->assignment_ops()) {
2345 Visitor->AddStmt(E);
2346 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002347}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002348void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002349 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002350}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002351void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2352 VisitOMPClauseList(C);
Alexey Bataev61205072016-03-02 04:57:40 +00002353 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002354 for (auto *E : C->privates()) {
2355 Visitor->AddStmt(E);
2356 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002357 for (auto *E : C->lhs_exprs()) {
2358 Visitor->AddStmt(E);
2359 }
2360 for (auto *E : C->rhs_exprs()) {
2361 Visitor->AddStmt(E);
2362 }
2363 for (auto *E : C->reduction_ops()) {
2364 Visitor->AddStmt(E);
2365 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002366}
Alexey Bataev169d96a2017-07-18 20:17:46 +00002367void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2368 const OMPTaskReductionClause *C) {
2369 VisitOMPClauseList(C);
2370 VisitOMPClauseWithPostUpdate(C);
2371 for (auto *E : C->privates()) {
2372 Visitor->AddStmt(E);
2373 }
2374 for (auto *E : C->lhs_exprs()) {
2375 Visitor->AddStmt(E);
2376 }
2377 for (auto *E : C->rhs_exprs()) {
2378 Visitor->AddStmt(E);
2379 }
2380 for (auto *E : C->reduction_ops()) {
2381 Visitor->AddStmt(E);
2382 }
2383}
Alexey Bataevfa312f32017-07-21 18:48:21 +00002384void OMPClauseEnqueue::VisitOMPInReductionClause(
2385 const OMPInReductionClause *C) {
2386 VisitOMPClauseList(C);
2387 VisitOMPClauseWithPostUpdate(C);
2388 for (auto *E : C->privates()) {
2389 Visitor->AddStmt(E);
2390 }
2391 for (auto *E : C->lhs_exprs()) {
2392 Visitor->AddStmt(E);
2393 }
2394 for (auto *E : C->rhs_exprs()) {
2395 Visitor->AddStmt(E);
2396 }
2397 for (auto *E : C->reduction_ops()) {
2398 Visitor->AddStmt(E);
2399 }
Alexey Bataev88202be2017-07-27 13:20:36 +00002400 for (auto *E : C->taskgroup_descriptors())
2401 Visitor->AddStmt(E);
Alexey Bataevfa312f32017-07-21 18:48:21 +00002402}
Alexander Musman8dba6642014-04-22 13:09:42 +00002403void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2404 VisitOMPClauseList(C);
Alexey Bataev78849fb2016-03-09 09:49:00 +00002405 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002406 for (const auto *E : C->privates()) {
2407 Visitor->AddStmt(E);
2408 }
Alexander Musman3276a272015-03-21 10:12:56 +00002409 for (const auto *E : C->inits()) {
2410 Visitor->AddStmt(E);
2411 }
2412 for (const auto *E : C->updates()) {
2413 Visitor->AddStmt(E);
2414 }
2415 for (const auto *E : C->finals()) {
2416 Visitor->AddStmt(E);
2417 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002418 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002419 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002420}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002421void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2422 VisitOMPClauseList(C);
2423 Visitor->AddStmt(C->getAlignment());
2424}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002425void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2426 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002427 for (auto *E : C->source_exprs()) {
2428 Visitor->AddStmt(E);
2429 }
2430 for (auto *E : C->destination_exprs()) {
2431 Visitor->AddStmt(E);
2432 }
2433 for (auto *E : C->assignment_ops()) {
2434 Visitor->AddStmt(E);
2435 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002436}
Michael Kruse7520cf02020-03-25 09:26:14 -05002437void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2438 const OMPCopyprivateClause *C) {
Alexey Bataevbae9a792014-06-27 10:37:06 +00002439 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002440 for (auto *E : C->source_exprs()) {
2441 Visitor->AddStmt(E);
2442 }
2443 for (auto *E : C->destination_exprs()) {
2444 Visitor->AddStmt(E);
2445 }
2446 for (auto *E : C->assignment_ops()) {
2447 Visitor->AddStmt(E);
2448 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002449}
Alexey Bataev6125da92014-07-21 11:26:11 +00002450void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2451 VisitOMPClauseList(C);
2452}
Alexey Bataevc112e942020-02-28 09:52:15 -05002453void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2454 Visitor->AddStmt(C->getDepobj());
2455}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002456void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2457 VisitOMPClauseList(C);
2458}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002459void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2460 VisitOMPClauseList(C);
2461}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002462void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2463 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002464 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002465 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002466}
Alexey Bataev3392d762016-02-16 11:18:12 +00002467void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2468 const OMPDefaultmapClause * /*C*/) {}
Samuel Antao661c0902016-05-26 17:39:58 +00002469void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2470 VisitOMPClauseList(C);
2471}
Samuel Antaoec172c62016-05-26 17:49:04 +00002472void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2473 VisitOMPClauseList(C);
2474}
Michael Kruse7520cf02020-03-25 09:26:14 -05002475void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2476 const OMPUseDevicePtrClause *C) {
Carlo Bertolli2404b172016-07-13 15:37:16 +00002477 VisitOMPClauseList(C);
2478}
Michael Kruse7520cf02020-03-25 09:26:14 -05002479void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2480 const OMPIsDevicePtrClause *C) {
Carlo Bertolli70594e92016-07-13 17:16:49 +00002481 VisitOMPClauseList(C);
2482}
Alexey Bataevb6e70842019-12-16 15:54:17 -05002483void OMPClauseEnqueue::VisitOMPNontemporalClause(
2484 const OMPNontemporalClause *C) {
2485 VisitOMPClauseList(C);
Alexey Bataev0860db92019-12-19 10:01:10 -05002486 for (const auto *E : C->private_refs())
2487 Visitor->AddStmt(E);
Alexey Bataevb6e70842019-12-16 15:54:17 -05002488}
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002489void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
Michael Kruse7520cf02020-03-25 09:26:14 -05002490} // namespace
Alexey Bataev756c1962013-09-24 03:17:45 +00002491
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002492void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2493 unsigned size = WL.size();
2494 OMPClauseEnqueue Visitor(this);
2495 Visitor.Visit(S);
2496 if (size == WL.size())
2497 return;
2498 // Now reverse the entries we just added. This will match the DFS
2499 // ordering performed by the worklist.
2500 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2501 std::reverse(I, E);
2502}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002503void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002504 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2505}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002506void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002507 AddDecl(B->getBlockDecl());
2508}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002509void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002510 EnqueueChildren(E);
2511 AddTypeLoc(E->getTypeSourceInfo());
2512}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002513void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002514 for (auto &I : llvm::reverse(S->body()))
2515 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002516}
Michael Kruse7520cf02020-03-25 09:26:14 -05002517void EnqueueVisitor::VisitMSDependentExistsStmt(
2518 const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002519 AddStmt(S->getSubStmt());
2520 AddDeclarationNameInfo(S);
2521 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2522 AddNestedNameSpecifierLoc(QualifierLoc);
2523}
2524
Michael Kruse7520cf02020-03-25 09:26:14 -05002525void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2526 const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002527 if (E->hasExplicitTemplateArgs())
2528 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002529 AddDeclarationNameInfo(E);
2530 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2531 AddNestedNameSpecifierLoc(QualifierLoc);
2532 if (!E->isImplicitAccess())
2533 AddStmt(E->getBase());
2534}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002535void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002536 // Enqueue the initializer , if any.
2537 AddStmt(E->getInitializer());
2538 // Enqueue the array size, if any.
Richard Smithb9fb1212019-05-06 03:47:15 +00002539 AddStmt(E->getArraySize().getValueOr(nullptr));
Guy Benyei11169dd2012-12-18 14:30:41 +00002540 // Enqueue the allocated type.
2541 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2542 // Enqueue the placement arguments.
2543 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002544 AddStmt(E->getPlacementArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002545}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002546void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002547 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002548 AddStmt(CE->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002549 AddStmt(CE->getCallee());
2550 AddStmt(CE->getArg(0));
2551}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002552void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002553 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002554 // Visit the name of the type being destroyed.
2555 AddTypeLoc(E->getDestroyedTypeInfo());
2556 // Visit the scope type that looks disturbingly like the nested-name-specifier
2557 // but isn't.
2558 AddTypeLoc(E->getScopeTypeInfo());
2559 // Visit the nested-name-specifier.
2560 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2561 AddNestedNameSpecifierLoc(QualifierLoc);
2562 // Visit base expression.
2563 AddStmt(E->getBase());
2564}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002565void EnqueueVisitor::VisitCXXScalarValueInitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002566 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002567 AddTypeLoc(E->getTypeSourceInfo());
2568}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002569void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002570 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002571 EnqueueChildren(E);
2572 AddTypeLoc(E->getTypeSourceInfo());
2573}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002574void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002575 EnqueueChildren(E);
2576 if (E->isTypeOperand())
2577 AddTypeLoc(E->getTypeOperandSourceInfo());
2578}
2579
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002580void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002581 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002582 EnqueueChildren(E);
2583 AddTypeLoc(E->getTypeSourceInfo());
2584}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002585void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002586 EnqueueChildren(E);
2587 if (E->isTypeOperand())
2588 AddTypeLoc(E->getTypeOperandSourceInfo());
2589}
2590
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002591void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002592 EnqueueChildren(S);
2593 AddDecl(S->getExceptionDecl());
2594}
2595
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002596void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002597 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002598 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002599 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002600}
2601
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002602void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002603 if (DR->hasExplicitTemplateArgs())
2604 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002605 WL.push_back(DeclRefExprParts(DR, Parent));
2606}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002607void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002608 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002609 if (E->hasExplicitTemplateArgs())
2610 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002611 AddDeclarationNameInfo(E);
2612 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2613}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002614void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002615 unsigned size = WL.size();
2616 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002617 for (const auto *D : S->decls()) {
2618 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002619 isFirst = false;
2620 }
2621 if (size == WL.size())
2622 return;
2623 // Now reverse the entries we just added. This will match the DFS
2624 // ordering performed by the worklist.
2625 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2626 std::reverse(I, E);
2627}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002628void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002629 AddStmt(E->getInit());
David Majnemerf7e36092016-06-23 00:15:04 +00002630 for (const DesignatedInitExpr::Designator &D :
2631 llvm::reverse(E->designators())) {
2632 if (D.isFieldDesignator()) {
2633 if (FieldDecl *Field = D.getField())
2634 AddMemberRef(Field, D.getFieldLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00002635 continue;
2636 }
David Majnemerf7e36092016-06-23 00:15:04 +00002637 if (D.isArrayDesignator()) {
2638 AddStmt(E->getArrayIndex(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002639 continue;
2640 }
David Majnemerf7e36092016-06-23 00:15:04 +00002641 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2642 AddStmt(E->getArrayRangeEnd(D));
2643 AddStmt(E->getArrayRangeStart(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002644 }
2645}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002646void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002647 EnqueueChildren(E);
2648 AddTypeLoc(E->getTypeInfoAsWritten());
2649}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002650void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002651 AddStmt(FS->getBody());
2652 AddStmt(FS->getInc());
2653 AddStmt(FS->getCond());
2654 AddDecl(FS->getConditionVariable());
2655 AddStmt(FS->getInit());
2656}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002657void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002658 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2659}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002660void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002661 AddStmt(If->getElse());
2662 AddStmt(If->getThen());
2663 AddStmt(If->getCond());
2664 AddDecl(If->getConditionVariable());
2665}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002666void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002667 // We care about the syntactic form of the initializer list, only.
2668 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2669 IE = Syntactic;
2670 EnqueueChildren(IE);
2671}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002672void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002673 WL.push_back(MemberExprParts(M, Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002674
Guy Benyei11169dd2012-12-18 14:30:41 +00002675 // If the base of the member access expression is an implicit 'this', don't
2676 // visit it.
2677 // FIXME: If we ever want to show these implicit accesses, this will be
2678 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002679 if (M->isImplicitAccess())
2680 return;
2681
2682 // Ignore base anonymous struct/union fields, otherwise they will shadow the
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00002683 // real field that we are interested in.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002684 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2685 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2686 if (FD->isAnonymousStructOrUnion()) {
2687 AddStmt(SubME->getBase());
2688 return;
2689 }
2690 }
2691 }
2692
2693 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002694}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002695void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002696 AddTypeLoc(E->getEncodedTypeSourceInfo());
2697}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002698void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002699 EnqueueChildren(M);
2700 AddTypeLoc(M->getClassReceiverTypeInfo());
2701}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002702void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002703 // Visit the components of the offsetof expression.
2704 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Michael Kruse7520cf02020-03-25 09:26:14 -05002705 const OffsetOfNode &Node = E->getComponent(I - 1);
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 switch (Node.getKind()) {
2707 case OffsetOfNode::Array:
2708 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2709 break;
2710 case OffsetOfNode::Field:
2711 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2712 break;
2713 case OffsetOfNode::Identifier:
2714 case OffsetOfNode::Base:
2715 continue;
2716 }
2717 }
2718 // Visit the type into which we're computing the offset.
2719 AddTypeLoc(E->getTypeSourceInfo());
2720}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002721void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002722 if (E->hasExplicitTemplateArgs())
2723 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002724 WL.push_back(OverloadExprParts(E, Parent));
2725}
2726void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002727 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002728 EnqueueChildren(E);
2729 if (E->isArgumentType())
2730 AddTypeLoc(E->getArgumentTypeInfo());
2731}
Michael Kruse7520cf02020-03-25 09:26:14 -05002732void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002733void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002734 AddStmt(S->getBody());
2735 AddStmt(S->getCond());
2736 AddDecl(S->getConditionVariable());
2737}
2738
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002739void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002740 AddStmt(W->getBody());
2741 AddStmt(W->getCond());
2742 AddDecl(W->getConditionVariable());
2743}
2744
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002745void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002746 for (unsigned I = E->getNumArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002747 AddTypeLoc(E->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002748}
2749
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002750void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002751 AddTypeLoc(E->getQueriedTypeSourceInfo());
2752}
2753
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002754void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002755 EnqueueChildren(E);
2756}
2757
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002758void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002759 VisitOverloadExpr(U);
2760 if (!U->isImplicitAccess())
2761 AddStmt(U->getBase());
2762}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002763void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002764 AddStmt(E->getSubExpr());
2765 AddTypeLoc(E->getWrittenTypeInfo());
2766}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002767void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002768 WL.push_back(SizeOfPackExprParts(E, Parent));
2769}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002770void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002771 // If the opaque value has a source expression, just transparently
2772 // visit that. This is useful for (e.g.) pseudo-object expressions.
2773 if (Expr *SourceExpr = E->getSourceExpr())
2774 return Visit(SourceExpr);
2775}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002776void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002777 AddStmt(E->getBody());
2778 WL.push_back(LambdaExprParts(E, Parent));
2779}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002780void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002781 // Treat the expression like its syntactic form.
2782 Visit(E->getSyntacticForm());
2783}
2784
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002785void EnqueueVisitor::VisitOMPExecutableDirective(
Michael Kruse7520cf02020-03-25 09:26:14 -05002786 const OMPExecutableDirective *D) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002787 EnqueueChildren(D);
2788 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2789 E = D->clauses().end();
2790 I != E; ++I)
2791 EnqueueChildren(*I);
2792}
2793
Alexander Musman3aaab662014-08-19 11:27:13 +00002794void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2795 VisitOMPExecutableDirective(D);
2796}
2797
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002798void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2799 VisitOMPExecutableDirective(D);
2800}
2801
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002802void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002803 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002804}
2805
Alexey Bataevf29276e2014-06-18 04:14:57 +00002806void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002807 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002808}
2809
Alexander Musmanf82886e2014-09-18 05:12:34 +00002810void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2811 VisitOMPLoopDirective(D);
2812}
2813
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002814void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2815 VisitOMPExecutableDirective(D);
2816}
2817
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002818void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2819 VisitOMPExecutableDirective(D);
2820}
2821
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002822void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2823 VisitOMPExecutableDirective(D);
2824}
2825
Alexander Musman80c22892014-07-17 08:54:58 +00002826void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2827 VisitOMPExecutableDirective(D);
2828}
2829
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002830void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2831 VisitOMPExecutableDirective(D);
2832 AddDeclarationNameInfo(D);
2833}
2834
Michael Kruse7520cf02020-03-25 09:26:14 -05002835void EnqueueVisitor::VisitOMPParallelForDirective(
2836 const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002837 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002838}
2839
Alexander Musmane4e893b2014-09-23 09:33:00 +00002840void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2841 const OMPParallelForSimdDirective *D) {
2842 VisitOMPLoopDirective(D);
2843}
2844
cchen47d60942019-12-05 13:43:48 -05002845void EnqueueVisitor::VisitOMPParallelMasterDirective(
2846 const OMPParallelMasterDirective *D) {
2847 VisitOMPExecutableDirective(D);
2848}
2849
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002850void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2851 const OMPParallelSectionsDirective *D) {
2852 VisitOMPExecutableDirective(D);
2853}
2854
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002855void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2856 VisitOMPExecutableDirective(D);
2857}
2858
Michael Kruse7520cf02020-03-25 09:26:14 -05002859void EnqueueVisitor::VisitOMPTaskyieldDirective(
2860 const OMPTaskyieldDirective *D) {
Alexey Bataev68446b72014-07-18 07:47:19 +00002861 VisitOMPExecutableDirective(D);
2862}
2863
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002864void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2865 VisitOMPExecutableDirective(D);
2866}
2867
Alexey Bataev2df347a2014-07-18 10:17:07 +00002868void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2869 VisitOMPExecutableDirective(D);
2870}
2871
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002872void EnqueueVisitor::VisitOMPTaskgroupDirective(
2873 const OMPTaskgroupDirective *D) {
2874 VisitOMPExecutableDirective(D);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00002875 if (const Expr *E = D->getReductionRef())
2876 VisitStmt(E);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002877}
2878
Alexey Bataev6125da92014-07-21 11:26:11 +00002879void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2880 VisitOMPExecutableDirective(D);
2881}
2882
Alexey Bataevc112e942020-02-28 09:52:15 -05002883void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
2884 VisitOMPExecutableDirective(D);
2885}
2886
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002887void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
2888 VisitOMPExecutableDirective(D);
2889}
2890
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002891void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2892 VisitOMPExecutableDirective(D);
2893}
2894
Alexey Bataev0162e452014-07-22 10:10:35 +00002895void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2896 VisitOMPExecutableDirective(D);
2897}
2898
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002899void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2900 VisitOMPExecutableDirective(D);
2901}
2902
Alexey Bataevc112e942020-02-28 09:52:15 -05002903void EnqueueVisitor::VisitOMPTargetDataDirective(
2904 const OMPTargetDataDirective *D) {
Michael Wong65f367f2015-07-21 13:44:28 +00002905 VisitOMPExecutableDirective(D);
2906}
2907
Samuel Antaodf67fc42016-01-19 19:15:56 +00002908void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2909 const OMPTargetEnterDataDirective *D) {
2910 VisitOMPExecutableDirective(D);
2911}
2912
Samuel Antao72590762016-01-19 20:04:50 +00002913void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2914 const OMPTargetExitDataDirective *D) {
2915 VisitOMPExecutableDirective(D);
2916}
2917
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002918void EnqueueVisitor::VisitOMPTargetParallelDirective(
2919 const OMPTargetParallelDirective *D) {
2920 VisitOMPExecutableDirective(D);
2921}
2922
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002923void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2924 const OMPTargetParallelForDirective *D) {
2925 VisitOMPLoopDirective(D);
2926}
2927
Alexey Bataev13314bf2014-10-09 04:18:56 +00002928void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2929 VisitOMPExecutableDirective(D);
2930}
2931
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002932void EnqueueVisitor::VisitOMPCancellationPointDirective(
2933 const OMPCancellationPointDirective *D) {
2934 VisitOMPExecutableDirective(D);
2935}
2936
Alexey Bataev80909872015-07-02 11:25:17 +00002937void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2938 VisitOMPExecutableDirective(D);
2939}
2940
Alexey Bataev49f6e782015-12-01 04:18:41 +00002941void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2942 VisitOMPLoopDirective(D);
2943}
2944
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002945void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2946 const OMPTaskLoopSimdDirective *D) {
2947 VisitOMPLoopDirective(D);
2948}
2949
Alexey Bataev60e51c42019-10-10 20:13:02 +00002950void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
2951 const OMPMasterTaskLoopDirective *D) {
2952 VisitOMPLoopDirective(D);
2953}
2954
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002955void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
2956 const OMPMasterTaskLoopSimdDirective *D) {
2957 VisitOMPLoopDirective(D);
2958}
2959
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002960void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
2961 const OMPParallelMasterTaskLoopDirective *D) {
2962 VisitOMPLoopDirective(D);
2963}
2964
Alexey Bataev14a388f2019-10-25 10:27:13 -04002965void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
2966 const OMPParallelMasterTaskLoopSimdDirective *D) {
2967 VisitOMPLoopDirective(D);
2968}
2969
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002970void EnqueueVisitor::VisitOMPDistributeDirective(
2971 const OMPDistributeDirective *D) {
2972 VisitOMPLoopDirective(D);
2973}
2974
Carlo Bertolli9925f152016-06-27 14:55:37 +00002975void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
2976 const OMPDistributeParallelForDirective *D) {
2977 VisitOMPLoopDirective(D);
2978}
2979
Kelvin Li4a39add2016-07-05 05:00:15 +00002980void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
2981 const OMPDistributeParallelForSimdDirective *D) {
2982 VisitOMPLoopDirective(D);
2983}
2984
Kelvin Li787f3fc2016-07-06 04:45:38 +00002985void EnqueueVisitor::VisitOMPDistributeSimdDirective(
2986 const OMPDistributeSimdDirective *D) {
2987 VisitOMPLoopDirective(D);
2988}
2989
Kelvin Lia579b912016-07-14 02:54:56 +00002990void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
2991 const OMPTargetParallelForSimdDirective *D) {
2992 VisitOMPLoopDirective(D);
2993}
2994
Kelvin Li986330c2016-07-20 22:57:10 +00002995void EnqueueVisitor::VisitOMPTargetSimdDirective(
2996 const OMPTargetSimdDirective *D) {
2997 VisitOMPLoopDirective(D);
2998}
2999
Kelvin Li02532872016-08-05 14:37:37 +00003000void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3001 const OMPTeamsDistributeDirective *D) {
3002 VisitOMPLoopDirective(D);
3003}
3004
Kelvin Li4e325f72016-10-25 12:50:55 +00003005void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3006 const OMPTeamsDistributeSimdDirective *D) {
3007 VisitOMPLoopDirective(D);
3008}
3009
Kelvin Li579e41c2016-11-30 23:51:03 +00003010void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3011 const OMPTeamsDistributeParallelForSimdDirective *D) {
3012 VisitOMPLoopDirective(D);
3013}
3014
Kelvin Li7ade93f2016-12-09 03:24:30 +00003015void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3016 const OMPTeamsDistributeParallelForDirective *D) {
3017 VisitOMPLoopDirective(D);
3018}
3019
Kelvin Libf594a52016-12-17 05:48:59 +00003020void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3021 const OMPTargetTeamsDirective *D) {
3022 VisitOMPExecutableDirective(D);
3023}
3024
Kelvin Li83c451e2016-12-25 04:52:54 +00003025void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3026 const OMPTargetTeamsDistributeDirective *D) {
3027 VisitOMPLoopDirective(D);
3028}
3029
Kelvin Li80e8f562016-12-29 22:16:30 +00003030void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3031 const OMPTargetTeamsDistributeParallelForDirective *D) {
3032 VisitOMPLoopDirective(D);
3033}
3034
Kelvin Li1851df52017-01-03 05:23:48 +00003035void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3036 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3037 VisitOMPLoopDirective(D);
3038}
3039
Kelvin Lida681182017-01-10 18:08:18 +00003040void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3041 const OMPTargetTeamsDistributeSimdDirective *D) {
3042 VisitOMPLoopDirective(D);
3043}
3044
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003045void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003046 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3047 .Visit(S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003048}
3049
3050bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3051 if (RegionOfInterest.isValid()) {
3052 SourceRange Range = getRawCursorExtent(C);
3053 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3054 return false;
3055 }
3056 return true;
3057}
3058
3059bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3060 while (!WL.empty()) {
3061 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00003062 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00003063
3064 // Set the Parent field, then back to its old value once we're done.
3065 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
Michael Kruse7520cf02020-03-25 09:26:14 -05003066
Guy Benyei11169dd2012-12-18 14:30:41 +00003067 switch (LI.getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003068 case VisitorJob::DeclVisitKind: {
3069 const Decl *D = cast<DeclVisit>(&LI)->get();
3070 if (!D)
3071 continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00003072
Michael Kruse7520cf02020-03-25 09:26:14 -05003073 // For now, perform default visitation for Decls.
3074 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3075 cast<DeclVisit>(&LI)->isFirst())))
3076 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003077
Michael Kruse7520cf02020-03-25 09:26:14 -05003078 continue;
3079 }
3080 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3081 for (const TemplateArgumentLoc &Arg :
3082 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3083 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003086 continue;
3087 }
3088 case VisitorJob::TypeLocVisitKind: {
3089 // Perform default visitation for TypeLocs.
3090 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3091 return true;
3092 continue;
3093 }
3094 case VisitorJob::LabelRefVisitKind: {
3095 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3096 if (LabelStmt *stmt = LS->getStmt()) {
3097 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3098 TU))) {
3099 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003100 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003102 continue;
3103 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003104
Michael Kruse7520cf02020-03-25 09:26:14 -05003105 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3106 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3107 if (VisitNestedNameSpecifierLoc(V->get()))
3108 return true;
3109 continue;
3110 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003111
Michael Kruse7520cf02020-03-25 09:26:14 -05003112 case VisitorJob::DeclarationNameInfoVisitKind: {
3113 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3114 return true;
3115 continue;
3116 }
3117 case VisitorJob::MemberRefVisitKind: {
3118 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3119 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3120 return true;
3121 continue;
3122 }
3123 case VisitorJob::StmtVisitKind: {
3124 const Stmt *S = cast<StmtVisit>(&LI)->get();
3125 if (!S)
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 continue;
Richard Smithba71c082013-05-16 06:20:58 +00003127
Michael Kruse7520cf02020-03-25 09:26:14 -05003128 // Update the current cursor.
3129 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3130 if (!IsInRegionOfInterest(Cursor))
3131 continue;
3132 switch (Visitor(Cursor, Parent, ClientData)) {
3133 case CXChildVisit_Break:
3134 return true;
3135 case CXChildVisit_Continue:
3136 break;
3137 case CXChildVisit_Recurse:
3138 if (PostChildrenVisitor)
3139 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3140 EnqueueWorkList(WL, S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 break;
3142 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003143 continue;
3144 }
3145 case VisitorJob::MemberExprPartsKind: {
3146 // Handle the other pieces in the MemberExpr besides the base.
3147 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00003148
Michael Kruse7520cf02020-03-25 09:26:14 -05003149 // Visit the nested-name-specifier
3150 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3151 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +00003152 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05003153
3154 // Visit the declaration name.
3155 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3156 return true;
3157
3158 // Visit the explicitly-specified template arguments, if any.
3159 if (M->hasExplicitTemplateArgs()) {
3160 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3161 *ArgEnd = Arg + M->getNumTemplateArgs();
3162 Arg != ArgEnd; ++Arg) {
3163 if (VisitTemplateArgumentLoc(*Arg))
3164 return true;
3165 }
3166 }
3167 continue;
3168 }
3169 case VisitorJob::DeclRefExprPartsKind: {
3170 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3171 // Visit nested-name-specifier, if present.
3172 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3173 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3174 return true;
3175 // Visit declaration name.
3176 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3177 return true;
3178 continue;
3179 }
3180 case VisitorJob::OverloadExprPartsKind: {
3181 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3182 // Visit the nested-name-specifier.
3183 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3185 return true;
3186 // Visit the declaration name.
3187 if (VisitDeclarationNameInfo(O->getNameInfo()))
3188 return true;
3189 // Visit the overloaded declaration reference.
3190 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3191 return true;
3192 continue;
3193 }
3194 case VisitorJob::SizeOfPackExprPartsKind: {
3195 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3196 NamedDecl *Pack = E->getPack();
3197 if (isa<TemplateTypeParmDecl>(Pack)) {
3198 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3199 E->getPackLoc(), TU)))
3200 return true;
3201
3202 continue;
3203 }
3204
3205 if (isa<TemplateTemplateParmDecl>(Pack)) {
3206 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3207 E->getPackLoc(), TU)))
3208 return true;
3209
3210 continue;
3211 }
3212
3213 // Non-type template parameter packs and function parameter packs are
3214 // treated like DeclRefExpr cursors.
3215 continue;
3216 }
3217
3218 case VisitorJob::LambdaExprPartsKind: {
3219 // Visit non-init captures.
3220 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3221 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3222 CEnd = E->explicit_capture_end();
3223 C != CEnd; ++C) {
3224 if (!C->capturesVariable())
3225 continue;
3226
3227 if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
3228 TU)))
3229 return true;
3230 }
3231 // Visit init captures
3232 for (auto InitExpr : E->capture_inits()) {
3233 if (Visit(InitExpr))
3234 return true;
3235 }
3236
3237 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3238 // Visit parameters and return type, if present.
3239 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3240 if (E->hasExplicitParameters()) {
3241 // Visit parameters.
3242 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3243 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3244 return true;
3245 }
3246 if (E->hasExplicitResultType()) {
3247 // Visit result type.
3248 if (Visit(Proto.getReturnLoc()))
3249 return true;
3250 }
3251 }
3252 break;
3253 }
3254
3255 case VisitorJob::PostChildrenVisitKind:
3256 if (PostChildrenVisitor(Parent, ClientData))
3257 return true;
3258 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00003259 }
3260 }
3261 return false;
3262}
3263
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003264bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00003265 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 if (!WorkListFreeList.empty()) {
3267 WL = WorkListFreeList.back();
3268 WL->clear();
3269 WorkListFreeList.pop_back();
Michael Kruse7520cf02020-03-25 09:26:14 -05003270 } else {
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 WL = new VisitorWorkList();
3272 WorkListCache.push_back(WL);
3273 }
3274 EnqueueWorkList(*WL, S);
3275 bool result = RunVisitorWorkList(*WL);
3276 WorkListFreeList.push_back(WL);
3277 return result;
3278}
3279
3280namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003281typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00003282RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3283 const DeclarationNameInfo &NI, SourceRange QLoc,
3284 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3286 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3287 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
Michael Kruse7520cf02020-03-25 09:26:14 -05003288
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
Michael Kruse7520cf02020-03-25 09:26:14 -05003290
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 RefNamePieces Pieces;
3292
3293 if (WantQualifier && QLoc.isValid())
3294 Pieces.push_back(QLoc);
Michael Kruse7520cf02020-03-25 09:26:14 -05003295
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3297 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00003298
3299 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3300 Pieces.push_back(*TemplateArgsLoc);
3301
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 if (Kind == DeclarationName::CXXOperatorName) {
3303 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003304 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003306 NI.getInfo().CXXOperatorName.EndOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003308
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 if (WantSinglePiece) {
3310 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3311 Pieces.clear();
3312 Pieces.push_back(R);
Michael Kruse7520cf02020-03-25 09:26:14 -05003313 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003314
Michael Kruse7520cf02020-03-25 09:26:14 -05003315 return Pieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00003316}
Michael Kruse7520cf02020-03-25 09:26:14 -05003317} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00003318
3319//===----------------------------------------------------------------------===//
3320// Misc. API hooks.
Michael Kruse7520cf02020-03-25 09:26:14 -05003321//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00003322
Chandler Carruth66660742014-06-27 16:37:27 +00003323namespace {
3324struct RegisterFatalErrorHandler {
3325 RegisterFatalErrorHandler() {
Jan Korousf7d23762019-09-12 22:55:55 +00003326 clang_install_aborting_llvm_fatal_error_handler();
Chandler Carruth66660742014-06-27 16:37:27 +00003327 }
3328};
Michael Kruse7520cf02020-03-25 09:26:14 -05003329} // namespace
Chandler Carruth66660742014-06-27 16:37:27 +00003330
Michael Kruse7520cf02020-03-25 09:26:14 -05003331static llvm::ManagedStatic<RegisterFatalErrorHandler>
3332 RegisterFatalErrorHandlerOnce;
Chandler Carruth66660742014-06-27 16:37:27 +00003333
Guy Benyei11169dd2012-12-18 14:30:41 +00003334CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3335 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 // We use crash recovery to make some of our APIs more reliable, implicitly
3337 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003338 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3339 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003340
Chandler Carruth66660742014-06-27 16:37:27 +00003341 // Look through the managed static to trigger construction of the managed
3342 // static which registers our fatal error handler. This ensures it is only
3343 // registered once.
3344 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003345
Adrian Prantlbc068582015-07-08 01:00:30 +00003346 // Initialize targets for clang module support.
3347 llvm::InitializeAllTargets();
3348 llvm::InitializeAllTargetMCs();
3349 llvm::InitializeAllAsmPrinters();
3350 llvm::InitializeAllAsmParsers();
3351
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003352 CIndexer *CIdxr = new CIndexer();
3353
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 if (excludeDeclarationsFromPCH)
3355 CIdxr->setOnlyLocalDecls();
3356 if (displayDiagnostics)
3357 CIdxr->setDisplayDiagnostics();
3358
3359 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3360 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3361 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3362 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3363 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3364 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3365
3366 return CIdxr;
3367}
3368
3369void clang_disposeIndex(CXIndex CIdx) {
3370 if (CIdx)
3371 delete static_cast<CIndexer *>(CIdx);
3372}
3373
3374void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3375 if (CIdx)
3376 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3377}
3378
3379unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3380 if (CIdx)
3381 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3382 return 0;
3383}
3384
Alex Lorenz08615792017-12-04 21:56:36 +00003385void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
3386 const char *Path) {
3387 if (CIdx)
3388 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
3389}
3390
Guy Benyei11169dd2012-12-18 14:30:41 +00003391void clang_toggleCrashRecovery(unsigned isEnabled) {
3392 if (isEnabled)
3393 llvm::CrashRecoveryContext::Enable();
3394 else
3395 llvm::CrashRecoveryContext::Disable();
3396}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003397
Guy Benyei11169dd2012-12-18 14:30:41 +00003398CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3399 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003400 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003401 enum CXErrorCode Result =
3402 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003403 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003404 assert((TU && Result == CXError_Success) ||
3405 (!TU && Result != CXError_Success));
3406 return TU;
3407}
3408
3409enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3410 const char *ast_filename,
3411 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003412 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003413 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003414
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003415 if (!CIdx || !ast_filename || !out_TU)
3416 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003417
Michael Kruse7520cf02020-03-25 09:26:14 -05003418 LOG_FUNC_SECTION { *Log << ast_filename; }
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003419
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3421 FileSystemOptions FileSystemOpts;
3422
Justin Bognerd512c1e2014-10-15 00:33:06 +00003423 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3424 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003425 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Richard Smithdbafb6c2017-06-29 23:23:46 +00003426 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
Michael Kruse7520cf02020-03-25 09:26:14 -05003427 ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3428 CXXIdx->getOnlyLocalDecls(), None, CaptureDiagsKind::All,
David Blaikie6f7382d2014-08-10 19:08:04 +00003429 /*AllowPCHWithCompilerErrors=*/true,
3430 /*UserFilesAreVolatile=*/true);
David Blaikieea4395e2017-01-06 19:49:01 +00003431 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003432 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003433}
3434
3435unsigned clang_defaultEditingTranslationUnitOptions() {
Michael Kruse7520cf02020-03-25 09:26:14 -05003436 return CXTranslationUnit_PrecompiledPreamble |
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 CXTranslationUnit_CacheCompletionResults;
3438}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003439
Michael Kruse7520cf02020-03-25 09:26:14 -05003440CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3441 CXIndex CIdx, const char *source_filename, int num_command_line_args,
3442 const char *const *command_line_args, unsigned num_unsaved_files,
3443 struct CXUnsavedFile *unsaved_files) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003444 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
Michael Kruse7520cf02020-03-25 09:26:14 -05003445 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3446 num_command_line_args, unsaved_files,
3447 num_unsaved_files, Options);
Guy Benyei11169dd2012-12-18 14:30:41 +00003448}
3449
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003450static CXErrorCode
3451clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3452 const char *const *command_line_args,
3453 int num_command_line_args,
3454 ArrayRef<CXUnsavedFile> unsaved_files,
3455 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003456 // Set up the initial return values.
3457 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003458 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003459
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003460 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003461 if (!CIdx || !out_TU)
3462 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003463
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3465
3466 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3467 setThreadBackgroundPriority();
3468
3469 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003470 bool CreatePreambleOnFirstParse =
3471 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 // FIXME: Add a flag for modules.
Michael Kruse7520cf02020-03-25 09:26:14 -05003473 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3474 CXTranslationUnit_SingleFileParse))
3475 ? TU_Prefix
3476 : TU_Complete;
3477 bool CacheCodeCompletionResults =
3478 options & CXTranslationUnit_CacheCompletionResults;
3479 bool IncludeBriefCommentsInCodeCompletion =
3480 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003481 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
3482 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
Michael Kruse7520cf02020-03-25 09:26:14 -05003483 bool RetainExcludedCB =
3484 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
Ivan Donchevskii6e895282018-05-17 09:24:37 +00003485 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
3486 if (options & CXTranslationUnit_SkipFunctionBodies) {
3487 SkipFunctionBodies =
3488 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
3489 ? SkipFunctionBodiesScope::Preamble
3490 : SkipFunctionBodiesScope::PreambleAndMainFile;
3491 }
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003492
3493 // Configure the diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05003494 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3495 CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003496
Manuel Klimek016c0242016-03-01 10:56:19 +00003497 if (options & CXTranslationUnit_KeepGoing)
Ivan Donchevskii878271b2019-03-07 10:13:50 +00003498 Diags->setFatalsAsError(true);
Manuel Klimek016c0242016-03-01 10:56:19 +00003499
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003500 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
3501 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
3502 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
3503
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003505 llvm::CrashRecoveryContextCleanupRegistrar<
3506 DiagnosticsEngine,
3507 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
3508 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003509
Ahmed Charlesb8984322014-03-07 20:03:18 +00003510 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3511 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003512
3513 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003514 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3515 RemappedCleanup(RemappedFiles.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003516
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003517 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003518 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003519 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003520 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 }
3522
Ahmed Charlesb8984322014-03-07 20:03:18 +00003523 std::unique_ptr<std::vector<const char *>> Args(
3524 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003525
3526 // Recover resources if we crash before exiting this method.
Michael Kruse7520cf02020-03-25 09:26:14 -05003527 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
3528 ArgsCleanup(Args.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003529
3530 // Since the Clang C library is primarily used by batch tools dealing with
3531 // (often very broken) source code, where spell-checking can have a
Michael Kruse7520cf02020-03-25 09:26:14 -05003532 // significant negative impact on performance (particularly when
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 // precompiled headers are involved), we disable it by default.
3534 // Only do this if we haven't found a spell-checking-related argument.
3535 bool FoundSpellCheckingArgument = false;
3536 for (int I = 0; I != num_command_line_args; ++I) {
3537 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3538 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3539 FoundSpellCheckingArgument = true;
3540 break;
3541 }
3542 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 Args->insert(Args->end(), command_line_args,
3544 command_line_args + num_command_line_args);
3545
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003546 if (!FoundSpellCheckingArgument)
3547 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3548
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 // The 'source_filename' argument is optional. If the caller does not
3550 // specify it then it is assumed that the source file is specified
3551 // in the actual argument list.
3552 // Put the source file after command_line_args otherwise if '-x' flag is
3553 // present it will be unused.
3554 if (source_filename)
3555 Args->push_back(source_filename);
3556
3557 // Do we need the detailed preprocessing record?
3558 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3559 Args->push_back("-Xclang");
3560 Args->push_back("-detailed-preprocessing-record");
3561 }
Alex Lorenzcb006402017-04-27 13:47:03 +00003562
3563 // Suppress any editor placeholder diagnostics.
3564 Args->push_back("-fallow-editor-placeholders");
3565
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003567 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003568 // Unless the user specified that they want the preamble on the first parse
3569 // set it up to be created on the first reparse. This makes the first parse
3570 // faster, trading for a slower (first) reparse.
3571 unsigned PrecompilePreambleAfterNParses =
3572 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Alex Lorenz08615792017-12-04 21:56:36 +00003573
Alex Lorenz08615792017-12-04 21:56:36 +00003574 LibclangInvocationReporter InvocationReporter(
3575 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
Alex Lorenz690f0e22017-12-07 20:37:50 +00003576 options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
3577 unsaved_files);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003578 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003579 Args->data(), Args->data() + Args->size(),
3580 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003581 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003582 CaptureDiagnostics, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003583 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3584 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Argyrios Kyrtzidis735e92c2017-06-09 01:20:48 +00003585 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
Evgeny Mankov2ed2e622019-08-27 22:15:32 +00003586 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003587 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3588 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003589
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003590 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003591 if (!Unit && !ErrUnit)
3592 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003593
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 if (NumErrors != Diags->getClient()->getNumErrors()) {
3595 // Make sure to check that 'Unit' is non-NULL.
3596 if (CXXIdx->getDisplayDiagnostics())
3597 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3598 }
3599
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003600 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3601 return CXError_ASTReadError;
3602
David Blaikieea4395e2017-01-06 19:49:01 +00003603 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
Alex Lorenz690f0e22017-12-07 20:37:50 +00003604 if (CXTranslationUnitImpl *TU = *out_TU) {
3605 TU->ParsingOptions = options;
3606 TU->Arguments.reserve(Args->size());
3607 for (const char *Arg : *Args)
3608 TU->Arguments.push_back(Arg);
3609 return CXError_Success;
3610 }
3611 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003612}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003613
3614CXTranslationUnit
Michael Kruse7520cf02020-03-25 09:26:14 -05003615clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003616 const char *const *command_line_args,
3617 int num_command_line_args,
3618 struct CXUnsavedFile *unsaved_files,
Michael Kruse7520cf02020-03-25 09:26:14 -05003619 unsigned num_unsaved_files, unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003620 CXTranslationUnit TU;
3621 enum CXErrorCode Result = clang_parseTranslationUnit2(
3622 CIdx, source_filename, command_line_args, num_command_line_args,
3623 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003624 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003625 assert((TU && Result == CXError_Success) ||
3626 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003627 return TU;
3628}
3629
3630enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003631 CXIndex CIdx, const char *source_filename,
3632 const char *const *command_line_args, int num_command_line_args,
3633 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3634 unsigned options, CXTranslationUnit *out_TU) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003635 noteBottomOfStack();
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003636 SmallVector<const char *, 4> Args;
3637 Args.push_back("clang");
3638 Args.append(command_line_args, command_line_args + num_command_line_args);
3639 return clang_parseTranslationUnit2FullArgv(
3640 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3641 num_unsaved_files, options, out_TU);
3642}
3643
3644enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3645 CXIndex CIdx, const char *source_filename,
3646 const char *const *command_line_args, int num_command_line_args,
3647 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3648 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003649 LOG_FUNC_SECTION {
3650 *Log << source_filename << ": ";
3651 for (int i = 0; i != num_command_line_args; ++i)
3652 *Log << command_line_args[i] << " ";
3653 }
3654
Alp Toker9d85b182014-07-07 01:23:14 +00003655 if (num_unsaved_files && !unsaved_files)
3656 return CXError_InvalidArguments;
3657
Alp Toker5c532982014-07-07 22:42:03 +00003658 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003659 auto ParseTranslationUnitImpl = [=, &result] {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003660 noteBottomOfStack();
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003661 result = clang_parseTranslationUnit_Impl(
3662 CIdx, source_filename, command_line_args, num_command_line_args,
3663 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3664 };
Erik Verbruggen284848d2017-08-29 09:08:02 +00003665
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 llvm::CrashRecoveryContext CRC;
3667
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003668 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3670 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3671 fprintf(stderr, " 'command_line_args' : [");
3672 for (int i = 0; i != num_command_line_args; ++i) {
3673 if (i)
3674 fprintf(stderr, ", ");
3675 fprintf(stderr, "'%s'", command_line_args[i]);
3676 }
3677 fprintf(stderr, "],\n");
3678 fprintf(stderr, " 'unsaved_files' : [");
3679 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3680 if (i)
3681 fprintf(stderr, ", ");
3682 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3683 unsaved_files[i].Length);
3684 }
3685 fprintf(stderr, "],\n");
3686 fprintf(stderr, " 'options' : %d,\n", options);
3687 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003688
3689 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003691 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003692 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 }
Alp Toker5c532982014-07-07 22:42:03 +00003694
3695 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003696}
3697
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003698CXString clang_Type_getObjCEncoding(CXType CT) {
3699 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3700 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3701 std::string encoding;
Michael Kruse7520cf02020-03-25 09:26:14 -05003702 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003703
3704 return cxstring::createDup(encoding);
3705}
3706
3707static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3708 if (C.kind == CXCursor_MacroDefinition) {
3709 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3710 return MDR->getName();
3711 } else if (C.kind == CXCursor_MacroExpansion) {
3712 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3713 return ME.getName();
3714 }
3715 return nullptr;
3716}
3717
3718unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3719 const IdentifierInfo *II = getMacroIdentifier(C);
3720 if (!II) {
3721 return false;
3722 }
3723 ASTUnit *ASTU = getCursorASTUnit(C);
3724 Preprocessor &PP = ASTU->getPreprocessor();
3725 if (const MacroInfo *MI = PP.getMacroInfo(II))
3726 return MI->isFunctionLike();
3727 return false;
3728}
3729
3730unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3731 const IdentifierInfo *II = getMacroIdentifier(C);
3732 if (!II) {
3733 return false;
3734 }
3735 ASTUnit *ASTU = getCursorASTUnit(C);
3736 Preprocessor &PP = ASTU->getPreprocessor();
3737 if (const MacroInfo *MI = PP.getMacroInfo(II))
3738 return MI->isBuiltinMacro();
3739 return false;
3740}
3741
3742unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3743 const Decl *D = getCursorDecl(C);
3744 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3745 if (!FD) {
3746 return false;
3747 }
3748 return FD->isInlined();
3749}
3750
Michael Kruse7520cf02020-03-25 09:26:14 -05003751static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003752 if (callExpr->getNumArgs() != 1) {
3753 return nullptr;
3754 }
3755
3756 StringLiteral *S = nullptr;
3757 auto *arg = callExpr->getArg(0);
3758 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3759 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3760 auto *subExpr = I->getSubExprAsWritten();
3761
Michael Kruse7520cf02020-03-25 09:26:14 -05003762 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003763 return nullptr;
3764 }
3765
3766 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3767 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3768 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3769 } else {
3770 return nullptr;
3771 }
3772 return S;
3773}
3774
David Blaikie59272572016-04-13 18:23:33 +00003775struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003776 CXEvalResultKind EvalType;
3777 union {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003778 unsigned long long unsignedVal;
3779 long long intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003780 double floatVal;
3781 char *stringVal;
3782 } EvalData;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003783 bool IsUnsignedInt;
David Blaikie59272572016-04-13 18:23:33 +00003784 ~ExprEvalResult() {
3785 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3786 EvalType != CXEval_Int) {
Alex Lorenza19cb2e2019-01-08 23:28:37 +00003787 delete[] EvalData.stringVal;
David Blaikie59272572016-04-13 18:23:33 +00003788 }
3789 }
3790};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003791
3792void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003793 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003794}
3795
3796CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3797 if (!E) {
3798 return CXEval_UnExposed;
3799 }
3800 return ((ExprEvalResult *)E)->EvalType;
3801}
3802
3803int clang_EvalResult_getAsInt(CXEvalResult E) {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003804 return clang_EvalResult_getAsLongLong(E);
3805}
3806
3807long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003808 if (!E) {
3809 return 0;
3810 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003811 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003812 if (Result->IsUnsignedInt)
3813 return Result->EvalData.unsignedVal;
3814 return Result->EvalData.intVal;
3815}
3816
3817unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
3818 return ((ExprEvalResult *)E)->IsUnsignedInt;
3819}
3820
3821unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
3822 if (!E) {
3823 return 0;
3824 }
3825
Michael Kruse7520cf02020-03-25 09:26:14 -05003826 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003827 if (Result->IsUnsignedInt)
3828 return Result->EvalData.unsignedVal;
3829 return Result->EvalData.intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003830}
3831
3832double clang_EvalResult_getAsDouble(CXEvalResult E) {
3833 if (!E) {
3834 return 0;
3835 }
3836 return ((ExprEvalResult *)E)->EvalData.floatVal;
3837}
3838
Michael Kruse7520cf02020-03-25 09:26:14 -05003839const char *clang_EvalResult_getAsStr(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003840 if (!E) {
3841 return nullptr;
3842 }
3843 return ((ExprEvalResult *)E)->EvalData.stringVal;
3844}
3845
Michael Kruse7520cf02020-03-25 09:26:14 -05003846static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003847 Expr::EvalResult ER;
3848 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003849 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003850 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003851
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003852 expr = expr->IgnoreParens();
Emilio Cobos Alvarez74375452019-07-09 14:27:01 +00003853 if (expr->isValueDependent())
3854 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003855 if (!expr->EvaluateAsRValue(ER, ctx))
3856 return nullptr;
3857
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003858 QualType rettype;
3859 CallExpr *callExpr;
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00003860 auto result = std::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003861 result->EvalType = CXEval_UnExposed;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003862 result->IsUnsignedInt = false;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003863
David Blaikiebbc00882016-04-13 18:36:19 +00003864 if (ER.Val.isInt()) {
3865 result->EvalType = CXEval_Int;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003866
Michael Kruse7520cf02020-03-25 09:26:14 -05003867 auto &val = ER.Val.getInt();
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003868 if (val.isUnsigned()) {
3869 result->IsUnsignedInt = true;
3870 result->EvalData.unsignedVal = val.getZExtValue();
3871 } else {
3872 result->EvalData.intVal = val.getExtValue();
3873 }
3874
David Blaikiebbc00882016-04-13 18:36:19 +00003875 return result.release();
3876 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003877
David Blaikiebbc00882016-04-13 18:36:19 +00003878 if (ER.Val.isFloat()) {
3879 llvm::SmallVector<char, 100> Buffer;
3880 ER.Val.getFloat().toString(Buffer);
3881 std::string floatStr(Buffer.data(), Buffer.size());
3882 result->EvalType = CXEval_Float;
3883 bool ignored;
3884 llvm::APFloat apFloat = ER.Val.getFloat();
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003885 apFloat.convert(llvm::APFloat::IEEEdouble(),
David Blaikiebbc00882016-04-13 18:36:19 +00003886 llvm::APFloat::rmNearestTiesToEven, &ignored);
3887 result->EvalData.floatVal = apFloat.convertToDouble();
3888 return result.release();
3889 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003890
David Blaikiebbc00882016-04-13 18:36:19 +00003891 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3892 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3893 auto *subExpr = I->getSubExprAsWritten();
3894 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3895 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003896 const StringLiteral *StrE = nullptr;
3897 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003898 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003899
3900 if (ObjCExpr) {
3901 StrE = ObjCExpr->getString();
3902 result->EvalType = CXEval_ObjCStrLiteral;
3903 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003904 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003905 result->EvalType = CXEval_StrLiteral;
3906 }
3907
3908 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003909 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003910 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3911 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003912 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003913 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003914 }
3915 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3916 expr->getStmtClass() == Stmt::StringLiteralClass) {
3917 const StringLiteral *StrE = nullptr;
3918 const ObjCStringLiteral *ObjCExpr;
3919 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003920
David Blaikiebbc00882016-04-13 18:36:19 +00003921 if (ObjCExpr) {
3922 StrE = ObjCExpr->getString();
3923 result->EvalType = CXEval_ObjCStrLiteral;
3924 } else {
3925 StrE = cast<StringLiteral>(expr);
3926 result->EvalType = CXEval_StrLiteral;
3927 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003928
David Blaikiebbc00882016-04-13 18:36:19 +00003929 std::string strRef(StrE->getString().str());
3930 result->EvalData.stringVal = new char[strRef.size() + 1];
3931 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3932 result->EvalData.stringVal[strRef.size()] = '\0';
3933 return result.release();
3934 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003935
David Blaikiebbc00882016-04-13 18:36:19 +00003936 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3937 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003938
David Blaikiebbc00882016-04-13 18:36:19 +00003939 rettype = CC->getType();
3940 if (rettype.getAsString() == "CFStringRef" &&
3941 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003942
David Blaikiebbc00882016-04-13 18:36:19 +00003943 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3944 StringLiteral *S = getCFSTR_value(callExpr);
3945 if (S) {
3946 std::string strLiteral(S->getString().str());
3947 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003948
David Blaikiebbc00882016-04-13 18:36:19 +00003949 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3950 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3951 strLiteral.size());
3952 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003953 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003954 }
3955 }
3956
David Blaikiebbc00882016-04-13 18:36:19 +00003957 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
3958 callExpr = static_cast<CallExpr *>(expr);
3959 rettype = callExpr->getCallReturnType(ctx);
3960
3961 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
3962 return nullptr;
3963
3964 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
3965 if (callExpr->getNumArgs() == 1 &&
3966 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
3967 return nullptr;
3968 } else if (rettype.getAsString() == "CFStringRef") {
3969
3970 StringLiteral *S = getCFSTR_value(callExpr);
3971 if (S) {
3972 std::string strLiteral(S->getString().str());
3973 result->EvalType = CXEval_CFStr;
3974 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3975 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3976 strLiteral.size());
3977 result->EvalData.stringVal[strLiteral.size()] = '\0';
3978 return result.release();
3979 }
3980 }
3981 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
3982 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
3983 ValueDecl *V = D->getDecl();
3984 if (V->getKind() == Decl::Function) {
3985 std::string strName = V->getNameAsString();
3986 result->EvalType = CXEval_Other;
3987 result->EvalData.stringVal = new char[strName.size() + 1];
3988 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
3989 result->EvalData.stringVal[strName.size()] = '\0';
3990 return result.release();
3991 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003992 }
3993
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003994 return nullptr;
3995}
3996
Alex Lorenz65317e12019-01-08 22:32:51 +00003997static const Expr *evaluateDeclExpr(const Decl *D) {
3998 if (!D)
Evgeniy Stepanov9b871492018-07-10 19:48:53 +00003999 return nullptr;
Alex Lorenz65317e12019-01-08 22:32:51 +00004000 if (auto *Var = dyn_cast<VarDecl>(D))
4001 return Var->getInit();
4002 else if (auto *Field = dyn_cast<FieldDecl>(D))
4003 return Field->getInClassInitializer();
4004 return nullptr;
4005}
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004006
Alex Lorenz65317e12019-01-08 22:32:51 +00004007static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4008 assert(CS && "invalid compound statement");
4009 for (auto *bodyIterator : CS->body()) {
4010 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4011 return E;
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004012 }
Alex Lorenzc4cf96e2018-07-09 19:56:45 +00004013 return nullptr;
4014}
4015
Alex Lorenz65317e12019-01-08 22:32:51 +00004016CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
4017 if (const Expr *E =
4018 clang_getCursorKind(C) == CXCursor_CompoundStmt
4019 ? evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)))
4020 : evaluateDeclExpr(getCursorDecl(C)))
4021 return const_cast<CXEvalResult>(
4022 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4023 return nullptr;
4024}
4025
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004026unsigned clang_Cursor_hasAttrs(CXCursor C) {
4027 const Decl *D = getCursorDecl(C);
4028 if (!D) {
4029 return 0;
4030 }
4031
4032 if (D->hasAttrs()) {
4033 return 1;
4034 }
4035
4036 return 0;
4037}
Guy Benyei11169dd2012-12-18 14:30:41 +00004038unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4039 return CXSaveTranslationUnit_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05004040}
Guy Benyei11169dd2012-12-18 14:30:41 +00004041
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004042static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4043 const char *FileName,
4044 unsigned options) {
4045 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4047 setThreadBackgroundPriority();
4048
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004049 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4050 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00004051}
4052
4053int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4054 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004055 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004056
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004057 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004058 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004060 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004061
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004062 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4064 if (!CXXUnit->hasSema())
4065 return CXSaveError_InvalidTU;
4066
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004067 CXSaveError result;
4068 auto SaveTranslationUnitImpl = [=, &result]() {
4069 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4070 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004071
Erik Verbruggen3cc39112017-11-14 09:34:39 +00004072 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004073 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00004074
4075 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4076 PrintLibclangResourceUsage(TU);
4077
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004078 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 }
4080
4081 // We have an AST that has invalid nodes due to compiler errors.
4082 // Use a crash recovery thread for protection.
4083
4084 llvm::CrashRecoveryContext CRC;
4085
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004086 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4088 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4089 fprintf(stderr, " 'options' : %d,\n", options);
4090 fprintf(stderr, "}\n");
4091
4092 return CXSaveError_Unknown;
4093
4094 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4095 PrintLibclangResourceUsage(TU);
4096 }
4097
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004098 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004099}
4100
4101void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4102 if (CTUnit) {
4103 // If the translation unit has been marked as unsafe to free, just discard
4104 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004105 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4106 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 return;
4108
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004109 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00004110 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4112 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00004113 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 delete CTUnit;
4115 }
4116}
4117
Erik Verbruggen346066b2017-05-30 14:25:54 +00004118unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4119 if (CTUnit) {
4120 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4121
4122 if (Unit && Unit->isUnsafeToFree())
4123 return false;
4124
4125 Unit->ResetForParse();
4126 return true;
4127 }
4128
4129 return false;
4130}
4131
Guy Benyei11169dd2012-12-18 14:30:41 +00004132unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4133 return CXReparse_None;
4134}
4135
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004136static CXErrorCode
4137clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4138 ArrayRef<CXUnsavedFile> unsaved_files,
4139 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004140 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004141 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004142 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004143 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004144 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004145
4146 // Reset the associated diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05004147 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00004148 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004149
Dmitri Gribenko183436e2013-01-26 21:49:50 +00004150 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4152 setThreadBackgroundPriority();
4153
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004154 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00004156
4157 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4158 new std::vector<ASTUnit::RemappedFile>());
4159
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05004161 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4162 RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00004163
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004164 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004165 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00004166 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004167 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004169
Adrian Prantlbb165fb2015-06-20 18:53:08 +00004170 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4171 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004172 return CXError_Success;
4173 if (isASTReadError(CXXUnit))
4174 return CXError_ASTReadError;
4175 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00004176}
4177
4178int clang_reparseTranslationUnit(CXTranslationUnit TU,
4179 unsigned num_unsaved_files,
4180 struct CXUnsavedFile *unsaved_files,
4181 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004182 LOG_FUNC_SECTION { *Log << TU; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004183
Alp Toker9d85b182014-07-07 01:23:14 +00004184 if (num_unsaved_files && !unsaved_files)
4185 return CXError_InvalidArguments;
4186
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004187 CXErrorCode result;
4188 auto ReparseTranslationUnitImpl = [=, &result]() {
4189 result = clang_reparseTranslationUnit_Impl(
4190 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
4191 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004192
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 llvm::CrashRecoveryContext CRC;
4194
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004195 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004197 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004198 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4200 PrintLibclangResourceUsage(TU);
4201
Alp Toker5c532982014-07-07 22:42:03 +00004202 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004203}
4204
Guy Benyei11169dd2012-12-18 14:30:41 +00004205CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004206 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004207 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004208 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004209 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004210
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004211 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004212 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004213}
4214
4215CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004216 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004217 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004218 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004219 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004220
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004221 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4223}
4224
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004225CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4226 if (isNotUsableTU(CTUnit)) {
4227 LOG_BAD_TU(CTUnit);
4228 return nullptr;
4229 }
4230
Michael Kruse7520cf02020-03-25 09:26:14 -05004231 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004232 impl->TranslationUnit = CTUnit;
4233 return impl;
4234}
4235
4236CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4237 if (!TargetInfo)
4238 return cxstring::createEmpty();
4239
4240 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4241 assert(!isNotUsableTU(CTUnit) &&
4242 "Unexpected unusable translation unit in TargetInfo");
4243
4244 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4245 std::string Triple =
Michael Kruse7520cf02020-03-25 09:26:14 -05004246 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004247 return cxstring::createDup(Triple);
4248}
4249
4250int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4251 if (!TargetInfo)
4252 return -1;
4253
4254 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4255 assert(!isNotUsableTU(CTUnit) &&
4256 "Unexpected unusable translation unit in TargetInfo");
4257
4258 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4259 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4260}
4261
4262void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4263 if (!TargetInfo)
4264 return;
4265
4266 delete TargetInfo;
4267}
4268
Guy Benyei11169dd2012-12-18 14:30:41 +00004269//===----------------------------------------------------------------------===//
4270// CXFile Operations.
4271//===----------------------------------------------------------------------===//
4272
Guy Benyei11169dd2012-12-18 14:30:41 +00004273CXString clang_getFileName(CXFile SFile) {
4274 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00004275 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00004276
4277 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004279}
4280
4281time_t clang_getFileTime(CXFile SFile) {
4282 if (!SFile)
4283 return 0;
4284
4285 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4286 return FEnt->getModificationTime();
4287}
4288
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004289CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004290 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004291 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00004292 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004293 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004294
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004295 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004296
4297 FileManager &FMgr = CXXUnit->getFileManager();
Harlan Haskins8d323d12019-08-01 21:31:56 +00004298 auto File = FMgr.getFile(file_name);
4299 if (!File)
4300 return nullptr;
4301 return const_cast<FileEntry *>(*File);
Guy Benyei11169dd2012-12-18 14:30:41 +00004302}
4303
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004304const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4305 size_t *size) {
4306 if (isNotUsableTU(TU)) {
4307 LOG_BAD_TU(TU);
4308 return nullptr;
4309 }
4310
4311 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4312 FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
4313 bool Invalid = true;
Nico Weber04347d82019-04-04 21:06:41 +00004314 const llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid);
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004315 if (Invalid) {
4316 if (size)
4317 *size = 0;
4318 return nullptr;
4319 }
4320 if (size)
4321 *size = buf->getBufferSize();
4322 return buf->getBufferStart();
4323}
4324
Michael Kruse7520cf02020-03-25 09:26:14 -05004325unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004326 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004327 LOG_BAD_TU(TU);
4328 return 0;
4329 }
4330
4331 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00004332 return 0;
4333
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004334 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004335 FileEntry *FEnt = static_cast<FileEntry *>(file);
Michael Kruse7520cf02020-03-25 09:26:14 -05004336 return CXXUnit->getPreprocessor()
4337 .getHeaderSearchInfo()
4338 .isFileMultipleIncludeGuarded(FEnt);
Guy Benyei11169dd2012-12-18 14:30:41 +00004339}
4340
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004341int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
4342 if (!file || !outID)
4343 return 1;
4344
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004345 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00004346 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
4347 outID->data[0] = ID.getDevice();
4348 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004349 outID->data[2] = FEnt->getModificationTime();
4350 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004351}
4352
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00004353int clang_File_isEqual(CXFile file1, CXFile file2) {
4354 if (file1 == file2)
4355 return true;
4356
4357 if (!file1 || !file2)
4358 return false;
4359
4360 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
4361 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
4362 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
4363}
4364
Fangrui Songe46ac5f2018-04-07 20:50:35 +00004365CXString clang_File_tryGetRealPathName(CXFile SFile) {
4366 if (!SFile)
4367 return cxstring::createNull();
4368
4369 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4370 return cxstring::createRef(FEnt->tryGetRealPathName());
4371}
4372
Guy Benyei11169dd2012-12-18 14:30:41 +00004373//===----------------------------------------------------------------------===//
4374// CXCursor Operations.
4375//===----------------------------------------------------------------------===//
4376
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004377static const Decl *getDeclFromExpr(const Stmt *E) {
4378 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004379 return getDeclFromExpr(CE->getSubExpr());
4380
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004381 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004382 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004383 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004385 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004386 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004387 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 if (PRE->isExplicitProperty())
4389 return PRE->getExplicitProperty();
4390 // It could be messaging both getter and setter as in:
4391 // ++myobj.myprop;
4392 // in which case prefer to associate the setter since it is less obvious
4393 // from inspecting the source that the setter is going to get called.
4394 if (PRE->isMessagingSetter())
4395 return PRE->getImplicitPropertySetter();
4396 return PRE->getImplicitPropertyGetter();
4397 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004398 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004400 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004401 if (Expr *Src = OVE->getSourceExpr())
4402 return getDeclFromExpr(Src);
Michael Kruse7520cf02020-03-25 09:26:14 -05004403
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004404 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004406 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 if (!CE->isElidable())
Michael Kruse7520cf02020-03-25 09:26:14 -05004408 return CE->getConstructor();
Richard Smith5179eb72016-06-28 19:03:57 +00004409 if (const CXXInheritedCtorInitExpr *CE =
4410 dyn_cast<CXXInheritedCtorInitExpr>(E))
4411 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004412 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 return OME->getMethodDecl();
4414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004415 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 return PE->getProtocol();
Michael Kruse7520cf02020-03-25 09:26:14 -05004417 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4418 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004420 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004421 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 isa<ParmVarDecl>(SizeOfPack->getPack()))
4423 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00004424
4425 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004426}
4427
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004428static SourceLocation getLocationFromExpr(const Expr *E) {
4429 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 return getLocationFromExpr(CE->getSubExpr());
4431
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004432 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004433 return /*FIXME:*/ Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004434 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004436 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004437 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004438 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004440 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004442 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 return PropRef->getLocation();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004444
4445 return E->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00004446}
4447
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00004448extern "C" {
4449
Michael Kruse7520cf02020-03-25 09:26:14 -05004450unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 CXClientData client_data) {
4452 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4453 /*VisitPreprocessorLast=*/false);
4454 return CursorVis.VisitChildren(parent);
4455}
4456
4457#ifndef __has_feature
4458#define __has_feature(x) 0
4459#endif
4460#if __has_feature(blocks)
Michael Kruse7520cf02020-03-25 09:26:14 -05004461typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4462 CXCursor parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00004463
4464static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004465 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4467 return block(cursor, parent);
4468}
4469#else
4470// If we are compiled with a compiler that doesn't have native blocks support,
Michael Kruse7520cf02020-03-25 09:26:14 -05004471// define and call the block manually, so the
4472typedef struct _CXChildVisitResult {
4473 void *isa;
4474 int flags;
4475 int reserved;
4476 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
4477 CXCursor);
4478} * CXCursorVisitorBlock;
Guy Benyei11169dd2012-12-18 14:30:41 +00004479
4480static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004481 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4483 return block->invoke(block, cursor, parent);
4484}
4485#endif
4486
Guy Benyei11169dd2012-12-18 14:30:41 +00004487unsigned clang_visitChildrenWithBlock(CXCursor parent,
4488 CXCursorVisitorBlock block) {
4489 return clang_visitChildren(parent, visitWithBlock, block);
4490}
4491
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004492static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004494 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004495
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004496 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004498 if (const ObjCPropertyImplDecl *PropImpl =
4499 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004501 return cxstring::createDup(Property->getIdentifier()->getName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004502
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004503 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004505 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004506
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004507 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004509
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004510 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004511 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004512
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004513 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4515 // and returns different names. NamedDecl returns the class name and
4516 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004517 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004518
4519 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004520 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05004521
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 SmallString<1024> S;
4523 llvm::raw_svector_ostream os(S);
4524 ND->printName(os);
Michael Kruse7520cf02020-03-25 09:26:14 -05004525
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004526 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004527}
4528
4529CXString clang_getCursorSpelling(CXCursor C) {
4530 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004531 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004532
4533 if (clang_isReference(C.kind)) {
4534 switch (C.kind) {
4535 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004536 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004537 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 }
4539 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004540 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004541 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 }
4543 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004544 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004546 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 }
4548 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004549 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004550 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 }
4552 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004553 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 assert(Type && "Missing type decl");
4555
Michael Kruse7520cf02020-03-25 09:26:14 -05004556 return cxstring::createDup(
4557 getCursorContext(C).getTypeDeclType(Type).getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 }
4559 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004560 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 assert(Template && "Missing template decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004562
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004563 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004565
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004567 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 assert(NS && "Missing namespace decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004569
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004570 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 }
4572
4573 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004574 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 assert(Field && "Missing member decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004576
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004577 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 }
4579
4580 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004581 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 assert(Label && "Missing label");
Michael Kruse7520cf02020-03-25 09:26:14 -05004583
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004584 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 }
4586
4587 case CXCursor_OverloadedDeclRef: {
4588 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004589 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4590 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004591 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004592 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004594 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004595 return cxstring::createDup(E->getName().getAsString());
Michael Kruse7520cf02020-03-25 09:26:14 -05004596 OverloadedTemplateStorage *Ovl =
4597 Storage.get<OverloadedTemplateStorage *>();
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004599 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004600 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004602
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004604 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004605 assert(Var && "Missing variable decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004606
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004607 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004609
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004611 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 }
4613 }
4614
4615 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004616 const Expr *E = getCursorExpr(C);
4617
4618 if (C.kind == CXCursor_ObjCStringLiteral ||
4619 C.kind == CXCursor_StringLiteral) {
4620 const StringLiteral *SLit;
4621 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4622 SLit = OSL->getString();
4623 } else {
4624 SLit = cast<StringLiteral>(E);
4625 }
4626 SmallString<256> Buf;
4627 llvm::raw_svector_ostream OS(Buf);
4628 SLit->outputString(OS);
4629 return cxstring::createDup(OS.str());
4630 }
4631
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004632 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 if (D)
4634 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004635 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 }
4637
4638 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004639 const Stmt *S = getCursorStmt(C);
4640 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004641 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004642
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004643 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004645
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 if (C.kind == CXCursor_MacroExpansion)
Michael Kruse7520cf02020-03-25 09:26:14 -05004647 return cxstring::createRef(
4648 getCursorMacroExpansion(C).getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004649
4650 if (C.kind == CXCursor_MacroDefinition)
Michael Kruse7520cf02020-03-25 09:26:14 -05004651 return cxstring::createRef(
4652 getCursorMacroDefinition(C)->getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004653
4654 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004655 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004656
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 if (clang_isDeclaration(C.kind))
4658 return getDeclSpelling(getCursorDecl(C));
4659
4660 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004661 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004662 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 }
4664
4665 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004666 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004667 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 }
4669
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004670 if (C.kind == CXCursor_PackedAttr) {
4671 return cxstring::createRef("packed");
4672 }
4673
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004674 if (C.kind == CXCursor_VisibilityAttr) {
4675 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4676 switch (AA->getVisibility()) {
4677 case VisibilityAttr::VisibilityType::Default:
4678 return cxstring::createRef("default");
4679 case VisibilityAttr::VisibilityType::Hidden:
4680 return cxstring::createRef("hidden");
4681 case VisibilityAttr::VisibilityType::Protected:
4682 return cxstring::createRef("protected");
4683 }
4684 llvm_unreachable("unknown visibility type");
4685 }
4686
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004687 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004688}
4689
Michael Kruse7520cf02020-03-25 09:26:14 -05004690CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 unsigned options) {
4692 if (clang_Cursor_isNull(C))
4693 return clang_getNullRange();
4694
4695 ASTContext &Ctx = getCursorContext(C);
4696
4697 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004698 const Stmt *S = getCursorStmt(C);
4699 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 if (pieceIndex > 0)
4701 return clang_getNullRange();
4702 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4703 }
4704
4705 return clang_getNullRange();
4706 }
4707
4708 if (C.kind == CXCursor_ObjCMessageExpr) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004709 if (const ObjCMessageExpr *ME =
4710 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 if (pieceIndex >= ME->getNumSelectorLocs())
4712 return clang_getNullRange();
4713 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4714 }
4715 }
4716
4717 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4718 C.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004719 if (const ObjCMethodDecl *MD =
4720 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 if (pieceIndex >= MD->getNumSelectorLocs())
4722 return clang_getNullRange();
4723 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4724 }
4725 }
4726
4727 if (C.kind == CXCursor_ObjCCategoryDecl ||
4728 C.kind == CXCursor_ObjCCategoryImplDecl) {
4729 if (pieceIndex > 0)
4730 return clang_getNullRange();
Michael Kruse7520cf02020-03-25 09:26:14 -05004731 if (const ObjCCategoryDecl *CD =
4732 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004733 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Michael Kruse7520cf02020-03-25 09:26:14 -05004734 if (const ObjCCategoryImplDecl *CID =
4735 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4737 }
4738
4739 if (C.kind == CXCursor_ModuleImportDecl) {
4740 if (pieceIndex > 0)
4741 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004742 if (const ImportDecl *ImportD =
4743 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4745 if (!Locs.empty())
Michael Kruse7520cf02020-03-25 09:26:14 -05004746 return cxloc::translateSourceRange(
4747 Ctx, SourceRange(Locs.front(), Locs.back()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 }
4749 return clang_getNullRange();
4750 }
4751
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004752 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
Kevin Funk4be5d672016-12-20 09:56:56 +00004753 C.kind == CXCursor_ConversionFunction ||
4754 C.kind == CXCursor_FunctionDecl) {
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004755 if (pieceIndex > 0)
4756 return clang_getNullRange();
4757 if (const FunctionDecl *FD =
4758 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4759 DeclarationNameInfo FunctionName = FD->getNameInfo();
4760 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4761 }
4762 return clang_getNullRange();
4763 }
4764
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 // FIXME: A CXCursor_InclusionDirective should give the location of the
4766 // filename, but we don't keep track of this.
4767
4768 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4769 // but we don't keep track of this.
4770
4771 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4772 // but we don't keep track of this.
4773
4774 // Default handling, give the location of the cursor.
4775
4776 if (pieceIndex > 0)
4777 return clang_getNullRange();
4778
4779 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4780 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4781 return cxloc::translateSourceRange(Ctx, Loc);
4782}
4783
Eli Bendersky44a206f2014-07-31 18:04:56 +00004784CXString clang_Cursor_getMangling(CXCursor C) {
4785 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4786 return cxstring::createEmpty();
4787
Eli Bendersky44a206f2014-07-31 18:04:56 +00004788 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004789 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004790 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4791 return cxstring::createEmpty();
4792
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004793 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004794 ASTNameGenerator ASTNameGen(Ctx);
4795 return cxstring::createDup(ASTNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004796}
4797
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004798CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4799 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4800 return nullptr;
4801
4802 const Decl *D = getCursorDecl(C);
4803 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4804 return nullptr;
4805
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004806 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004807 ASTNameGenerator ASTNameGen(Ctx);
4808 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004809 return cxstring::createSet(Manglings);
4810}
4811
Dave Lee1a532c92017-09-22 16:58:57 +00004812CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
4813 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4814 return nullptr;
4815
4816 const Decl *D = getCursorDecl(C);
4817 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
4818 return nullptr;
4819
4820 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004821 ASTNameGenerator ASTNameGen(Ctx);
4822 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Dave Lee1a532c92017-09-22 16:58:57 +00004823 return cxstring::createSet(Manglings);
4824}
4825
Jonathan Coe45ef5032018-01-16 10:19:56 +00004826CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
4827 if (clang_Cursor_isNull(C))
4828 return 0;
4829 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
4830}
4831
4832void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
4833 if (Policy)
4834 delete static_cast<PrintingPolicy *>(Policy);
4835}
4836
4837unsigned
4838clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
4839 enum CXPrintingPolicyProperty Property) {
4840 if (!Policy)
4841 return 0;
4842
4843 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4844 switch (Property) {
4845 case CXPrintingPolicy_Indentation:
4846 return P->Indentation;
4847 case CXPrintingPolicy_SuppressSpecifiers:
4848 return P->SuppressSpecifiers;
4849 case CXPrintingPolicy_SuppressTagKeyword:
4850 return P->SuppressTagKeyword;
4851 case CXPrintingPolicy_IncludeTagDefinition:
4852 return P->IncludeTagDefinition;
4853 case CXPrintingPolicy_SuppressScope:
4854 return P->SuppressScope;
4855 case CXPrintingPolicy_SuppressUnwrittenScope:
4856 return P->SuppressUnwrittenScope;
4857 case CXPrintingPolicy_SuppressInitializers:
4858 return P->SuppressInitializers;
4859 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4860 return P->ConstantArraySizeAsWritten;
4861 case CXPrintingPolicy_AnonymousTagLocations:
4862 return P->AnonymousTagLocations;
4863 case CXPrintingPolicy_SuppressStrongLifetime:
4864 return P->SuppressStrongLifetime;
4865 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4866 return P->SuppressLifetimeQualifiers;
4867 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4868 return P->SuppressTemplateArgsInCXXConstructors;
4869 case CXPrintingPolicy_Bool:
4870 return P->Bool;
4871 case CXPrintingPolicy_Restrict:
4872 return P->Restrict;
4873 case CXPrintingPolicy_Alignof:
4874 return P->Alignof;
4875 case CXPrintingPolicy_UnderscoreAlignof:
4876 return P->UnderscoreAlignof;
4877 case CXPrintingPolicy_UseVoidForZeroParams:
4878 return P->UseVoidForZeroParams;
4879 case CXPrintingPolicy_TerseOutput:
4880 return P->TerseOutput;
4881 case CXPrintingPolicy_PolishForDeclaration:
4882 return P->PolishForDeclaration;
4883 case CXPrintingPolicy_Half:
4884 return P->Half;
4885 case CXPrintingPolicy_MSWChar:
4886 return P->MSWChar;
4887 case CXPrintingPolicy_IncludeNewlines:
4888 return P->IncludeNewlines;
4889 case CXPrintingPolicy_MSVCFormatting:
4890 return P->MSVCFormatting;
4891 case CXPrintingPolicy_ConstantsAsWritten:
4892 return P->ConstantsAsWritten;
4893 case CXPrintingPolicy_SuppressImplicitBase:
4894 return P->SuppressImplicitBase;
4895 case CXPrintingPolicy_FullyQualifiedName:
4896 return P->FullyQualifiedName;
4897 }
4898
4899 assert(false && "Invalid CXPrintingPolicyProperty");
4900 return 0;
4901}
4902
4903void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
4904 enum CXPrintingPolicyProperty Property,
4905 unsigned Value) {
4906 if (!Policy)
4907 return;
4908
4909 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4910 switch (Property) {
4911 case CXPrintingPolicy_Indentation:
4912 P->Indentation = Value;
4913 return;
4914 case CXPrintingPolicy_SuppressSpecifiers:
4915 P->SuppressSpecifiers = Value;
4916 return;
4917 case CXPrintingPolicy_SuppressTagKeyword:
4918 P->SuppressTagKeyword = Value;
4919 return;
4920 case CXPrintingPolicy_IncludeTagDefinition:
4921 P->IncludeTagDefinition = Value;
4922 return;
4923 case CXPrintingPolicy_SuppressScope:
4924 P->SuppressScope = Value;
4925 return;
4926 case CXPrintingPolicy_SuppressUnwrittenScope:
4927 P->SuppressUnwrittenScope = Value;
4928 return;
4929 case CXPrintingPolicy_SuppressInitializers:
4930 P->SuppressInitializers = Value;
4931 return;
4932 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4933 P->ConstantArraySizeAsWritten = Value;
4934 return;
4935 case CXPrintingPolicy_AnonymousTagLocations:
4936 P->AnonymousTagLocations = Value;
4937 return;
4938 case CXPrintingPolicy_SuppressStrongLifetime:
4939 P->SuppressStrongLifetime = Value;
4940 return;
4941 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4942 P->SuppressLifetimeQualifiers = Value;
4943 return;
4944 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4945 P->SuppressTemplateArgsInCXXConstructors = Value;
4946 return;
4947 case CXPrintingPolicy_Bool:
4948 P->Bool = Value;
4949 return;
4950 case CXPrintingPolicy_Restrict:
4951 P->Restrict = Value;
4952 return;
4953 case CXPrintingPolicy_Alignof:
4954 P->Alignof = Value;
4955 return;
4956 case CXPrintingPolicy_UnderscoreAlignof:
4957 P->UnderscoreAlignof = Value;
4958 return;
4959 case CXPrintingPolicy_UseVoidForZeroParams:
4960 P->UseVoidForZeroParams = Value;
4961 return;
4962 case CXPrintingPolicy_TerseOutput:
4963 P->TerseOutput = Value;
4964 return;
4965 case CXPrintingPolicy_PolishForDeclaration:
4966 P->PolishForDeclaration = Value;
4967 return;
4968 case CXPrintingPolicy_Half:
4969 P->Half = Value;
4970 return;
4971 case CXPrintingPolicy_MSWChar:
4972 P->MSWChar = Value;
4973 return;
4974 case CXPrintingPolicy_IncludeNewlines:
4975 P->IncludeNewlines = Value;
4976 return;
4977 case CXPrintingPolicy_MSVCFormatting:
4978 P->MSVCFormatting = Value;
4979 return;
4980 case CXPrintingPolicy_ConstantsAsWritten:
4981 P->ConstantsAsWritten = Value;
4982 return;
4983 case CXPrintingPolicy_SuppressImplicitBase:
4984 P->SuppressImplicitBase = Value;
4985 return;
4986 case CXPrintingPolicy_FullyQualifiedName:
4987 P->FullyQualifiedName = Value;
4988 return;
4989 }
4990
4991 assert(false && "Invalid CXPrintingPolicyProperty");
4992}
4993
4994CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
4995 if (clang_Cursor_isNull(C))
4996 return cxstring::createEmpty();
4997
4998 if (clang_isDeclaration(C.kind)) {
4999 const Decl *D = getCursorDecl(C);
5000 if (!D)
5001 return cxstring::createEmpty();
5002
5003 SmallString<128> Str;
5004 llvm::raw_svector_ostream OS(Str);
5005 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5006 D->print(OS, UserPolicy ? *UserPolicy
5007 : getCursorContext(C).getPrintingPolicy());
5008
5009 return cxstring::createDup(OS.str());
5010 }
5011
5012 return cxstring::createEmpty();
5013}
5014
Guy Benyei11169dd2012-12-18 14:30:41 +00005015CXString clang_getCursorDisplayName(CXCursor C) {
5016 if (!clang_isDeclaration(C.kind))
5017 return clang_getCursorSpelling(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05005018
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005019 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005021 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005022
5023 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005024 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005025 D = FunTmpl->getTemplatedDecl();
Michael Kruse7520cf02020-03-25 09:26:14 -05005026
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005027 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 SmallString<64> Str;
5029 llvm::raw_svector_ostream OS(Str);
5030 OS << *Function;
5031 if (Function->getPrimaryTemplate())
5032 OS << "<>";
5033 OS << "(";
5034 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5035 if (I)
5036 OS << ", ";
5037 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5038 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005039
Guy Benyei11169dd2012-12-18 14:30:41 +00005040 if (Function->isVariadic()) {
5041 if (Function->getNumParams())
5042 OS << ", ";
5043 OS << "...";
5044 }
5045 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005046 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005048
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005049 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 SmallString<64> Str;
5051 llvm::raw_svector_ostream OS(Str);
5052 OS << *ClassTemplate;
5053 OS << "<";
5054 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5055 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5056 if (I)
5057 OS << ", ";
Michael Kruse7520cf02020-03-25 09:26:14 -05005058
Guy Benyei11169dd2012-12-18 14:30:41 +00005059 NamedDecl *Param = Params->getParam(I);
5060 if (Param->getIdentifier()) {
5061 OS << Param->getIdentifier()->getName();
5062 continue;
5063 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005064
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 // There is no parameter name, which makes this tricky. Try to come up
5066 // with something useful that isn't too long.
5067 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
Saar Razff1e0fc2020-01-15 02:48:42 +02005068 if (const auto *TC = TTP->getTypeConstraint()) {
5069 TC->getConceptNameInfo().printName(OS, Policy);
5070 if (TC->hasExplicitTemplateArgs())
5071 OS << "<...>";
5072 } else
Michael Kruse7520cf02020-03-25 09:26:14 -05005073 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5074 else if (NonTypeTemplateParmDecl *NTTP =
5075 dyn_cast<NonTypeTemplateParmDecl>(Param))
Guy Benyei11169dd2012-12-18 14:30:41 +00005076 OS << NTTP->getType().getAsString(Policy);
5077 else
5078 OS << "template<...> class";
5079 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005080
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005082 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005084
5085 if (const ClassTemplateSpecializationDecl *ClassSpec =
5086 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 // If the type was explicitly written, use that.
5088 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005089 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Serge Pavlov03e672c2017-11-28 16:14:14 +00005090
Benjamin Kramer9170e912013-02-22 15:46:01 +00005091 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 llvm::raw_svector_ostream OS(Str);
5093 OS << *ClassSpec;
Serge Pavlov03e672c2017-11-28 16:14:14 +00005094 printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
5095 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005096 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005098
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 return clang_getCursorSpelling(C);
5100}
Michael Kruse7520cf02020-03-25 09:26:14 -05005101
Guy Benyei11169dd2012-12-18 14:30:41 +00005102CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5103 switch (Kind) {
5104 case CXCursor_FunctionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005105 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 case CXCursor_TypedefDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005107 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 case CXCursor_EnumDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005109 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 case CXCursor_EnumConstantDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005111 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 case CXCursor_StructDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005113 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 case CXCursor_UnionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005115 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005116 case CXCursor_ClassDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005117 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 case CXCursor_FieldDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005119 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 case CXCursor_VarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005121 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 case CXCursor_ParmDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005123 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005124 case CXCursor_ObjCInterfaceDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005125 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 case CXCursor_ObjCCategoryDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005127 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 case CXCursor_ObjCProtocolDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005129 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 case CXCursor_ObjCPropertyDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005131 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 case CXCursor_ObjCIvarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005133 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 case CXCursor_ObjCInstanceMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005135 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 case CXCursor_ObjCClassMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005137 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 case CXCursor_ObjCImplementationDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005139 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 case CXCursor_ObjCCategoryImplDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005141 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 case CXCursor_CXXMethod:
Michael Kruse7520cf02020-03-25 09:26:14 -05005143 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 case CXCursor_UnexposedDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005145 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005146 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005147 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 case CXCursor_ObjCProtocolRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005149 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 case CXCursor_ObjCClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005151 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 case CXCursor_TypeRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005153 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 case CXCursor_TemplateRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005155 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005157 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005159 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005161 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005163 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005165 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 case CXCursor_IntegerLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005167 return cxstring::createRef("IntegerLiteral");
Leonard Chandb01c3a2018-06-20 17:19:40 +00005168 case CXCursor_FixedPointLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005169 return cxstring::createRef("FixedPointLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 case CXCursor_FloatingLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005171 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 case CXCursor_ImaginaryLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005173 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 case CXCursor_StringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005175 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 case CXCursor_CharacterLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005177 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 case CXCursor_ParenExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005179 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 case CXCursor_UnaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005181 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 case CXCursor_ArraySubscriptExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005183 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00005184 case CXCursor_OMPArraySectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005185 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 case CXCursor_BinaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005187 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 case CXCursor_CompoundAssignOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005189 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 case CXCursor_ConditionalOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005191 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 case CXCursor_CStyleCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005193 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 case CXCursor_CompoundLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005195 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 case CXCursor_InitListExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005197 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 case CXCursor_AddrLabelExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005199 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 case CXCursor_StmtExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005201 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 case CXCursor_GenericSelectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005203 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 case CXCursor_GNUNullExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005205 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 case CXCursor_CXXStaticCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005207 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 case CXCursor_CXXDynamicCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005209 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 case CXCursor_CXXReinterpretCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005211 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 case CXCursor_CXXConstCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005213 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 case CXCursor_CXXFunctionalCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005215 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 case CXCursor_CXXTypeidExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005217 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 case CXCursor_CXXBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005219 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 case CXCursor_CXXNullPtrLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005221 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 case CXCursor_CXXThisExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005223 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 case CXCursor_CXXThrowExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005225 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 case CXCursor_CXXNewExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005227 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 case CXCursor_CXXDeleteExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005229 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 case CXCursor_UnaryExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005231 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 case CXCursor_ObjCStringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005233 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 case CXCursor_ObjCBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005235 return cxstring::createRef("ObjCBoolLiteralExpr");
Erik Pilkington29099de2016-07-16 00:35:23 +00005236 case CXCursor_ObjCAvailabilityCheckExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005237 return cxstring::createRef("ObjCAvailabilityCheckExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00005238 case CXCursor_ObjCSelfExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005239 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 case CXCursor_ObjCEncodeExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005241 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 case CXCursor_ObjCSelectorExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005243 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 case CXCursor_ObjCProtocolExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005245 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 case CXCursor_ObjCBridgedCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005247 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 case CXCursor_BlockExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005249 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 case CXCursor_PackExpansionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005251 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 case CXCursor_SizeOfPackExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005253 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005255 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 case CXCursor_UnexposedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005257 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 case CXCursor_DeclRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005259 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 case CXCursor_MemberRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005261 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005263 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 case CXCursor_ObjCMessageExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005265 return cxstring::createRef("ObjCMessageExpr");
Erik Pilkingtoneee944e2019-07-02 18:28:13 +00005266 case CXCursor_BuiltinBitCastExpr:
5267 return cxstring::createRef("BuiltinBitCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 case CXCursor_UnexposedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005269 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 case CXCursor_DeclStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005271 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 case CXCursor_LabelStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005273 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 case CXCursor_CompoundStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005275 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 case CXCursor_CaseStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005277 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 case CXCursor_DefaultStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005279 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 case CXCursor_IfStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005281 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 case CXCursor_SwitchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005283 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 case CXCursor_WhileStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005285 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 case CXCursor_DoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005287 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 case CXCursor_ForStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005289 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 case CXCursor_GotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005291 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 case CXCursor_IndirectGotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005293 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 case CXCursor_ContinueStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005295 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 case CXCursor_BreakStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005297 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 case CXCursor_ReturnStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005299 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 case CXCursor_GCCAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005301 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 case CXCursor_MSAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005303 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 case CXCursor_ObjCAtTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005305 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 case CXCursor_ObjCAtCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005307 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 case CXCursor_ObjCAtFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005309 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 case CXCursor_ObjCAtThrowStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005311 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 case CXCursor_ObjCAtSynchronizedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005313 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 case CXCursor_ObjCAutoreleasePoolStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005315 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 case CXCursor_ObjCForCollectionStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005317 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 case CXCursor_CXXCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005319 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 case CXCursor_CXXTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005321 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 case CXCursor_CXXForRangeStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005323 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 case CXCursor_SEHTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005325 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 case CXCursor_SEHExceptStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005327 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 case CXCursor_SEHFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005329 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00005330 case CXCursor_SEHLeaveStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005331 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 case CXCursor_NullStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005333 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 case CXCursor_InvalidFile:
Michael Kruse7520cf02020-03-25 09:26:14 -05005335 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005337 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 case CXCursor_NoDeclFound:
Michael Kruse7520cf02020-03-25 09:26:14 -05005339 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 case CXCursor_NotImplemented:
Michael Kruse7520cf02020-03-25 09:26:14 -05005341 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 case CXCursor_TranslationUnit:
Michael Kruse7520cf02020-03-25 09:26:14 -05005343 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 case CXCursor_UnexposedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005345 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 case CXCursor_IBActionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005347 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 case CXCursor_IBOutletAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005349 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 case CXCursor_IBOutletCollectionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005351 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 case CXCursor_CXXFinalAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005353 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 case CXCursor_CXXOverrideAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005355 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005357 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005359 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005360 case CXCursor_PackedAttr:
5361 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00005362 case CXCursor_PureAttr:
5363 return cxstring::createRef("attribute(pure)");
5364 case CXCursor_ConstAttr:
5365 return cxstring::createRef("attribute(const)");
5366 case CXCursor_NoDuplicateAttr:
5367 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00005368 case CXCursor_CUDAConstantAttr:
5369 return cxstring::createRef("attribute(constant)");
5370 case CXCursor_CUDADeviceAttr:
5371 return cxstring::createRef("attribute(device)");
5372 case CXCursor_CUDAGlobalAttr:
5373 return cxstring::createRef("attribute(global)");
5374 case CXCursor_CUDAHostAttr:
5375 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00005376 case CXCursor_CUDASharedAttr:
5377 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00005378 case CXCursor_VisibilityAttr:
5379 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00005380 case CXCursor_DLLExport:
5381 return cxstring::createRef("attribute(dllexport)");
5382 case CXCursor_DLLImport:
5383 return cxstring::createRef("attribute(dllimport)");
Michael Wud092d0b2018-08-03 05:03:22 +00005384 case CXCursor_NSReturnsRetained:
5385 return cxstring::createRef("attribute(ns_returns_retained)");
5386 case CXCursor_NSReturnsNotRetained:
5387 return cxstring::createRef("attribute(ns_returns_not_retained)");
5388 case CXCursor_NSReturnsAutoreleased:
5389 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5390 case CXCursor_NSConsumesSelf:
5391 return cxstring::createRef("attribute(ns_consumes_self)");
5392 case CXCursor_NSConsumed:
5393 return cxstring::createRef("attribute(ns_consumed)");
5394 case CXCursor_ObjCException:
5395 return cxstring::createRef("attribute(objc_exception)");
5396 case CXCursor_ObjCNSObject:
5397 return cxstring::createRef("attribute(NSObject)");
5398 case CXCursor_ObjCIndependentClass:
5399 return cxstring::createRef("attribute(objc_independent_class)");
5400 case CXCursor_ObjCPreciseLifetime:
5401 return cxstring::createRef("attribute(objc_precise_lifetime)");
5402 case CXCursor_ObjCReturnsInnerPointer:
5403 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5404 case CXCursor_ObjCRequiresSuper:
5405 return cxstring::createRef("attribute(objc_requires_super)");
5406 case CXCursor_ObjCRootClass:
5407 return cxstring::createRef("attribute(objc_root_class)");
5408 case CXCursor_ObjCSubclassingRestricted:
5409 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5410 case CXCursor_ObjCExplicitProtocolImpl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005411 return cxstring::createRef(
5412 "attribute(objc_protocol_requires_explicit_implementation)");
Michael Wud092d0b2018-08-03 05:03:22 +00005413 case CXCursor_ObjCDesignatedInitializer:
5414 return cxstring::createRef("attribute(objc_designated_initializer)");
5415 case CXCursor_ObjCRuntimeVisible:
5416 return cxstring::createRef("attribute(objc_runtime_visible)");
5417 case CXCursor_ObjCBoxable:
5418 return cxstring::createRef("attribute(objc_boxable)");
Michael Wu58d837d2018-08-03 05:55:40 +00005419 case CXCursor_FlagEnum:
5420 return cxstring::createRef("attribute(flag_enum)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005421 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005422 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005424 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00005425 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005426 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005427 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005428 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005430 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005432 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005434 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005436 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005438 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005440 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005442 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005444 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005446 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005448 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005450 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005452 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005454 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005456 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005458 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005460 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005462 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005464 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005466 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005468 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005469 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00005470 return cxstring::createRef("OMPParallelDirective");
5471 case CXCursor_OMPSimdDirective:
5472 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00005473 case CXCursor_OMPForDirective:
5474 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00005475 case CXCursor_OMPForSimdDirective:
5476 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00005477 case CXCursor_OMPSectionsDirective:
5478 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00005479 case CXCursor_OMPSectionDirective:
5480 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00005481 case CXCursor_OMPSingleDirective:
5482 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00005483 case CXCursor_OMPMasterDirective:
5484 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00005485 case CXCursor_OMPCriticalDirective:
5486 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00005487 case CXCursor_OMPParallelForDirective:
5488 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00005489 case CXCursor_OMPParallelForSimdDirective:
5490 return cxstring::createRef("OMPParallelForSimdDirective");
cchen47d60942019-12-05 13:43:48 -05005491 case CXCursor_OMPParallelMasterDirective:
5492 return cxstring::createRef("OMPParallelMasterDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00005493 case CXCursor_OMPParallelSectionsDirective:
5494 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00005495 case CXCursor_OMPTaskDirective:
5496 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00005497 case CXCursor_OMPTaskyieldDirective:
5498 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00005499 case CXCursor_OMPBarrierDirective:
5500 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00005501 case CXCursor_OMPTaskwaitDirective:
5502 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00005503 case CXCursor_OMPTaskgroupDirective:
5504 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00005505 case CXCursor_OMPFlushDirective:
5506 return cxstring::createRef("OMPFlushDirective");
Alexey Bataevc112e942020-02-28 09:52:15 -05005507 case CXCursor_OMPDepobjDirective:
5508 return cxstring::createRef("OMPDepobjDirective");
Alexey Bataevfcba7c32020-03-20 07:03:01 -04005509 case CXCursor_OMPScanDirective:
5510 return cxstring::createRef("OMPScanDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00005511 case CXCursor_OMPOrderedDirective:
5512 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00005513 case CXCursor_OMPAtomicDirective:
5514 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00005515 case CXCursor_OMPTargetDirective:
5516 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00005517 case CXCursor_OMPTargetDataDirective:
5518 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00005519 case CXCursor_OMPTargetEnterDataDirective:
5520 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00005521 case CXCursor_OMPTargetExitDataDirective:
5522 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00005523 case CXCursor_OMPTargetParallelDirective:
5524 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00005525 case CXCursor_OMPTargetParallelForDirective:
5526 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00005527 case CXCursor_OMPTargetUpdateDirective:
5528 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00005529 case CXCursor_OMPTeamsDirective:
5530 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00005531 case CXCursor_OMPCancellationPointDirective:
5532 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00005533 case CXCursor_OMPCancelDirective:
5534 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00005535 case CXCursor_OMPTaskLoopDirective:
5536 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005537 case CXCursor_OMPTaskLoopSimdDirective:
5538 return cxstring::createRef("OMPTaskLoopSimdDirective");
Alexey Bataev60e51c42019-10-10 20:13:02 +00005539 case CXCursor_OMPMasterTaskLoopDirective:
5540 return cxstring::createRef("OMPMasterTaskLoopDirective");
Alexey Bataevb8552ab2019-10-18 16:47:35 +00005541 case CXCursor_OMPMasterTaskLoopSimdDirective:
5542 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
Alexey Bataev5bbcead2019-10-14 17:17:41 +00005543 case CXCursor_OMPParallelMasterTaskLoopDirective:
5544 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
Alexey Bataev14a388f2019-10-25 10:27:13 -04005545 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5546 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00005547 case CXCursor_OMPDistributeDirective:
5548 return cxstring::createRef("OMPDistributeDirective");
Carlo Bertolli9925f152016-06-27 14:55:37 +00005549 case CXCursor_OMPDistributeParallelForDirective:
5550 return cxstring::createRef("OMPDistributeParallelForDirective");
Kelvin Li4a39add2016-07-05 05:00:15 +00005551 case CXCursor_OMPDistributeParallelForSimdDirective:
5552 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
Kelvin Li787f3fc2016-07-06 04:45:38 +00005553 case CXCursor_OMPDistributeSimdDirective:
5554 return cxstring::createRef("OMPDistributeSimdDirective");
Kelvin Lia579b912016-07-14 02:54:56 +00005555 case CXCursor_OMPTargetParallelForSimdDirective:
5556 return cxstring::createRef("OMPTargetParallelForSimdDirective");
Kelvin Li986330c2016-07-20 22:57:10 +00005557 case CXCursor_OMPTargetSimdDirective:
5558 return cxstring::createRef("OMPTargetSimdDirective");
Kelvin Li02532872016-08-05 14:37:37 +00005559 case CXCursor_OMPTeamsDistributeDirective:
5560 return cxstring::createRef("OMPTeamsDistributeDirective");
Kelvin Li4e325f72016-10-25 12:50:55 +00005561 case CXCursor_OMPTeamsDistributeSimdDirective:
5562 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
Kelvin Li579e41c2016-11-30 23:51:03 +00005563 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5564 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
Kelvin Li7ade93f2016-12-09 03:24:30 +00005565 case CXCursor_OMPTeamsDistributeParallelForDirective:
5566 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
Kelvin Libf594a52016-12-17 05:48:59 +00005567 case CXCursor_OMPTargetTeamsDirective:
5568 return cxstring::createRef("OMPTargetTeamsDirective");
Kelvin Li83c451e2016-12-25 04:52:54 +00005569 case CXCursor_OMPTargetTeamsDistributeDirective:
5570 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
Kelvin Li80e8f562016-12-29 22:16:30 +00005571 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5572 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
Kelvin Li1851df52017-01-03 05:23:48 +00005573 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5574 return cxstring::createRef(
5575 "OMPTargetTeamsDistributeParallelForSimdDirective");
Kelvin Lida681182017-01-10 18:08:18 +00005576 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5577 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00005578 case CXCursor_OverloadCandidate:
Michael Kruse7520cf02020-03-25 09:26:14 -05005579 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00005580 case CXCursor_TypeAliasTemplateDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005581 return cxstring::createRef("TypeAliasTemplateDecl");
Olivier Goffart81978012016-06-09 16:15:55 +00005582 case CXCursor_StaticAssert:
Michael Kruse7520cf02020-03-25 09:26:14 -05005583 return cxstring::createRef("StaticAssert");
Olivier Goffartd211c642016-11-04 06:29:27 +00005584 case CXCursor_FriendDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005585 return cxstring::createRef("FriendDecl");
Sven van Haastregtdc2c9302019-02-11 11:00:56 +00005586 case CXCursor_ConvergentAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005587 return cxstring::createRef("attribute(convergent)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005588 case CXCursor_WarnUnusedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005589 return cxstring::createRef("attribute(warn_unused)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005590 case CXCursor_WarnUnusedResultAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005591 return cxstring::createRef("attribute(warn_unused_result)");
Emilio Cobos Alvarezcd741272019-03-13 16:16:54 +00005592 case CXCursor_AlignedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005593 return cxstring::createRef("attribute(aligned)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005594 }
5595
5596 llvm_unreachable("Unhandled CXCursorKind");
5597}
5598
5599struct GetCursorData {
5600 SourceLocation TokenBeginLoc;
5601 bool PointsAtMacroArgExpansion;
5602 bool VisitedObjCPropertyImplDecl;
5603 SourceLocation VisitedDeclaratorDeclStartLoc;
5604 CXCursor &BestCursor;
5605
Michael Kruse7520cf02020-03-25 09:26:14 -05005606 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5607 CXCursor &outputCursor)
5608 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5610 VisitedObjCPropertyImplDecl = false;
5611 }
5612};
5613
Michael Kruse7520cf02020-03-25 09:26:14 -05005614static enum CXChildVisitResult
5615GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005616 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5617 CXCursor *BestCursor = &Data->BestCursor;
5618
5619 // If we point inside a macro argument we should provide info of what the
5620 // token is so use the actual cursor, don't replace it with a macro expansion
5621 // cursor.
5622 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5623 return CXChildVisit_Recurse;
Michael Kruse7520cf02020-03-25 09:26:14 -05005624
Guy Benyei11169dd2012-12-18 14:30:41 +00005625 if (clang_isDeclaration(cursor.kind)) {
5626 // Avoid having the implicit methods override the property decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05005627 if (const ObjCMethodDecl *MD =
5628 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005629 if (MD->isImplicit())
5630 return CXChildVisit_Break;
5631
Michael Kruse7520cf02020-03-25 09:26:14 -05005632 } else if (const ObjCInterfaceDecl *ID =
5633 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 // Check that when we have multiple @class references in the same line,
5635 // that later ones do not override the previous ones.
5636 // If we have:
5637 // @class Foo, Bar;
5638 // source ranges for both start at '@', so 'Bar' will end up overriding
5639 // 'Foo' even though the cursor location was at 'Foo'.
5640 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5641 BestCursor->kind == CXCursor_ObjCClassRef)
Michael Kruse7520cf02020-03-25 09:26:14 -05005642 if (const ObjCInterfaceDecl *PrevID =
5643 dyn_cast_or_null<ObjCInterfaceDecl>(
5644 getCursorDecl(*BestCursor))) {
5645 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5646 !ID->isThisDeclarationADefinition())
5647 return CXChildVisit_Break;
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 }
5649
Michael Kruse7520cf02020-03-25 09:26:14 -05005650 } else if (const DeclaratorDecl *DD =
5651 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5653 // Check that when we have multiple declarators in the same line,
5654 // that later ones do not override the previous ones.
5655 // If we have:
5656 // int Foo, Bar;
5657 // source ranges for both start at 'int', so 'Bar' will end up overriding
5658 // 'Foo' even though the cursor location was at 'Foo'.
5659 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5660 return CXChildVisit_Break;
5661 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5662
Michael Kruse7520cf02020-03-25 09:26:14 -05005663 } else if (const ObjCPropertyImplDecl *PropImp =
5664 dyn_cast_or_null<ObjCPropertyImplDecl>(
5665 getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005666 (void)PropImp;
5667 // Check that when we have multiple @synthesize in the same line,
5668 // that later ones do not override the previous ones.
5669 // If we have:
5670 // @synthesize Foo, Bar;
5671 // source ranges for both start at '@', so 'Bar' will end up overriding
5672 // 'Foo' even though the cursor location was at 'Foo'.
5673 if (Data->VisitedObjCPropertyImplDecl)
5674 return CXChildVisit_Break;
5675 Data->VisitedObjCPropertyImplDecl = true;
5676 }
5677 }
5678
5679 if (clang_isExpression(cursor.kind) &&
5680 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005681 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005682 // Avoid having the cursor of an expression replace the declaration cursor
5683 // when the expression source range overlaps the declaration range.
5684 // This can happen for C++ constructor expressions whose range generally
5685 // include the variable declaration, e.g.:
Michael Kruse7520cf02020-03-25 09:26:14 -05005686 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5687 // cursor.
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5689 D->getLocation() == Data->TokenBeginLoc)
5690 return CXChildVisit_Break;
5691 }
5692 }
5693
Michael Kruse7520cf02020-03-25 09:26:14 -05005694 // If our current best cursor is the construction of a temporary object,
5695 // don't replace that cursor with a type reference, because we want
Guy Benyei11169dd2012-12-18 14:30:41 +00005696 // clang_getCursor() to point at the constructor.
5697 if (clang_isExpression(BestCursor->kind) &&
5698 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5699 cursor.kind == CXCursor_TypeRef) {
5700 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5701 // as having the actual point on the type reference.
5702 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5703 return CXChildVisit_Recurse;
5704 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005705
5706 // If we already have an Objective-C superclass reference, don't
5707 // update it further.
5708 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5709 return CXChildVisit_Break;
5710
Guy Benyei11169dd2012-12-18 14:30:41 +00005711 *BestCursor = cursor;
5712 return CXChildVisit_Recurse;
5713}
5714
5715CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005716 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005717 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005718 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005719 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005720
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005721 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5723
5724 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5725 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5726
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005727 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005728 CXFile SearchFile;
5729 unsigned SearchLine, SearchColumn;
5730 CXFile ResultFile;
5731 unsigned ResultLine, ResultColumn;
5732 CXString SearchFileName, ResultFileName, KindSpelling, USR;
Michael Kruse7520cf02020-03-25 09:26:14 -05005733 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005735
5736 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5737 nullptr);
Michael Kruse7520cf02020-03-25 09:26:14 -05005738 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5739 nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 SearchFileName = clang_getFileName(SearchFile);
5741 ResultFileName = clang_getFileName(ResultFile);
5742 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5743 USR = clang_getCursorUSR(Result);
Michael Kruse7520cf02020-03-25 09:26:14 -05005744 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5745 SearchLine, SearchColumn,
5746 clang_getCString(KindSpelling))
5747 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5748 ResultLine, ResultColumn, clang_getCString(USR),
5749 IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 clang_disposeString(SearchFileName);
5751 clang_disposeString(ResultFileName);
5752 clang_disposeString(KindSpelling);
5753 clang_disposeString(USR);
Michael Kruse7520cf02020-03-25 09:26:14 -05005754
Guy Benyei11169dd2012-12-18 14:30:41 +00005755 CXCursor Definition = clang_getCursorDefinition(Result);
5756 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5757 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
Michael Kruse7520cf02020-03-25 09:26:14 -05005758 CXString DefinitionKindSpelling =
5759 clang_getCursorKindSpelling(Definition.kind);
Guy Benyei11169dd2012-12-18 14:30:41 +00005760 CXFile DefinitionFile;
5761 unsigned DefinitionLine, DefinitionColumn;
Michael Kruse7520cf02020-03-25 09:26:14 -05005762 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5763 &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005765 *Log << llvm::format(" -> %s(%s:%d:%d)",
Michael Kruse7520cf02020-03-25 09:26:14 -05005766 clang_getCString(DefinitionKindSpelling),
5767 clang_getCString(DefinitionFileName), DefinitionLine,
5768 DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005769 clang_disposeString(DefinitionFileName);
5770 clang_disposeString(DefinitionKindSpelling);
5771 }
5772 }
5773
5774 return Result;
5775}
5776
5777CXCursor clang_getNullCursor(void) {
5778 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5779}
5780
5781unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005782 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5783 // can't set consistently. For example, when visiting a DeclStmt we will set
5784 // it but we don't set it on the result of clang_getCursorDefinition for
5785 // a reference of the same declaration.
5786 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5787 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5788 // to provide that kind of info.
5789 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005790 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005791 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005792 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005793
Guy Benyei11169dd2012-12-18 14:30:41 +00005794 return X == Y;
5795}
5796
5797unsigned clang_hashCursor(CXCursor C) {
5798 unsigned Index = 0;
5799 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5800 Index = 1;
Michael Kruse7520cf02020-03-25 09:26:14 -05005801
5802 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5803 std::make_pair(C.kind, C.data[Index]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005804}
5805
5806unsigned clang_isInvalid(enum CXCursorKind K) {
5807 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5808}
5809
5810unsigned clang_isDeclaration(enum CXCursorKind K) {
5811 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005812 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5813}
5814
Ivan Donchevskii08ff9102018-01-04 10:59:50 +00005815unsigned clang_isInvalidDeclaration(CXCursor C) {
5816 if (clang_isDeclaration(C.kind)) {
5817 if (const Decl *D = getCursorDecl(C))
5818 return D->isInvalidDecl();
5819 }
5820
5821 return 0;
5822}
5823
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005824unsigned clang_isReference(enum CXCursorKind K) {
5825 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5826}
Guy Benyei11169dd2012-12-18 14:30:41 +00005827
5828unsigned clang_isExpression(enum CXCursorKind K) {
5829 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5830}
5831
5832unsigned clang_isStatement(enum CXCursorKind K) {
5833 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5834}
5835
5836unsigned clang_isAttribute(enum CXCursorKind K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005837 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005838}
5839
5840unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5841 return K == CXCursor_TranslationUnit;
5842}
5843
5844unsigned clang_isPreprocessing(enum CXCursorKind K) {
5845 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5846}
Michael Kruse7520cf02020-03-25 09:26:14 -05005847
Guy Benyei11169dd2012-12-18 14:30:41 +00005848unsigned clang_isUnexposed(enum CXCursorKind K) {
5849 switch (K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005850 case CXCursor_UnexposedDecl:
5851 case CXCursor_UnexposedExpr:
5852 case CXCursor_UnexposedStmt:
5853 case CXCursor_UnexposedAttr:
5854 return true;
5855 default:
5856 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005857 }
5858}
5859
Michael Kruse7520cf02020-03-25 09:26:14 -05005860CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005861
5862CXSourceLocation clang_getCursorLocation(CXCursor C) {
5863 if (clang_isReference(C.kind)) {
5864 switch (C.kind) {
5865 case CXCursor_ObjCSuperClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005866 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5867 getCursorObjCSuperClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005868 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5869 }
5870
5871 case CXCursor_ObjCProtocolRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005872 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5873 getCursorObjCProtocolRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005874 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5875 }
5876
5877 case CXCursor_ObjCClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005878 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5879 getCursorObjCClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005880 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5881 }
5882
5883 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005884 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5886 }
5887
5888 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005889 std::pair<const TemplateDecl *, SourceLocation> P =
5890 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5892 }
5893
5894 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005895 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005896 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5897 }
5898
5899 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005900 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5902 }
5903
5904 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005905 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005906 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5907 }
5908
5909 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005910 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005911 if (!BaseSpec)
5912 return clang_getNullLocation();
Michael Kruse7520cf02020-03-25 09:26:14 -05005913
Guy Benyei11169dd2012-12-18 14:30:41 +00005914 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
Michael Kruse7520cf02020-03-25 09:26:14 -05005915 return cxloc::translateSourceLocation(
5916 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005917
Guy Benyei11169dd2012-12-18 14:30:41 +00005918 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005919 BaseSpec->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005920 }
5921
5922 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005923 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5925 }
5926
5927 case CXCursor_OverloadedDeclRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005928 return cxloc::translateSourceLocation(
5929 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
Guy Benyei11169dd2012-12-18 14:30:41 +00005930
5931 default:
5932 // FIXME: Need a way to enumerate all non-reference cases.
5933 llvm_unreachable("Missed a reference kind");
5934 }
5935 }
5936
5937 if (clang_isExpression(C.kind))
Michael Kruse7520cf02020-03-25 09:26:14 -05005938 return cxloc::translateSourceLocation(
5939 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
Guy Benyei11169dd2012-12-18 14:30:41 +00005940
5941 if (clang_isStatement(C.kind))
5942 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005943 getCursorStmt(C)->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005944
5945 if (C.kind == CXCursor_PreprocessingDirective) {
5946 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5947 return cxloc::translateSourceLocation(getCursorContext(C), L);
5948 }
5949
5950 if (C.kind == CXCursor_MacroExpansion) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005951 SourceLocation L =
5952 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005953 return cxloc::translateSourceLocation(getCursorContext(C), L);
5954 }
5955
5956 if (C.kind == CXCursor_MacroDefinition) {
5957 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
5958 return cxloc::translateSourceLocation(getCursorContext(C), L);
5959 }
5960
5961 if (C.kind == CXCursor_InclusionDirective) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005962 SourceLocation L =
5963 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00005964 return cxloc::translateSourceLocation(getCursorContext(C), L);
5965 }
5966
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005967 if (clang_isAttribute(C.kind)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005968 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005969 return cxloc::translateSourceLocation(getCursorContext(C), L);
5970 }
5971
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 if (!clang_isDeclaration(C.kind))
5973 return clang_getNullLocation();
5974
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005975 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 if (!D)
5977 return clang_getNullLocation();
5978
5979 SourceLocation Loc = D->getLocation();
5980 // FIXME: Multiple variables declared in a single declaration
5981 // currently lack the information needed to correctly determine their
5982 // ranges when accounting for the type-specifier. We use context
5983 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
5984 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005985 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005986 if (!cxcursor::isFirstInDeclGroup(C))
5987 Loc = VD->getLocation();
5988 }
5989
5990 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005991 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005992 Loc = MD->getSelectorStartLoc();
5993
5994 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
5995}
5996
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00005997} // end extern "C"
5998
Guy Benyei11169dd2012-12-18 14:30:41 +00005999CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6000 assert(TU);
6001
6002 // Guard against an invalid SourceLocation, or we may assert in one
6003 // of the following calls.
6004 if (SLoc.isInvalid())
6005 return clang_getNullCursor();
6006
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006007 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006008
6009 // Translate the given source location to make it point at the beginning of
6010 // the token under the cursor.
6011 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6012 CXXUnit->getASTContext().getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05006013
Guy Benyei11169dd2012-12-18 14:30:41 +00006014 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6015 if (SLoc.isValid()) {
6016 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6017 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Michael Kruse7520cf02020-03-25 09:26:14 -05006018 /*VisitPreprocessorLast=*/true,
Guy Benyei11169dd2012-12-18 14:30:41 +00006019 /*VisitIncludedEntities=*/false,
6020 SourceLocation(SLoc));
6021 CursorVis.visitFileRegion();
6022 }
6023
6024 return Result;
6025}
6026
6027static SourceRange getRawCursorExtent(CXCursor C) {
6028 if (clang_isReference(C.kind)) {
6029 switch (C.kind) {
6030 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05006031 return getCursorObjCSuperClassRef(C).second;
Guy Benyei11169dd2012-12-18 14:30:41 +00006032
6033 case CXCursor_ObjCProtocolRef:
6034 return getCursorObjCProtocolRef(C).second;
6035
6036 case CXCursor_ObjCClassRef:
6037 return getCursorObjCClassRef(C).second;
6038
6039 case CXCursor_TypeRef:
6040 return getCursorTypeRef(C).second;
6041
6042 case CXCursor_TemplateRef:
6043 return getCursorTemplateRef(C).second;
6044
6045 case CXCursor_NamespaceRef:
6046 return getCursorNamespaceRef(C).second;
6047
6048 case CXCursor_MemberRef:
6049 return getCursorMemberRef(C).second;
6050
6051 case CXCursor_CXXBaseSpecifier:
6052 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6053
6054 case CXCursor_LabelRef:
6055 return getCursorLabelRef(C).second;
6056
6057 case CXCursor_OverloadedDeclRef:
6058 return getCursorOverloadedDeclRef(C).second;
6059
6060 case CXCursor_VariableRef:
6061 return getCursorVariableRef(C).second;
Michael Kruse7520cf02020-03-25 09:26:14 -05006062
Guy Benyei11169dd2012-12-18 14:30:41 +00006063 default:
6064 // FIXME: Need a way to enumerate all non-reference cases.
6065 llvm_unreachable("Missed a reference kind");
6066 }
6067 }
6068
6069 if (clang_isExpression(C.kind))
6070 return getCursorExpr(C)->getSourceRange();
6071
6072 if (clang_isStatement(C.kind))
6073 return getCursorStmt(C)->getSourceRange();
6074
6075 if (clang_isAttribute(C.kind))
6076 return getCursorAttr(C)->getRange();
6077
6078 if (C.kind == CXCursor_PreprocessingDirective)
6079 return cxcursor::getCursorPreprocessingDirective(C);
6080
6081 if (C.kind == CXCursor_MacroExpansion) {
6082 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006083 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006084 return TU->mapRangeFromPreamble(Range);
6085 }
6086
6087 if (C.kind == CXCursor_MacroDefinition) {
6088 ASTUnit *TU = getCursorASTUnit(C);
6089 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6090 return TU->mapRangeFromPreamble(Range);
6091 }
6092
6093 if (C.kind == CXCursor_InclusionDirective) {
6094 ASTUnit *TU = getCursorASTUnit(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05006095 SourceRange Range =
6096 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006097 return TU->mapRangeFromPreamble(Range);
6098 }
6099
6100 if (C.kind == CXCursor_TranslationUnit) {
6101 ASTUnit *TU = getCursorASTUnit(C);
6102 FileID MainID = TU->getSourceManager().getMainFileID();
6103 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6104 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6105 return SourceRange(Start, End);
6106 }
6107
6108 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006109 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006110 if (!D)
6111 return SourceRange();
6112
6113 SourceRange R = D->getSourceRange();
6114 // FIXME: Multiple variables declared in a single declaration
6115 // currently lack the information needed to correctly determine their
6116 // ranges when accounting for the type-specifier. We use context
6117 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6118 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006119 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006120 if (!cxcursor::isFirstInDeclGroup(C))
6121 R.setBegin(VD->getLocation());
6122 }
6123 return R;
6124 }
6125 return SourceRange();
6126}
6127
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006128/// Retrieves the "raw" cursor extent, which is then extended to include
Guy Benyei11169dd2012-12-18 14:30:41 +00006129/// the decl-specifier-seq for declarations.
6130static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6131 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006132 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006133 if (!D)
6134 return SourceRange();
6135
6136 SourceRange R = D->getSourceRange();
6137
6138 // Adjust the start of the location for declarations preceded by
6139 // declaration specifiers.
6140 SourceLocation StartLoc;
6141 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6142 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006143 StartLoc = TI->getTypeLoc().getBeginLoc();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006144 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006146 StartLoc = TI->getTypeLoc().getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 }
6148
6149 if (StartLoc.isValid() && R.getBegin().isValid() &&
6150 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6151 R.setBegin(StartLoc);
6152
6153 // FIXME: Multiple variables declared in a single declaration
6154 // currently lack the information needed to correctly determine their
6155 // ranges when accounting for the type-specifier. We use context
6156 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6157 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006158 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006159 if (!cxcursor::isFirstInDeclGroup(C))
6160 R.setBegin(VD->getLocation());
6161 }
6162
Michael Kruse7520cf02020-03-25 09:26:14 -05006163 return R;
Guy Benyei11169dd2012-12-18 14:30:41 +00006164 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006165
Guy Benyei11169dd2012-12-18 14:30:41 +00006166 return getRawCursorExtent(C);
6167}
6168
Guy Benyei11169dd2012-12-18 14:30:41 +00006169CXSourceRange clang_getCursorExtent(CXCursor C) {
6170 SourceRange R = getRawCursorExtent(C);
6171 if (R.isInvalid())
6172 return clang_getNullRange();
6173
6174 return cxloc::translateSourceRange(getCursorContext(C), R);
6175}
6176
6177CXCursor clang_getCursorReferenced(CXCursor C) {
6178 if (clang_isInvalid(C.kind))
6179 return clang_getNullCursor();
6180
6181 CXTranslationUnit tu = getCursorTU(C);
6182 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006183 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006184 if (!D)
6185 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006186 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006187 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006188 if (const ObjCPropertyImplDecl *PropImpl =
6189 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6191 return MakeCXCursor(Property, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006192
Guy Benyei11169dd2012-12-18 14:30:41 +00006193 return C;
6194 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006195
Guy Benyei11169dd2012-12-18 14:30:41 +00006196 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006197 const Expr *E = getCursorExpr(C);
6198 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00006199 if (D) {
6200 CXCursor declCursor = MakeCXCursor(D, tu);
6201 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6202 declCursor);
6203 return declCursor;
6204 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006205
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006206 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00006207 return MakeCursorOverloadedDeclRef(Ovl, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006208
Guy Benyei11169dd2012-12-18 14:30:41 +00006209 return clang_getNullCursor();
6210 }
6211
6212 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006213 const Stmt *S = getCursorStmt(C);
6214 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00006215 if (LabelDecl *label = Goto->getLabel())
6216 if (LabelStmt *labelS = label->getStmt())
Michael Kruse7520cf02020-03-25 09:26:14 -05006217 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006218
6219 return clang_getNullCursor();
6220 }
Richard Smith66a81862015-05-04 02:25:31 +00006221
Guy Benyei11169dd2012-12-18 14:30:41 +00006222 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00006223 if (const MacroDefinitionRecord *Def =
6224 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006225 return MakeMacroDefinitionCursor(Def, tu);
6226 }
6227
6228 if (!clang_isReference(C.kind))
6229 return clang_getNullCursor();
6230
6231 switch (C.kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006232 case CXCursor_ObjCSuperClassRef:
6233 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006234
Michael Kruse7520cf02020-03-25 09:26:14 -05006235 case CXCursor_ObjCProtocolRef: {
6236 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6237 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6238 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006239
Michael Kruse7520cf02020-03-25 09:26:14 -05006240 return MakeCXCursor(Prot, tu);
6241 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006242
Michael Kruse7520cf02020-03-25 09:26:14 -05006243 case CXCursor_ObjCClassRef: {
6244 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6245 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6246 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006247
Michael Kruse7520cf02020-03-25 09:26:14 -05006248 return MakeCXCursor(Class, tu);
6249 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006250
Michael Kruse7520cf02020-03-25 09:26:14 -05006251 case CXCursor_TypeRef:
6252 return MakeCXCursor(getCursorTypeRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006253
Michael Kruse7520cf02020-03-25 09:26:14 -05006254 case CXCursor_TemplateRef:
6255 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006256
Michael Kruse7520cf02020-03-25 09:26:14 -05006257 case CXCursor_NamespaceRef:
6258 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006259
Michael Kruse7520cf02020-03-25 09:26:14 -05006260 case CXCursor_MemberRef:
6261 return MakeCXCursor(getCursorMemberRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006262
Michael Kruse7520cf02020-03-25 09:26:14 -05006263 case CXCursor_CXXBaseSpecifier: {
6264 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6265 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6266 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006267
Michael Kruse7520cf02020-03-25 09:26:14 -05006268 case CXCursor_LabelRef:
6269 // FIXME: We end up faking the "parent" declaration here because we
6270 // don't want to make CXCursor larger.
6271 return MakeCXCursor(
6272 getCursorLabelRef(C).first,
6273 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006274
Michael Kruse7520cf02020-03-25 09:26:14 -05006275 case CXCursor_OverloadedDeclRef:
6276 return C;
Guy Benyei11169dd2012-12-18 14:30:41 +00006277
Michael Kruse7520cf02020-03-25 09:26:14 -05006278 case CXCursor_VariableRef:
6279 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6280
6281 default:
6282 // We would prefer to enumerate all non-reference cursor kinds here.
6283 llvm_unreachable("Unhandled reference cursor kind");
Guy Benyei11169dd2012-12-18 14:30:41 +00006284 }
6285}
6286
6287CXCursor clang_getCursorDefinition(CXCursor C) {
6288 if (clang_isInvalid(C.kind))
6289 return clang_getNullCursor();
6290
6291 CXTranslationUnit TU = getCursorTU(C);
6292
6293 bool WasReference = false;
6294 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6295 C = clang_getCursorReferenced(C);
6296 WasReference = true;
6297 }
6298
6299 if (C.kind == CXCursor_MacroExpansion)
6300 return clang_getCursorReferenced(C);
6301
6302 if (!clang_isDeclaration(C.kind))
6303 return clang_getNullCursor();
6304
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006305 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006306 if (!D)
6307 return clang_getNullCursor();
6308
6309 switch (D->getKind()) {
6310 // Declaration kinds that don't really separate the notions of
6311 // declaration and definition.
6312 case Decl::Namespace:
6313 case Decl::Typedef:
6314 case Decl::TypeAlias:
6315 case Decl::TypeAliasTemplate:
6316 case Decl::TemplateTypeParm:
6317 case Decl::EnumConstant:
6318 case Decl::Field:
Richard Smithbdb84f32016-07-22 23:36:59 +00006319 case Decl::Binding:
John McCall5e77d762013-04-16 07:28:30 +00006320 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006321 case Decl::IndirectField:
6322 case Decl::ObjCIvar:
6323 case Decl::ObjCAtDefsField:
6324 case Decl::ImplicitParam:
6325 case Decl::ParmVar:
6326 case Decl::NonTypeTemplateParm:
6327 case Decl::TemplateTemplateParm:
6328 case Decl::ObjCCategoryImpl:
6329 case Decl::ObjCImplementation:
6330 case Decl::AccessSpec:
6331 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006332 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006333 case Decl::ObjCPropertyImpl:
6334 case Decl::FileScopeAsm:
6335 case Decl::StaticAssert:
6336 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006337 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006338 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006339 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006340 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006341 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006342 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006343 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006344 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006345 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006346 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006347 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006348 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006349 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006350 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006351 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006352 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006353 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006354 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006355 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006356 return C;
6357
6358 // Declaration kinds that don't make any sense here, but are
6359 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006360 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006361 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006362 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006363 break;
6364
6365 // Declaration kinds for which the definition is not resolvable.
6366 case Decl::UnresolvedUsingTypename:
6367 case Decl::UnresolvedUsingValue:
6368 break;
6369
6370 case Decl::UsingDirective:
6371 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6372 TU);
6373
6374 case Decl::NamespaceAlias:
6375 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6376
6377 case Decl::Enum:
6378 case Decl::Record:
6379 case Decl::CXXRecord:
6380 case Decl::ClassTemplateSpecialization:
6381 case Decl::ClassTemplatePartialSpecialization:
6382 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6383 return MakeCXCursor(Def, TU);
6384 return clang_getNullCursor();
6385
6386 case Decl::Function:
6387 case Decl::CXXMethod:
6388 case Decl::CXXConstructor:
6389 case Decl::CXXDestructor:
6390 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006391 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006392 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006393 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006394 return clang_getNullCursor();
6395 }
6396
Larisse Voufo39a1e502013-08-06 01:03:05 +00006397 case Decl::Var:
6398 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006399 case Decl::VarTemplatePartialSpecialization:
6400 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006401 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006402 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006403 return MakeCXCursor(Def, TU);
6404 return clang_getNullCursor();
6405 }
6406
6407 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006408 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006409 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6410 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6411 return clang_getNullCursor();
6412 }
6413
6414 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006415 if (RecordDecl *Def =
6416 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006417 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6418 TU);
6419 return clang_getNullCursor();
6420 }
6421
Larisse Voufo39a1e502013-08-06 01:03:05 +00006422 case Decl::VarTemplate: {
6423 if (VarDecl *Def =
6424 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6425 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6426 return clang_getNullCursor();
6427 }
6428
Guy Benyei11169dd2012-12-18 14:30:41 +00006429 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006430 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6431 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006432
6433 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006434 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006435 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006436 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006437
6438 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006439 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006440 if (Method->isThisDeclarationADefinition())
6441 return C;
6442
6443 // Dig out the method definition in the associated
6444 // @implementation, if we have it.
6445 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006446 if (const ObjCInterfaceDecl *Class =
6447 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006448 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006449 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6450 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006451 if (Def->isThisDeclarationADefinition())
6452 return MakeCXCursor(Def, TU);
6453
6454 return clang_getNullCursor();
6455 }
6456
6457 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006458 if (ObjCCategoryImplDecl *Impl =
6459 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006460 return MakeCXCursor(Impl, TU);
6461 return clang_getNullCursor();
6462
6463 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006464 if (const ObjCProtocolDecl *Def =
6465 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006466 return MakeCXCursor(Def, TU);
6467 return clang_getNullCursor();
6468
6469 case Decl::ObjCInterface: {
6470 // There are two notions of a "definition" for an Objective-C
6471 // class: the interface and its implementation. When we resolved a
6472 // reference to an Objective-C class, produce the @interface as
6473 // the definition; when we were provided with the interface,
6474 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006475 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006476 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006477 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006478 return MakeCXCursor(Def, TU);
6479 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6480 return MakeCXCursor(Impl, TU);
6481 return clang_getNullCursor();
6482 }
6483
6484 case Decl::ObjCProperty:
6485 // FIXME: We don't really know where to find the
6486 // ObjCPropertyImplDecls that implement this property.
6487 return clang_getNullCursor();
6488
6489 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006490 if (const ObjCInterfaceDecl *Class =
6491 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006492 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006493 return MakeCXCursor(Def, TU);
6494
6495 return clang_getNullCursor();
6496
6497 case Decl::Friend:
6498 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6499 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6500 return clang_getNullCursor();
6501
6502 case Decl::FriendTemplate:
6503 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6504 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6505 return clang_getNullCursor();
6506 }
6507
6508 return clang_getNullCursor();
6509}
6510
6511unsigned clang_isCursorDefinition(CXCursor C) {
6512 if (!clang_isDeclaration(C.kind))
6513 return 0;
6514
6515 return clang_getCursorDefinition(C) == C;
6516}
6517
6518CXCursor clang_getCanonicalCursor(CXCursor C) {
6519 if (!clang_isDeclaration(C.kind))
6520 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006521
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006522 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006523 if (const ObjCCategoryImplDecl *CatImplD =
6524 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006525 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6526 return MakeCXCursor(CatD, getCursorTU(C));
6527
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006528 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6529 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006530 return MakeCXCursor(IFD, getCursorTU(C));
6531
6532 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6533 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006534
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 return C;
6536}
6537
6538int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6539 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6540}
Michael Kruse7520cf02020-03-25 09:26:14 -05006541
Guy Benyei11169dd2012-12-18 14:30:41 +00006542unsigned clang_getNumOverloadedDecls(CXCursor C) {
6543 if (C.kind != CXCursor_OverloadedDeclRef)
6544 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006545
Guy Benyei11169dd2012-12-18 14:30:41 +00006546 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006547 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006548 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006549
6550 if (OverloadedTemplateStorage *S =
6551 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006552 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006553
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006554 const Decl *D = Storage.get<const Decl *>();
6555 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006556 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006557
Guy Benyei11169dd2012-12-18 14:30:41 +00006558 return 0;
6559}
6560
6561CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6562 if (cursor.kind != CXCursor_OverloadedDeclRef)
6563 return clang_getNullCursor();
6564
6565 if (index >= clang_getNumOverloadedDecls(cursor))
6566 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006567
Guy Benyei11169dd2012-12-18 14:30:41 +00006568 CXTranslationUnit TU = getCursorTU(cursor);
6569 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006570 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006572
6573 if (OverloadedTemplateStorage *S =
6574 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006575 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006576
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006577 const Decl *D = Storage.get<const Decl *>();
6578 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006579 // FIXME: This is, unfortunately, linear time.
6580 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6581 std::advance(Pos, index);
6582 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6583 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006584
Guy Benyei11169dd2012-12-18 14:30:41 +00006585 return clang_getNullCursor();
6586}
Michael Kruse7520cf02020-03-25 09:26:14 -05006587
6588void clang_getDefinitionSpellingAndExtent(
6589 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6590 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006591 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006592 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006593 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6594
6595 SourceManager &SM = FD->getASTContext().getSourceManager();
6596 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6597 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6598 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6599 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6600 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6601 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6602}
6603
Guy Benyei11169dd2012-12-18 14:30:41 +00006604CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6605 unsigned PieceIndex) {
6606 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006607
Guy Benyei11169dd2012-12-18 14:30:41 +00006608 switch (C.kind) {
6609 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006610 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006611 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6612 E->getQualifierLoc().getSourceRange());
6613 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006614
Guy Benyei11169dd2012-12-18 14:30:41 +00006615 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006616 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6617 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6618 Pieces =
6619 buildPieces(NameFlags, false, E->getNameInfo(),
6620 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6621 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006622 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006623
Guy Benyei11169dd2012-12-18 14:30:41 +00006624 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006625 if (const CXXOperatorCallExpr *OCE =
6626 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006627 const Expr *Callee = OCE->getCallee();
6628 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006629 Callee = ICE->getSubExpr();
6630
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006631 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006632 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6633 DRE->getQualifierLoc().getSourceRange());
6634 }
6635 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006636
Guy Benyei11169dd2012-12-18 14:30:41 +00006637 default:
6638 break;
6639 }
6640
6641 if (Pieces.empty()) {
6642 if (PieceIndex == 0)
6643 return clang_getCursorExtent(C);
6644 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006645 SourceRange R = Pieces[PieceIndex];
6646 if (R.isValid())
6647 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006648 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006649
Guy Benyei11169dd2012-12-18 14:30:41 +00006650 return clang_getNullRange();
6651}
6652
6653void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006654 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6655 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006656}
6657
Michael Kruse7520cf02020-03-25 09:26:14 -05006658void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006659 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006660 llvm::llvm_execute_on_thread(fn, user_data,
6661 stack_size == 0
6662 ? clang::DesiredStackSize
6663 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006664}
6665
Guy Benyei11169dd2012-12-18 14:30:41 +00006666//===----------------------------------------------------------------------===//
6667// Token-based Operations.
6668//===----------------------------------------------------------------------===//
6669
6670/* CXToken layout:
6671 * int_data[0]: a CXTokenKind
6672 * int_data[1]: starting token location
6673 * int_data[2]: token length
6674 * int_data[3]: reserved
6675 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6676 * otherwise unused.
6677 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006678CXTokenKind clang_getTokenKind(CXToken CXTok) {
6679 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6680}
6681
6682CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6683 switch (clang_getTokenKind(CXTok)) {
6684 case CXToken_Identifier:
6685 case CXToken_Keyword:
6686 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006687 return cxstring::createRef(
6688 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006689
6690 case CXToken_Literal: {
6691 // We have stashed the starting pointer in the ptr_data field. Use it.
6692 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006693 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006694 }
6695
6696 case CXToken_Punctuation:
6697 case CXToken_Comment:
6698 break;
6699 }
6700
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006701 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006702 LOG_BAD_TU(TU);
6703 return cxstring::createEmpty();
6704 }
6705
Guy Benyei11169dd2012-12-18 14:30:41 +00006706 // We have to find the starting buffer pointer the hard way, by
6707 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006708 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006709 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006710 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006711
6712 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006713 std::pair<FileID, unsigned> LocInfo =
6714 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006715 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006716 StringRef Buffer =
6717 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006718 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006719 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006720
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006721 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006722}
6723
6724CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006725 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006726 LOG_BAD_TU(TU);
6727 return clang_getNullLocation();
6728 }
6729
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006730 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006731 if (!CXXUnit)
6732 return clang_getNullLocation();
6733
Michael Kruse7520cf02020-03-25 09:26:14 -05006734 return cxloc::translateSourceLocation(
6735 CXXUnit->getASTContext(),
6736 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006737}
6738
6739CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006740 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006741 LOG_BAD_TU(TU);
6742 return clang_getNullRange();
6743 }
6744
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006745 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006746 if (!CXXUnit)
6747 return clang_getNullRange();
6748
Michael Kruse7520cf02020-03-25 09:26:14 -05006749 return cxloc::translateSourceRange(
6750 CXXUnit->getASTContext(),
6751 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006752}
6753
6754static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6755 SmallVectorImpl<CXToken> &CXTokens) {
6756 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006757 std::pair<FileID, unsigned> BeginLocInfo =
6758 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6759 std::pair<FileID, unsigned> EndLocInfo =
6760 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006761
6762 // Cannot tokenize across files.
6763 if (BeginLocInfo.first != EndLocInfo.first)
6764 return;
6765
6766 // Create a lexer
6767 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006768 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006769 if (Invalid)
6770 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006771
Guy Benyei11169dd2012-12-18 14:30:41 +00006772 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006773 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6774 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006775 Lex.SetCommentRetentionState(true);
6776
6777 // Lex tokens until we hit the end of the range.
6778 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6779 Token Tok;
6780 bool previousWasAt = false;
6781 do {
6782 // Lex the next token
6783 Lex.LexFromRawLexer(Tok);
6784 if (Tok.is(tok::eof))
6785 break;
6786
6787 // Initialize the CXToken.
6788 CXToken CXTok;
6789
6790 // - Common fields
6791 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6792 CXTok.int_data[2] = Tok.getLength();
6793 CXTok.int_data[3] = 0;
6794
6795 // - Kind-specific fields
6796 if (Tok.isLiteral()) {
6797 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006798 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006799 } else if (Tok.is(tok::raw_identifier)) {
6800 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006801 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006802
6803 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6804 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006805 } else {
6806 CXTok.int_data[0] =
6807 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006808 }
6809 CXTok.ptr_data = II;
6810 } else if (Tok.is(tok::comment)) {
6811 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006812 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006813 } else {
6814 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006815 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006816 }
6817 CXTokens.push_back(CXTok);
6818 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006819 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006820}
6821
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006822CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006823 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006824
6825 if (isNotUsableTU(TU)) {
6826 LOG_BAD_TU(TU);
6827 return NULL;
6828 }
6829
6830 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6831 if (!CXXUnit)
6832 return NULL;
6833
6834 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6835 if (Begin.isInvalid())
6836 return NULL;
6837 SourceManager &SM = CXXUnit->getSourceManager();
6838 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006839 DecomposedEnd.second +=
6840 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006841
Michael Kruse7520cf02020-03-25 09:26:14 -05006842 SourceLocation End =
6843 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006844
6845 SmallVector<CXToken, 32> CXTokens;
6846 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6847
6848 if (CXTokens.empty())
6849 return NULL;
6850
6851 CXTokens.resize(1);
6852 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6853
6854 memmove(Token, CXTokens.data(), sizeof(CXToken));
6855 return Token;
6856}
6857
Michael Kruse7520cf02020-03-25 09:26:14 -05006858void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6859 unsigned *NumTokens) {
6860 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006861
Guy Benyei11169dd2012-12-18 14:30:41 +00006862 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006863 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006864 if (NumTokens)
6865 *NumTokens = 0;
6866
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006867 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006868 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006869 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006870 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006871
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006872 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006873 if (!CXXUnit || !Tokens || !NumTokens)
6874 return;
6875
6876 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006877
Guy Benyei11169dd2012-12-18 14:30:41 +00006878 SourceRange R = cxloc::translateCXSourceRange(Range);
6879 if (R.isInvalid())
6880 return;
6881
6882 SmallVector<CXToken, 32> CXTokens;
6883 getTokens(CXXUnit, R, CXTokens);
6884
6885 if (CXTokens.empty())
6886 return;
6887
Serge Pavlov52525732018-02-21 02:02:39 +00006888 *Tokens = static_cast<CXToken *>(
6889 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006890 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6891 *NumTokens = CXTokens.size();
6892}
6893
Michael Kruse7520cf02020-03-25 09:26:14 -05006894void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6895 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006896 free(Tokens);
6897}
6898
Guy Benyei11169dd2012-12-18 14:30:41 +00006899//===----------------------------------------------------------------------===//
6900// Token annotation APIs.
6901//===----------------------------------------------------------------------===//
6902
Guy Benyei11169dd2012-12-18 14:30:41 +00006903static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6904 CXCursor parent,
6905 CXClientData client_data);
6906static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6907 CXClientData client_data);
6908
6909namespace {
6910class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006911 CXToken *Tokens;
6912 CXCursor *Cursors;
6913 unsigned NumTokens;
6914 unsigned TokIdx;
6915 unsigned PreprocessingTokIdx;
6916 CursorVisitor AnnotateVis;
6917 SourceManager &SrcMgr;
6918 bool HasContextSensitiveKeywords;
6919
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006920 struct PostChildrenAction {
6921 CXCursor cursor;
6922 enum Action { Invalid, Ignore, Postpone } action;
6923 };
6924 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6925
Guy Benyei11169dd2012-12-18 14:30:41 +00006926 struct PostChildrenInfo {
6927 CXCursor Cursor;
6928 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006929 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006930 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006931 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006932 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006933 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006934
6935 CXToken &getTok(unsigned Idx) {
6936 assert(Idx < NumTokens);
6937 return Tokens[Idx];
6938 }
6939 const CXToken &getTok(unsigned Idx) const {
6940 assert(Idx < NumTokens);
6941 return Tokens[Idx];
6942 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006943 bool MoreTokens() const { return TokIdx < NumTokens; }
6944 unsigned NextToken() const { return TokIdx; }
6945 void AdvanceToken() { ++TokIdx; }
6946 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006947 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006948 }
6949 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006950 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006951 }
6952 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006953 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006954 }
6955
6956 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006957 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00006958 SourceRange);
6959
6960public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006961 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006962 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05006963 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
6964 PreprocessingTokIdx(0),
6965 AnnotateVis(TU, AnnotateTokensVisitor, this,
6966 /*VisitPreprocessorLast=*/true,
6967 /*VisitIncludedEntities=*/false, RegionOfInterest,
6968 /*VisitDeclsOnly=*/false,
6969 AnnotateTokensPostChildrenVisitor),
6970 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
6971 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00006972
6973 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
6974 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006975 bool IsIgnoredChildCursor(CXCursor cursor) const;
6976 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
6977
Guy Benyei11169dd2012-12-18 14:30:41 +00006978 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006979 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
6980 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
6981
Guy Benyei11169dd2012-12-18 14:30:41 +00006982 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05006983
6984 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00006985 /// context-sensitive keywords.
6986 bool hasContextSensitiveKeywords() const {
6987 return HasContextSensitiveKeywords;
6988 }
6989
Michael Kruse7520cf02020-03-25 09:26:14 -05006990 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00006991};
Michael Kruse7520cf02020-03-25 09:26:14 -05006992} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00006993
6994void AnnotateTokensWorker::AnnotateTokens() {
6995 // Walk the AST within the region of interest, annotating tokens
6996 // along the way.
6997 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006998}
Guy Benyei11169dd2012-12-18 14:30:41 +00006999
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007000bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7001 if (PostChildrenInfos.empty())
7002 return false;
7003
7004 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7005 if (ChildAction.cursor == cursor &&
7006 ChildAction.action == PostChildrenAction::Ignore) {
7007 return true;
7008 }
7009 }
7010
7011 return false;
7012}
7013
7014const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7015 if (!clang_isExpression(Cursor.kind))
7016 return nullptr;
7017
7018 const Expr *E = getCursorExpr(Cursor);
7019 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7020 const OverloadedOperatorKind Kind = OCE->getOperator();
7021 if (Kind == OO_Call || Kind == OO_Subscript)
7022 return OCE;
7023 }
7024
7025 return nullptr;
7026}
7027
7028AnnotateTokensWorker::PostChildrenActions
7029AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7030 PostChildrenActions actions;
7031
7032 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7033 // visited before the arguments to the operator call. For the Call and
7034 // Subscript operator the range of this DeclRefExpr includes the whole call
7035 // expression, so that all tokens in that range would be mapped to the
7036 // operator function, including the tokens of the arguments. To avoid that,
7037 // ensure to visit this DeclRefExpr as last node.
7038 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7039 const Expr *Callee = OCE->getCallee();
7040 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7041 const Expr *SubExpr = ICE->getSubExpr();
7042 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007043 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007044 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7045
7046 // Visit the DeclRefExpr as last.
7047 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7048 actions.push_back({cxChild, PostChildrenAction::Postpone});
7049
7050 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7051 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7052 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7053 actions.push_back({cxChild, PostChildrenAction::Ignore});
7054 }
7055 }
7056 }
7057
7058 return actions;
7059}
7060
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007061static inline void updateCursorAnnotation(CXCursor &Cursor,
7062 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007063 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007064 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007065 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007066}
7067
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007068/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007069//// between the cursor location and the source range is the same as
7070/// \arg compResult.
7071///
7072/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7073/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007074void AnnotateTokensWorker::annotateAndAdvanceTokens(
7075 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007076 while (MoreTokens()) {
7077 const unsigned I = NextToken();
7078 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007079 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7080 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007081
7082 SourceLocation TokLoc = GetTokenLoc(I);
7083 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007084 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007085 AdvanceToken();
7086 continue;
7087 }
7088 break;
7089 }
7090}
7091
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007092/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007093/// \returns true if it advanced beyond all macro tokens, false otherwise.
7094bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007095 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007096 assert(MoreTokens());
7097 assert(isFunctionMacroToken(NextToken()) &&
7098 "Should be called only for macro arg tokens");
7099
7100 // This works differently than annotateAndAdvanceTokens; because expanded
7101 // macro arguments can have arbitrary translation-unit source order, we do not
7102 // advance the token index one by one until a token fails the range test.
7103 // We only advance once past all of the macro arg tokens if all of them
7104 // pass the range test. If one of them fails we keep the token index pointing
7105 // at the start of the macro arg tokens so that the failing token will be
7106 // annotated by a subsequent annotation try.
7107
7108 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007109
Guy Benyei11169dd2012-12-18 14:30:41 +00007110 unsigned I = NextToken();
7111 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7112 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7113 if (TokLoc.isFileID())
7114 continue; // not macro arg token, it's parens or comma.
7115 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7116 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7117 Cursors[I] = updateC;
7118 } else
7119 atLeastOneCompFail = true;
7120 }
7121
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007122 if (atLeastOneCompFail)
7123 return false;
7124
7125 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7126 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007127}
7128
Michael Kruse7520cf02020-03-25 09:26:14 -05007129enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7130 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007131 SourceRange cursorRange = getRawCursorExtent(cursor);
7132 if (cursorRange.isInvalid())
7133 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007134
7135 if (IsIgnoredChildCursor(cursor))
7136 return CXChildVisit_Continue;
7137
Guy Benyei11169dd2012-12-18 14:30:41 +00007138 if (!HasContextSensitiveKeywords) {
7139 // Objective-C properties can have context-sensitive keywords.
7140 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007141 if (const ObjCPropertyDecl *Property =
7142 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7143 HasContextSensitiveKeywords =
7144 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007145 }
7146 // Objective-C methods can have context-sensitive keywords.
7147 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7148 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007149 if (const ObjCMethodDecl *Method =
7150 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007151 if (Method->getObjCDeclQualifier())
7152 HasContextSensitiveKeywords = true;
7153 else {
David Majnemer59f77922016-06-24 04:05:48 +00007154 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007155 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007156 HasContextSensitiveKeywords = true;
7157 break;
7158 }
7159 }
7160 }
7161 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007162 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007163 // C++ methods can have context-sensitive keywords.
7164 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007165 if (const CXXMethodDecl *Method =
7166 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007167 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7168 HasContextSensitiveKeywords = true;
7169 }
7170 }
7171 // C++ classes can have context-sensitive keywords.
7172 else if (cursor.kind == CXCursor_StructDecl ||
7173 cursor.kind == CXCursor_ClassDecl ||
7174 cursor.kind == CXCursor_ClassTemplate ||
7175 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007176 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007177 if (D->hasAttr<FinalAttr>())
7178 HasContextSensitiveKeywords = true;
7179 }
7180 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007181
7182 // Don't override a property annotation with its getter/setter method.
7183 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7184 parent.kind == CXCursor_ObjCPropertyDecl)
7185 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007186
7187 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007188 // Items in the preprocessing record are kept separate from items in
7189 // declarations, so we keep a separate token index.
7190 unsigned SavedTokIdx = TokIdx;
7191 TokIdx = PreprocessingTokIdx;
7192
7193 // Skip tokens up until we catch up to the beginning of the preprocessing
7194 // entry.
7195 while (MoreTokens()) {
7196 const unsigned I = NextToken();
7197 SourceLocation TokLoc = GetTokenLoc(I);
7198 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7199 case RangeBefore:
7200 AdvanceToken();
7201 continue;
7202 case RangeAfter:
7203 case RangeOverlap:
7204 break;
7205 }
7206 break;
7207 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007208
Guy Benyei11169dd2012-12-18 14:30:41 +00007209 // Look at all of the tokens within this range.
7210 while (MoreTokens()) {
7211 const unsigned I = NextToken();
7212 SourceLocation TokLoc = GetTokenLoc(I);
7213 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7214 case RangeBefore:
7215 llvm_unreachable("Infeasible");
7216 case RangeAfter:
7217 break;
7218 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007219 // For macro expansions, just note where the beginning of the macro
7220 // expansion occurs.
7221 if (cursor.kind == CXCursor_MacroExpansion) {
7222 if (TokLoc == cursorRange.getBegin())
7223 Cursors[I] = cursor;
7224 AdvanceToken();
7225 break;
7226 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007227 // We may have already annotated macro names inside macro definitions.
7228 if (Cursors[I].kind != CXCursor_MacroExpansion)
7229 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007230 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007231 continue;
7232 }
7233 break;
7234 }
7235
7236 // Save the preprocessing token index; restore the non-preprocessing
7237 // token index.
7238 PreprocessingTokIdx = TokIdx;
7239 TokIdx = SavedTokIdx;
7240 return CXChildVisit_Recurse;
7241 }
7242
7243 if (cursorRange.isInvalid())
7244 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007245
7246 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007247 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007248 const enum CXCursorKind K = clang_getCursorKind(parent);
7249 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007250 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7251 // Attributes are annotated out-of-order, skip tokens until we reach it.
7252 clang_isAttribute(cursor.kind))
7253 ? clang_getNullCursor()
7254 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007255
7256 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7257
7258 // Avoid having the cursor of an expression "overwrite" the annotation of the
7259 // variable declaration that it belongs to.
7260 // This can happen for C++ constructor expressions whose range generally
7261 // include the variable declaration, e.g.:
7262 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007263 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007264 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007265 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007266 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007267 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7268 E->getBeginLoc() == D->getLocation() &&
7269 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007270 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007271 AdvanceToken();
7272 }
7273 }
7274 }
7275
7276 // Before recursing into the children keep some state that we are going
7277 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7278 // extra work after the child nodes are visited.
7279 // Note that we don't call VisitChildren here to avoid traversing statements
7280 // code-recursively which can blow the stack.
7281
7282 PostChildrenInfo Info;
7283 Info.Cursor = cursor;
7284 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007285 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007286 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007287 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007288 PostChildrenInfos.push_back(Info);
7289
7290 return CXChildVisit_Recurse;
7291}
7292
7293bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7294 if (PostChildrenInfos.empty())
7295 return false;
7296 const PostChildrenInfo &Info = PostChildrenInfos.back();
7297 if (!clang_equalCursors(Info.Cursor, cursor))
7298 return false;
7299
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007300 HandlePostPonedChildCursors(Info);
7301
Guy Benyei11169dd2012-12-18 14:30:41 +00007302 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7303 const unsigned AfterChildren = NextToken();
7304 SourceRange cursorRange = Info.CursorRange;
7305
7306 // Scan the tokens that are at the end of the cursor, but are not captured
7307 // but the child cursors.
7308 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7309
7310 // Scan the tokens that are at the beginning of the cursor, but are not
7311 // capture by the child cursors.
7312 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7313 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7314 break;
7315
7316 Cursors[I] = cursor;
7317 }
7318
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007319 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7320 // encountered the attribute cursor.
7321 if (clang_isAttribute(cursor.kind))
7322 TokIdx = Info.BeforeReachingCursorIdx;
7323
Guy Benyei11169dd2012-12-18 14:30:41 +00007324 PostChildrenInfos.pop_back();
7325 return false;
7326}
7327
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007328void AnnotateTokensWorker::HandlePostPonedChildCursors(
7329 const PostChildrenInfo &Info) {
7330 for (const auto &ChildAction : Info.ChildActions) {
7331 if (ChildAction.action == PostChildrenAction::Postpone) {
7332 HandlePostPonedChildCursor(ChildAction.cursor,
7333 Info.BeforeChildrenTokenIdx);
7334 }
7335 }
7336}
7337
7338void AnnotateTokensWorker::HandlePostPonedChildCursor(
7339 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007340 unsigned I = StartTokenIndex;
7341
7342 // The bracket tokens of a Call or Subscript operator are mapped to
7343 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7344 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7345 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007346 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7347 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007348 if (clang_Range_isNull(CXRefNameRange))
7349 break; // All ranges handled.
7350
7351 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7352 while (I < NumTokens) {
7353 const SourceLocation TokenLocation = GetTokenLoc(I);
7354 if (!TokenLocation.isValid())
7355 break;
7356
7357 // Adapt the end range, because LocationCompare() reports
7358 // RangeOverlap even for the not-inclusive end location.
7359 const SourceLocation fixedEnd =
7360 RefNameRange.getEnd().getLocWithOffset(-1);
7361 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7362
7363 const RangeComparisonResult ComparisonResult =
7364 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7365
7366 if (ComparisonResult == RangeOverlap) {
7367 Cursors[I++] = Cursor;
7368 } else if (ComparisonResult == RangeBefore) {
7369 ++I; // Not relevant token, check next one.
7370 } else if (ComparisonResult == RangeAfter) {
7371 break; // All tokens updated for current range, check next.
7372 }
7373 }
7374 }
7375}
7376
Guy Benyei11169dd2012-12-18 14:30:41 +00007377static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7378 CXCursor parent,
7379 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007380 return static_cast<AnnotateTokensWorker *>(client_data)
7381 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007382}
7383
7384static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7385 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007386 return static_cast<AnnotateTokensWorker *>(client_data)
7387 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007388}
7389
7390namespace {
7391
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007392/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007393/// and mark tokens that are macro arguments. This info is used by the
7394/// AnnotateTokensWorker.
7395class MarkMacroArgTokensVisitor {
7396 SourceManager &SM;
7397 CXToken *Tokens;
7398 unsigned NumTokens;
7399 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007400
Guy Benyei11169dd2012-12-18 14:30:41 +00007401public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007402 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7403 unsigned numTokens)
7404 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007405
7406 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7407 if (cursor.kind != CXCursor_MacroExpansion)
7408 return CXChildVisit_Continue;
7409
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007410 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007411 if (macroRange.getBegin() == macroRange.getEnd())
7412 return CXChildVisit_Continue; // it's not a function macro.
7413
7414 for (; CurIdx < NumTokens; ++CurIdx) {
7415 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7416 macroRange.getBegin()))
7417 break;
7418 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007419
Guy Benyei11169dd2012-12-18 14:30:41 +00007420 if (CurIdx == NumTokens)
7421 return CXChildVisit_Break;
7422
7423 for (; CurIdx < NumTokens; ++CurIdx) {
7424 SourceLocation tokLoc = getTokenLoc(CurIdx);
7425 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7426 break;
7427
7428 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7429 }
7430
7431 if (CurIdx == NumTokens)
7432 return CXChildVisit_Break;
7433
7434 return CXChildVisit_Continue;
7435 }
7436
7437private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007438 CXToken &getTok(unsigned Idx) {
7439 assert(Idx < NumTokens);
7440 return Tokens[Idx];
7441 }
7442 const CXToken &getTok(unsigned Idx) const {
7443 assert(Idx < NumTokens);
7444 return Tokens[Idx];
7445 }
7446
Guy Benyei11169dd2012-12-18 14:30:41 +00007447 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007448 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007449 }
7450
7451 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7452 // The third field is reserved and currently not used. Use it here
7453 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007454 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007455 }
7456};
7457
7458} // end anonymous namespace
7459
7460static CXChildVisitResult
7461MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7462 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007463 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7464 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007465}
7466
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007467/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007468/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007469static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7470 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007471 if (NextIdx >= NumTokens)
7472 return true;
7473
7474 ++NextIdx;
7475 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007476 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007477}
7478
Guy Benyei11169dd2012-12-18 14:30:41 +00007479static void annotatePreprocessorTokens(CXTranslationUnit TU,
7480 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007481 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007482 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007483 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007484
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007485 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007486 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007487 std::pair<FileID, unsigned> BeginLocInfo =
7488 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7489 std::pair<FileID, unsigned> EndLocInfo =
7490 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007491
7492 if (BeginLocInfo.first != EndLocInfo.first)
7493 return;
7494
7495 StringRef Buffer;
7496 bool Invalid = false;
7497 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7498 if (Buffer.empty() || Invalid)
7499 return;
7500
7501 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007502 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7503 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007504 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007505
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007506 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007507 // Lex tokens in raw mode until we hit the end of the range, to avoid
7508 // entering #includes or expanding macros.
7509 while (true) {
7510 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007511 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7512 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007513 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007514 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007515 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7516
Guy Benyei11169dd2012-12-18 14:30:41 +00007517 reprocess:
7518 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007519 // We have found a preprocessing directive. Annotate the tokens
7520 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007521 //
7522 // FIXME: Some simple tests here could identify macro definitions and
7523 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007524
7525 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007526 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7527 break;
7528
Craig Topper69186e72014-06-08 08:38:04 +00007529 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007530 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007531 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7532 break;
7533
7534 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007535 IdentifierInfo &II =
7536 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007537 SourceLocation MappedTokLoc =
7538 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7539 MI = getMacroInfo(II, MappedTokLoc, TU);
7540 }
7541 }
7542
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007543 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007544 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007545 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7546 finished = true;
7547 break;
7548 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007549 // If we are in a macro definition, check if the token was ever a
7550 // macro name and annotate it if that's the case.
7551 if (MI) {
7552 SourceLocation SaveLoc = Tok.getLocation();
7553 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007554 MacroDefinitionRecord *MacroDef =
7555 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007556 Tok.setLocation(SaveLoc);
7557 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007558 Cursors[NextIdx - 1] =
7559 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007560 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007561 } while (!Tok.isAtStartOfLine());
7562
Michael Kruse7520cf02020-03-25 09:26:14 -05007563 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007564 assert(TokIdx <= LastIdx);
7565 SourceLocation EndLoc =
7566 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7567 CXCursor Cursor =
7568 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7569
7570 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007571 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007572
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007573 if (finished)
7574 break;
7575 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007576 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007577 }
7578}
7579
7580// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007581static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7582 CXToken *Tokens, unsigned NumTokens,
7583 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007584 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007585 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7586 setThreadBackgroundPriority();
7587
7588 // Determine the region of interest, which contains all of the tokens.
7589 SourceRange RegionOfInterest;
7590 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007591 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7592 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7593 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007594
Guy Benyei11169dd2012-12-18 14:30:41 +00007595 // Relex the tokens within the source range to look for preprocessing
7596 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007597 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007598
7599 // If begin location points inside a macro argument, set it to the expansion
7600 // location so we can have the full context when annotating semantically.
7601 {
7602 SourceManager &SM = CXXUnit->getSourceManager();
7603 SourceLocation Loc =
7604 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7605 if (Loc.isMacroID())
7606 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7607 }
7608
Guy Benyei11169dd2012-12-18 14:30:41 +00007609 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7610 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007611 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7612 NumTokens);
7613 CursorVisitor MacroArgMarker(
7614 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7615 /*VisitPreprocessorLast=*/true,
7616 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007617 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7618 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007619
Guy Benyei11169dd2012-12-18 14:30:41 +00007620 // Annotate all of the source locations in the region of interest that map to
7621 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007622 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007623
Guy Benyei11169dd2012-12-18 14:30:41 +00007624 // FIXME: We use a ridiculous stack size here because the data-recursion
7625 // algorithm uses a large stack frame than the non-data recursive version,
7626 // and AnnotationTokensWorker currently transforms the data-recursion
7627 // algorithm back into a traditional recursion by explicitly calling
7628 // VisitChildren(). We will need to remove this explicit recursive call.
7629 W.AnnotateTokens();
7630
7631 // If we ran into any entities that involve context-sensitive keywords,
7632 // take another pass through the tokens to mark them as such.
7633 if (W.hasContextSensitiveKeywords()) {
7634 for (unsigned I = 0; I != NumTokens; ++I) {
7635 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7636 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007637
Guy Benyei11169dd2012-12-18 14:30:41 +00007638 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7639 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007640 if (const ObjCPropertyDecl *Property =
7641 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007642 if (Property->getPropertyAttributesAsWritten() != 0 &&
7643 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007644 .Case("readonly", true)
7645 .Case("assign", true)
7646 .Case("unsafe_unretained", true)
7647 .Case("readwrite", true)
7648 .Case("retain", true)
7649 .Case("copy", true)
7650 .Case("nonatomic", true)
7651 .Case("atomic", true)
7652 .Case("getter", true)
7653 .Case("setter", true)
7654 .Case("strong", true)
7655 .Case("weak", true)
7656 .Case("class", true)
7657 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007658 Tokens[I].int_data[0] = CXToken_Keyword;
7659 }
7660 continue;
7661 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007662
Guy Benyei11169dd2012-12-18 14:30:41 +00007663 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7664 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7665 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7666 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007667 .Case("in", true)
7668 .Case("out", true)
7669 .Case("inout", true)
7670 .Case("oneway", true)
7671 .Case("bycopy", true)
7672 .Case("byref", true)
7673 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007674 Tokens[I].int_data[0] = CXToken_Keyword;
7675 continue;
7676 }
7677
7678 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7679 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7680 Tokens[I].int_data[0] = CXToken_Keyword;
7681 continue;
7682 }
7683 }
7684 }
7685}
7686
Michael Kruse7520cf02020-03-25 09:26:14 -05007687void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7688 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007689 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007690 LOG_BAD_TU(TU);
7691 return;
7692 }
7693 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007694 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007695 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007696 }
7697
7698 LOG_FUNC_SECTION {
7699 *Log << TU << ' ';
7700 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007701 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007702 *Log << clang_getRange(bloc, eloc);
7703 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007704
7705 // Any token we don't specifically annotate will have a NULL cursor.
7706 CXCursor C = clang_getNullCursor();
7707 for (unsigned I = 0; I != NumTokens; ++I)
7708 Cursors[I] = C;
7709
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007710 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007711 if (!CXXUnit)
7712 return;
7713
7714 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007715
7716 auto AnnotateTokensImpl = [=]() {
7717 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7718 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007719 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007720 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007721 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7722 }
7723}
7724
Guy Benyei11169dd2012-12-18 14:30:41 +00007725//===----------------------------------------------------------------------===//
7726// Operations for querying linkage of a cursor.
7727//===----------------------------------------------------------------------===//
7728
Guy Benyei11169dd2012-12-18 14:30:41 +00007729CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7730 if (!clang_isDeclaration(cursor.kind))
7731 return CXLinkage_Invalid;
7732
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007733 const Decl *D = cxcursor::getCursorDecl(cursor);
7734 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007735 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007736 case NoLinkage:
7737 case VisibleNoLinkage:
7738 return CXLinkage_NoLinkage;
7739 case ModuleInternalLinkage:
7740 case InternalLinkage:
7741 return CXLinkage_Internal;
7742 case UniqueExternalLinkage:
7743 return CXLinkage_UniqueExternal;
7744 case ModuleLinkage:
7745 case ExternalLinkage:
7746 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007747 };
7748
7749 return CXLinkage_Invalid;
7750}
Guy Benyei11169dd2012-12-18 14:30:41 +00007751
7752//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007753// Operations for querying visibility of a cursor.
7754//===----------------------------------------------------------------------===//
7755
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007756CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7757 if (!clang_isDeclaration(cursor.kind))
7758 return CXVisibility_Invalid;
7759
7760 const Decl *D = cxcursor::getCursorDecl(cursor);
7761 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7762 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007763 case HiddenVisibility:
7764 return CXVisibility_Hidden;
7765 case ProtectedVisibility:
7766 return CXVisibility_Protected;
7767 case DefaultVisibility:
7768 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007769 };
7770
7771 return CXVisibility_Invalid;
7772}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007773
7774//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007775// Operations for querying language of a cursor.
7776//===----------------------------------------------------------------------===//
7777
7778static CXLanguageKind getDeclLanguage(const Decl *D) {
7779 if (!D)
7780 return CXLanguage_C;
7781
7782 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007783 default:
7784 break;
7785 case Decl::ImplicitParam:
7786 case Decl::ObjCAtDefsField:
7787 case Decl::ObjCCategory:
7788 case Decl::ObjCCategoryImpl:
7789 case Decl::ObjCCompatibleAlias:
7790 case Decl::ObjCImplementation:
7791 case Decl::ObjCInterface:
7792 case Decl::ObjCIvar:
7793 case Decl::ObjCMethod:
7794 case Decl::ObjCProperty:
7795 case Decl::ObjCPropertyImpl:
7796 case Decl::ObjCProtocol:
7797 case Decl::ObjCTypeParam:
7798 return CXLanguage_ObjC;
7799 case Decl::CXXConstructor:
7800 case Decl::CXXConversion:
7801 case Decl::CXXDestructor:
7802 case Decl::CXXMethod:
7803 case Decl::CXXRecord:
7804 case Decl::ClassTemplate:
7805 case Decl::ClassTemplatePartialSpecialization:
7806 case Decl::ClassTemplateSpecialization:
7807 case Decl::Friend:
7808 case Decl::FriendTemplate:
7809 case Decl::FunctionTemplate:
7810 case Decl::LinkageSpec:
7811 case Decl::Namespace:
7812 case Decl::NamespaceAlias:
7813 case Decl::NonTypeTemplateParm:
7814 case Decl::StaticAssert:
7815 case Decl::TemplateTemplateParm:
7816 case Decl::TemplateTypeParm:
7817 case Decl::UnresolvedUsingTypename:
7818 case Decl::UnresolvedUsingValue:
7819 case Decl::Using:
7820 case Decl::UsingDirective:
7821 case Decl::UsingShadow:
7822 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007823 }
7824
7825 return CXLanguage_C;
7826}
7827
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007828static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7829 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007830 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007831
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007832 switch (D->getAvailability()) {
7833 case AR_Available:
7834 case AR_NotYetIntroduced:
7835 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007836 return getCursorAvailabilityForDecl(
7837 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007838 return CXAvailability_Available;
7839
7840 case AR_Deprecated:
7841 return CXAvailability_Deprecated;
7842
7843 case AR_Unavailable:
7844 return CXAvailability_NotAvailable;
7845 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007846
7847 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007848}
7849
Guy Benyei11169dd2012-12-18 14:30:41 +00007850enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7851 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007852 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7853 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007854
7855 return CXAvailability_Available;
7856}
7857
7858static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007859 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007860 if (In.empty())
7861 return Out;
7862
7863 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007864
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007865 Optional<unsigned> Minor = In.getMinor();
7866 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007867 Out.Minor = *Minor;
7868 else
7869 return Out;
7870
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007871 Optional<unsigned> Subminor = In.getSubminor();
7872 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007873 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007874
Guy Benyei11169dd2012-12-18 14:30:41 +00007875 return Out;
7876}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007877
Alex Lorenz1345ea22017-06-12 19:06:30 +00007878static void getCursorPlatformAvailabilityForDecl(
7879 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7880 int *always_unavailable, CXString *unavailable_message,
7881 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007882 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007883 for (auto A : D->attrs()) {
7884 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007885 HadAvailAttr = true;
7886 if (always_deprecated)
7887 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007888 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007889 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007890 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007891 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007892 continue;
7893 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007894
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007895 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007896 HadAvailAttr = true;
7897 if (always_unavailable)
7898 *always_unavailable = 1;
7899 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007900 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007901 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7902 }
7903 continue;
7904 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007905
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007906 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007907 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007908 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007909 }
7910 }
7911
7912 if (!HadAvailAttr)
7913 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7914 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007915 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7916 deprecated_message, always_unavailable, unavailable_message,
7917 AvailabilityAttrs);
7918
7919 if (AvailabilityAttrs.empty())
7920 return;
7921
Michael Kruse7520cf02020-03-25 09:26:14 -05007922 llvm::sort(
7923 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7924 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7925 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007926 ASTContext &Ctx = D->getASTContext();
7927 auto It = std::unique(
7928 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7929 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7930 if (LHS->getPlatform() != RHS->getPlatform())
7931 return false;
7932
7933 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7934 LHS->getDeprecated() == RHS->getDeprecated() &&
7935 LHS->getObsoleted() == RHS->getObsoleted() &&
7936 LHS->getMessage() == RHS->getMessage() &&
7937 LHS->getReplacement() == RHS->getReplacement())
7938 return true;
7939
7940 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
7941 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
7942 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
7943 return false;
7944
7945 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
7946 LHS->setIntroduced(Ctx, RHS->getIntroduced());
7947
7948 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
7949 LHS->setDeprecated(Ctx, RHS->getDeprecated());
7950 if (LHS->getMessage().empty())
7951 LHS->setMessage(Ctx, RHS->getMessage());
7952 if (LHS->getReplacement().empty())
7953 LHS->setReplacement(Ctx, RHS->getReplacement());
7954 }
7955
7956 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
7957 LHS->setObsoleted(Ctx, RHS->getObsoleted());
7958 if (LHS->getMessage().empty())
7959 LHS->setMessage(Ctx, RHS->getMessage());
7960 if (LHS->getReplacement().empty())
7961 LHS->setReplacement(Ctx, RHS->getReplacement());
7962 }
7963
7964 return true;
7965 });
7966 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007967}
7968
Alex Lorenz1345ea22017-06-12 19:06:30 +00007969int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00007970 CXString *deprecated_message,
7971 int *always_unavailable,
7972 CXString *unavailable_message,
7973 CXPlatformAvailability *availability,
7974 int availability_size) {
7975 if (always_deprecated)
7976 *always_deprecated = 0;
7977 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007978 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00007979 if (always_unavailable)
7980 *always_unavailable = 0;
7981 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00007982 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007983
Guy Benyei11169dd2012-12-18 14:30:41 +00007984 if (!clang_isDeclaration(cursor.kind))
7985 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007986
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007987 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007988 if (!D)
7989 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007990
Alex Lorenz1345ea22017-06-12 19:06:30 +00007991 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
7992 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
7993 always_unavailable, unavailable_message,
7994 AvailabilityAttrs);
7995 for (const auto &Avail :
7996 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
7997 .take_front(availability_size))) {
7998 availability[Avail.index()].Platform =
7999 cxstring::createDup(Avail.value()->getPlatform()->getName());
8000 availability[Avail.index()].Introduced =
8001 convertVersion(Avail.value()->getIntroduced());
8002 availability[Avail.index()].Deprecated =
8003 convertVersion(Avail.value()->getDeprecated());
8004 availability[Avail.index()].Obsoleted =
8005 convertVersion(Avail.value()->getObsoleted());
8006 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8007 availability[Avail.index()].Message =
8008 cxstring::createDup(Avail.value()->getMessage());
8009 }
8010
8011 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008012}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008013
Guy Benyei11169dd2012-12-18 14:30:41 +00008014void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8015 clang_disposeString(availability->Platform);
8016 clang_disposeString(availability->Message);
8017}
8018
8019CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8020 if (clang_isDeclaration(cursor.kind))
8021 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8022
8023 return CXLanguage_Invalid;
8024}
8025
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008026CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8027 const Decl *D = cxcursor::getCursorDecl(cursor);
8028 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8029 switch (VD->getTLSKind()) {
8030 case VarDecl::TLS_None:
8031 return CXTLS_None;
8032 case VarDecl::TLS_Dynamic:
8033 return CXTLS_Dynamic;
8034 case VarDecl::TLS_Static:
8035 return CXTLS_Static;
8036 }
8037 }
8038
8039 return CXTLS_None;
8040}
8041
Michael Kruse7520cf02020-03-25 09:26:14 -05008042/// If the given cursor is the "templated" declaration
8043/// describing a class or function template, return the class or
8044/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008045static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008046 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008047 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008048
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008049 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008050 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8051 return FunTmpl;
8052
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008053 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008054 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8055 return ClassTmpl;
8056
8057 return D;
8058}
8059
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008060enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8061 StorageClass sc = SC_None;
8062 const Decl *D = getCursorDecl(C);
8063 if (D) {
8064 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8065 sc = FD->getStorageClass();
8066 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8067 sc = VD->getStorageClass();
8068 } else {
8069 return CX_SC_Invalid;
8070 }
8071 } else {
8072 return CX_SC_Invalid;
8073 }
8074 switch (sc) {
8075 case SC_None:
8076 return CX_SC_None;
8077 case SC_Extern:
8078 return CX_SC_Extern;
8079 case SC_Static:
8080 return CX_SC_Static;
8081 case SC_PrivateExtern:
8082 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008083 case SC_Auto:
8084 return CX_SC_Auto;
8085 case SC_Register:
8086 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008087 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008088 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008089}
8090
Guy Benyei11169dd2012-12-18 14:30:41 +00008091CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8092 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008093 if (const Decl *D = getCursorDecl(cursor)) {
8094 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008095 if (!DC)
8096 return clang_getNullCursor();
8097
Michael Kruse7520cf02020-03-25 09:26:14 -05008098 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008099 getCursorTU(cursor));
8100 }
8101 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008102
Guy Benyei11169dd2012-12-18 14:30:41 +00008103 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008104 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008105 return MakeCXCursor(D, getCursorTU(cursor));
8106 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008107
Guy Benyei11169dd2012-12-18 14:30:41 +00008108 return clang_getNullCursor();
8109}
8110
8111CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8112 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008113 if (const Decl *D = getCursorDecl(cursor)) {
8114 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008115 if (!DC)
8116 return clang_getNullCursor();
8117
Michael Kruse7520cf02020-03-25 09:26:14 -05008118 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008119 getCursorTU(cursor));
8120 }
8121 }
8122
Michael Kruse7520cf02020-03-25 09:26:14 -05008123 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008124 // statement or expression, so we return nothing.
8125 return clang_getNullCursor();
8126}
8127
8128CXFile clang_getIncludedFile(CXCursor cursor) {
8129 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008130 return nullptr;
8131
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008132 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008133 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008134}
8135
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008136unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8137 if (C.kind != CXCursor_ObjCPropertyDecl)
8138 return CXObjCPropertyAttr_noattr;
8139
8140 unsigned Result = CXObjCPropertyAttr_noattr;
8141 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8142 ObjCPropertyDecl::PropertyAttributeKind Attr =
8143 PD->getPropertyAttributesAsWritten();
8144
Michael Kruse7520cf02020-03-25 09:26:14 -05008145#define SET_CXOBJCPROP_ATTR(A) \
8146 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
8147 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008148 SET_CXOBJCPROP_ATTR(readonly);
8149 SET_CXOBJCPROP_ATTR(getter);
8150 SET_CXOBJCPROP_ATTR(assign);
8151 SET_CXOBJCPROP_ATTR(readwrite);
8152 SET_CXOBJCPROP_ATTR(retain);
8153 SET_CXOBJCPROP_ATTR(copy);
8154 SET_CXOBJCPROP_ATTR(nonatomic);
8155 SET_CXOBJCPROP_ATTR(setter);
8156 SET_CXOBJCPROP_ATTR(atomic);
8157 SET_CXOBJCPROP_ATTR(weak);
8158 SET_CXOBJCPROP_ATTR(strong);
8159 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008160 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008161#undef SET_CXOBJCPROP_ATTR
8162
8163 return Result;
8164}
8165
Michael Wu6e88f532018-08-03 05:38:29 +00008166CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8167 if (C.kind != CXCursor_ObjCPropertyDecl)
8168 return cxstring::createNull();
8169
8170 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8171 Selector sel = PD->getGetterName();
8172 if (sel.isNull())
8173 return cxstring::createNull();
8174
8175 return cxstring::createDup(sel.getAsString());
8176}
8177
8178CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8179 if (C.kind != CXCursor_ObjCPropertyDecl)
8180 return cxstring::createNull();
8181
8182 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8183 Selector sel = PD->getSetterName();
8184 if (sel.isNull())
8185 return cxstring::createNull();
8186
8187 return cxstring::createDup(sel.getAsString());
8188}
8189
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008190unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8191 if (!clang_isDeclaration(C.kind))
8192 return CXObjCDeclQualifier_None;
8193
8194 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8195 const Decl *D = getCursorDecl(C);
8196 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8197 QT = MD->getObjCDeclQualifier();
8198 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8199 QT = PD->getObjCDeclQualifier();
8200 if (QT == Decl::OBJC_TQ_None)
8201 return CXObjCDeclQualifier_None;
8202
8203 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008204 if (QT & Decl::OBJC_TQ_In)
8205 Result |= CXObjCDeclQualifier_In;
8206 if (QT & Decl::OBJC_TQ_Inout)
8207 Result |= CXObjCDeclQualifier_Inout;
8208 if (QT & Decl::OBJC_TQ_Out)
8209 Result |= CXObjCDeclQualifier_Out;
8210 if (QT & Decl::OBJC_TQ_Bycopy)
8211 Result |= CXObjCDeclQualifier_Bycopy;
8212 if (QT & Decl::OBJC_TQ_Byref)
8213 Result |= CXObjCDeclQualifier_Byref;
8214 if (QT & Decl::OBJC_TQ_Oneway)
8215 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008216
8217 return Result;
8218}
8219
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008220unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8221 if (!clang_isDeclaration(C.kind))
8222 return 0;
8223
8224 const Decl *D = getCursorDecl(C);
8225 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8226 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8227 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8228 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8229
8230 return 0;
8231}
8232
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008233unsigned clang_Cursor_isVariadic(CXCursor C) {
8234 if (!clang_isDeclaration(C.kind))
8235 return 0;
8236
8237 const Decl *D = getCursorDecl(C);
8238 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8239 return FD->isVariadic();
8240 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8241 return MD->isVariadic();
8242
8243 return 0;
8244}
8245
Michael Kruse7520cf02020-03-25 09:26:14 -05008246unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8247 CXString *definedIn,
8248 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008249 if (!clang_isDeclaration(C.kind))
8250 return 0;
8251
8252 const Decl *D = getCursorDecl(C);
8253
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008254 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008255 if (language)
8256 *language = cxstring::createDup(attr->getLanguage());
8257 if (definedIn)
8258 *definedIn = cxstring::createDup(attr->getDefinedIn());
8259 if (isGenerated)
8260 *isGenerated = attr->getGeneratedDeclaration();
8261 return 1;
8262 }
8263 return 0;
8264}
8265
Guy Benyei11169dd2012-12-18 14:30:41 +00008266CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8267 if (!clang_isDeclaration(C.kind))
8268 return clang_getNullRange();
8269
8270 const Decl *D = getCursorDecl(C);
8271 ASTContext &Context = getCursorContext(C);
8272 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8273 if (!RC)
8274 return clang_getNullRange();
8275
8276 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8277}
8278
8279CXString clang_Cursor_getRawCommentText(CXCursor C) {
8280 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008281 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008282
8283 const Decl *D = getCursorDecl(C);
8284 ASTContext &Context = getCursorContext(C);
8285 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008286 StringRef RawText =
8287 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008288
8289 // Don't duplicate the string because RawText points directly into source
8290 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008291 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008292}
8293
8294CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8295 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008296 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008297
8298 const Decl *D = getCursorDecl(C);
8299 const ASTContext &Context = getCursorContext(C);
8300 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8301
8302 if (RC) {
8303 StringRef BriefText = RC->getBriefText(Context);
8304
8305 // Don't duplicate the string because RawComment ensures that this memory
8306 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008307 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008308 }
8309
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008310 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008311}
8312
Guy Benyei11169dd2012-12-18 14:30:41 +00008313CXModule clang_Cursor_getModule(CXCursor C) {
8314 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008315 if (const ImportDecl *ImportD =
8316 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008317 return ImportD->getImportedModule();
8318 }
8319
Craig Topper69186e72014-06-08 08:38:04 +00008320 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008321}
8322
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008323CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8324 if (isNotUsableTU(TU)) {
8325 LOG_BAD_TU(TU);
8326 return nullptr;
8327 }
8328 if (!File)
8329 return nullptr;
8330 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008331
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008332 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8333 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8334 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008335
Richard Smithfeb54b62014-10-23 02:01:19 +00008336 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008337}
8338
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008339CXFile clang_Module_getASTFile(CXModule CXMod) {
8340 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008341 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008342 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008343 return const_cast<FileEntry *>(Mod->getASTFile());
8344}
8345
Guy Benyei11169dd2012-12-18 14:30:41 +00008346CXModule clang_Module_getParent(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);
Guy Benyei11169dd2012-12-18 14:30:41 +00008350 return Mod->Parent;
8351}
8352
8353CXString clang_Module_getName(CXModule CXMod) {
8354 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008355 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008356 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008357 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008358}
8359
8360CXString clang_Module_getFullName(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->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008365}
8366
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008367int clang_Module_isSystem(CXModule CXMod) {
8368 if (!CXMod)
8369 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008370 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008371 return Mod->IsSystem;
8372}
8373
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008374unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8375 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008376 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008377 LOG_BAD_TU(TU);
8378 return 0;
8379 }
8380 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008381 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008382 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008383 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8384 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8385 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008386}
8387
Michael Kruse7520cf02020-03-25 09:26:14 -05008388CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8389 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008390 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008391 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008392 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008393 }
8394 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008395 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008396 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008397 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008398
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008399 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8400 if (Index < TopHeaders.size())
8401 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008402
Craig Topper69186e72014-06-08 08:38:04 +00008403 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008404}
8405
Guy Benyei11169dd2012-12-18 14:30:41 +00008406//===----------------------------------------------------------------------===//
8407// C++ AST instrospection.
8408//===----------------------------------------------------------------------===//
8409
Jonathan Coe29565352016-04-27 12:48:25 +00008410unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8411 if (!clang_isDeclaration(C.kind))
8412 return 0;
8413
8414 const Decl *D = cxcursor::getCursorDecl(C);
8415 const CXXConstructorDecl *Constructor =
8416 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8417 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8418}
8419
8420unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8421 if (!clang_isDeclaration(C.kind))
8422 return 0;
8423
8424 const Decl *D = cxcursor::getCursorDecl(C);
8425 const CXXConstructorDecl *Constructor =
8426 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8427 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8428}
8429
8430unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8431 if (!clang_isDeclaration(C.kind))
8432 return 0;
8433
8434 const Decl *D = cxcursor::getCursorDecl(C);
8435 const CXXConstructorDecl *Constructor =
8436 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8437 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8438}
8439
8440unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8441 if (!clang_isDeclaration(C.kind))
8442 return 0;
8443
8444 const Decl *D = cxcursor::getCursorDecl(C);
8445 const CXXConstructorDecl *Constructor =
8446 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8447 // Passing 'false' excludes constructors marked 'explicit'.
8448 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8449}
8450
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008451unsigned clang_CXXField_isMutable(CXCursor C) {
8452 if (!clang_isDeclaration(C.kind))
8453 return 0;
8454
8455 if (const auto D = cxcursor::getCursorDecl(C))
8456 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8457 return FD->isMutable() ? 1 : 0;
8458 return 0;
8459}
8460
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008461unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8462 if (!clang_isDeclaration(C.kind))
8463 return 0;
8464
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008465 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008466 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008467 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008468 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8469}
8470
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008471unsigned clang_CXXMethod_isConst(CXCursor C) {
8472 if (!clang_isDeclaration(C.kind))
8473 return 0;
8474
8475 const Decl *D = cxcursor::getCursorDecl(C);
8476 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008477 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008478 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008479}
8480
Jonathan Coe29565352016-04-27 12:48:25 +00008481unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8482 if (!clang_isDeclaration(C.kind))
8483 return 0;
8484
8485 const Decl *D = cxcursor::getCursorDecl(C);
8486 const CXXMethodDecl *Method =
8487 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8488 return (Method && Method->isDefaulted()) ? 1 : 0;
8489}
8490
Guy Benyei11169dd2012-12-18 14:30:41 +00008491unsigned clang_CXXMethod_isStatic(CXCursor C) {
8492 if (!clang_isDeclaration(C.kind))
8493 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008494
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008495 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008496 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008497 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008498 return (Method && Method->isStatic()) ? 1 : 0;
8499}
8500
8501unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8502 if (!clang_isDeclaration(C.kind))
8503 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008504
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008505 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008506 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008507 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008508 return (Method && Method->isVirtual()) ? 1 : 0;
8509}
Guy Benyei11169dd2012-12-18 14:30:41 +00008510
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008511unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8512 if (!clang_isDeclaration(C.kind))
8513 return 0;
8514
8515 const auto *D = cxcursor::getCursorDecl(C);
8516 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8517 if (RD)
8518 RD = RD->getDefinition();
8519 return (RD && RD->isAbstract()) ? 1 : 0;
8520}
8521
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008522unsigned clang_EnumDecl_isScoped(CXCursor C) {
8523 if (!clang_isDeclaration(C.kind))
8524 return 0;
8525
8526 const Decl *D = cxcursor::getCursorDecl(C);
8527 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8528 return (Enum && Enum->isScoped()) ? 1 : 0;
8529}
8530
Guy Benyei11169dd2012-12-18 14:30:41 +00008531//===----------------------------------------------------------------------===//
8532// Attribute introspection.
8533//===----------------------------------------------------------------------===//
8534
Guy Benyei11169dd2012-12-18 14:30:41 +00008535CXType clang_getIBOutletCollectionType(CXCursor C) {
8536 if (C.kind != CXCursor_IBOutletCollectionAttr)
8537 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008538
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008539 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008540 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8541
8542 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008543}
Guy Benyei11169dd2012-12-18 14:30:41 +00008544
8545//===----------------------------------------------------------------------===//
8546// Inspecting memory usage.
8547//===----------------------------------------------------------------------===//
8548
8549typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8550
8551static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008552 enum CXTUResourceUsageKind k,
8553 unsigned long amount) {
8554 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008555 entries.push_back(entry);
8556}
8557
Guy Benyei11169dd2012-12-18 14:30:41 +00008558const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8559 const char *str = "";
8560 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008561 case CXTUResourceUsage_AST:
8562 str = "ASTContext: expressions, declarations, and types";
8563 break;
8564 case CXTUResourceUsage_Identifiers:
8565 str = "ASTContext: identifiers";
8566 break;
8567 case CXTUResourceUsage_Selectors:
8568 str = "ASTContext: selectors";
8569 break;
8570 case CXTUResourceUsage_GlobalCompletionResults:
8571 str = "Code completion: cached global results";
8572 break;
8573 case CXTUResourceUsage_SourceManagerContentCache:
8574 str = "SourceManager: content cache allocator";
8575 break;
8576 case CXTUResourceUsage_AST_SideTables:
8577 str = "ASTContext: side tables";
8578 break;
8579 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8580 str = "SourceManager: malloc'ed memory buffers";
8581 break;
8582 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8583 str = "SourceManager: mmap'ed memory buffers";
8584 break;
8585 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8586 str = "ExternalASTSource: malloc'ed memory buffers";
8587 break;
8588 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8589 str = "ExternalASTSource: mmap'ed memory buffers";
8590 break;
8591 case CXTUResourceUsage_Preprocessor:
8592 str = "Preprocessor: malloc'ed memory";
8593 break;
8594 case CXTUResourceUsage_PreprocessingRecord:
8595 str = "Preprocessor: PreprocessingRecord";
8596 break;
8597 case CXTUResourceUsage_SourceManager_DataStructures:
8598 str = "SourceManager: data structures and tables";
8599 break;
8600 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8601 str = "Preprocessor: header search tables";
8602 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008603 }
8604 return str;
8605}
8606
8607CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008608 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008609 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008610 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008611 return usage;
8612 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008613
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008614 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008615 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008616 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008617
Guy Benyei11169dd2012-12-18 14:30:41 +00008618 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008619 createCXTUResourceUsageEntry(
8620 *entries, CXTUResourceUsage_AST,
8621 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008622
8623 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008624 createCXTUResourceUsageEntry(
8625 *entries, CXTUResourceUsage_Identifiers,
8626 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008627
8628 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008629 createCXTUResourceUsageEntry(
8630 *entries, CXTUResourceUsage_Selectors,
8631 (unsigned long)astContext.Selectors.getTotalMemory());
8632
Guy Benyei11169dd2012-12-18 14:30:41 +00008633 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008634 createCXTUResourceUsageEntry(
8635 *entries, CXTUResourceUsage_AST_SideTables,
8636 (unsigned long)astContext.getSideTableAllocatedMemory());
8637
Guy Benyei11169dd2012-12-18 14:30:41 +00008638 // How much memory is used for caching global code completion results?
8639 unsigned long completionBytes = 0;
8640 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008641 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008642 completionBytes = completionAllocator->getTotalMemory();
8643 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008644 createCXTUResourceUsageEntry(
8645 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8646
Guy Benyei11169dd2012-12-18 14:30:41 +00008647 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008648 createCXTUResourceUsageEntry(
8649 *entries, CXTUResourceUsage_SourceManagerContentCache,
8650 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8651
Guy Benyei11169dd2012-12-18 14:30:41 +00008652 // How much memory is being used by the MemoryBuffer's in SourceManager?
8653 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008654 astUnit->getSourceManager().getMemoryBufferSizes();
8655
Guy Benyei11169dd2012-12-18 14:30:41 +00008656 createCXTUResourceUsageEntry(*entries,
8657 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008658 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008659 createCXTUResourceUsageEntry(*entries,
8660 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008661 (unsigned long)srcBufs.mmap_bytes);
8662 createCXTUResourceUsageEntry(
8663 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8664 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8665
Guy Benyei11169dd2012-12-18 14:30:41 +00008666 // How much memory is being used by the ExternalASTSource?
8667 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8668 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008669 esrc->getMemoryBufferSizes();
8670
8671 createCXTUResourceUsageEntry(
8672 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8673 (unsigned long)sizes.malloc_bytes);
8674 createCXTUResourceUsageEntry(
8675 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8676 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008677 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008678
Guy Benyei11169dd2012-12-18 14:30:41 +00008679 // How much memory is being used by the Preprocessor?
8680 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008681 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008682 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008683
Guy Benyei11169dd2012-12-18 14:30:41 +00008684 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8685 createCXTUResourceUsageEntry(*entries,
8686 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008687 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008688 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008689
Guy Benyei11169dd2012-12-18 14:30:41 +00008690 createCXTUResourceUsageEntry(*entries,
8691 CXTUResourceUsage_Preprocessor_HeaderSearch,
8692 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008693
Michael Kruse7520cf02020-03-25 09:26:14 -05008694 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8695 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008696 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008697 return usage;
8698}
8699
8700void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8701 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008702 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008703}
8704
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008705CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8706 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008707 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008708 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008709
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008710 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008711 LOG_BAD_TU(TU);
8712 return skipped;
8713 }
8714
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008715 if (!file)
8716 return skipped;
8717
8718 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008719 PreprocessingRecord *ppRec =
8720 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008721 if (!ppRec)
8722 return skipped;
8723
8724 ASTContext &Ctx = astUnit->getASTContext();
8725 SourceManager &sm = Ctx.getSourceManager();
8726 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8727 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008728 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008729
8730 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8731 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008732 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8733 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008734 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008735 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8736 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008737 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008738 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8739 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008740 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008741 }
8742
8743 skipped->count = wantedRanges.size();
8744 skipped->ranges = new CXSourceRange[skipped->count];
8745 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8746 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8747
8748 return skipped;
8749}
8750
Cameron Desrochersd8091282016-08-18 15:43:55 +00008751CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8752 CXSourceRangeList *skipped = new CXSourceRangeList;
8753 skipped->count = 0;
8754 skipped->ranges = nullptr;
8755
8756 if (isNotUsableTU(TU)) {
8757 LOG_BAD_TU(TU);
8758 return skipped;
8759 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008760
Cameron Desrochersd8091282016-08-18 15:43:55 +00008761 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008762 PreprocessingRecord *ppRec =
8763 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008764 if (!ppRec)
8765 return skipped;
8766
8767 ASTContext &Ctx = astUnit->getASTContext();
8768
8769 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8770
8771 skipped->count = SkippedRanges.size();
8772 skipped->ranges = new CXSourceRange[skipped->count];
8773 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8774 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8775
8776 return skipped;
8777}
8778
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008779void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8780 if (ranges) {
8781 delete[] ranges->ranges;
8782 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008783 }
8784}
8785
Guy Benyei11169dd2012-12-18 14:30:41 +00008786void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8787 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8788 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008789 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008790 clang_getTUResourceUsageName(Usage.entries[I].kind),
8791 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008792
Guy Benyei11169dd2012-12-18 14:30:41 +00008793 clang_disposeCXTUResourceUsage(Usage);
8794}
8795
8796//===----------------------------------------------------------------------===//
8797// Misc. utility functions.
8798//===----------------------------------------------------------------------===//
8799
Richard Smith0a7b2972018-07-03 21:34:13 +00008800/// Default to using our desired 8 MB stack size on "safety" threads.
8801static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008802
8803namespace clang {
8804
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008805bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008806 unsigned Size) {
8807 if (!Size)
8808 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008809 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008810 return CRC.RunSafelyOnThread(Fn, Size);
8811 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008812}
8813
Michael Kruse7520cf02020-03-25 09:26:14 -05008814unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008815
Michael Kruse7520cf02020-03-25 09:26:14 -05008816void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008817
Michael Kruse7520cf02020-03-25 09:26:14 -05008818} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008819
8820void clang::setThreadBackgroundPriority() {
8821 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8822 return;
8823
Nico Weber18cfd9f2019-04-21 19:18:41 +00008824#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008825 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008826#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008827}
8828
8829void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8830 if (!Unit)
8831 return;
8832
Michael Kruse7520cf02020-03-25 09:26:14 -05008833 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8834 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008835 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008836 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008837 CXString Msg =
8838 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008839 fprintf(stderr, "%s\n", clang_getCString(Msg));
8840 clang_disposeString(Msg);
8841 }
Nico Weber1865df42018-04-27 19:11:14 +00008842#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008843 // On Windows, force a flush, since there may be multiple copies of
8844 // stderr and stdout in the file system, all with different buffers
8845 // but writing to the same device.
8846 fflush(stderr);
8847#endif
8848}
8849
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008850MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8851 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008852 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008853 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008854 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008855 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008856 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008857
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008858 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008859 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008860 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008861 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008862 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8863 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008864 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8865 return Def.getMacroInfo();
8866 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008867 }
8868
Craig Topper69186e72014-06-08 08:38:04 +00008869 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008870}
8871
Richard Smith66a81862015-05-04 02:25:31 +00008872const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008873 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008874 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008875 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008876 const IdentifierInfo *II = MacroDef->getName();
8877 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008878 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008879
8880 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8881}
8882
Richard Smith66a81862015-05-04 02:25:31 +00008883MacroDefinitionRecord *
8884cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8885 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008886 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008887 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008888 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008889 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008890
8891 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008892 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008893 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8894 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008895 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008896
8897 // Check that the token is inside the definition and not its argument list.
8898 SourceManager &SM = Unit->getSourceManager();
8899 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008900 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008901 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00008902 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008903
8904 Preprocessor &PP = Unit->getPreprocessor();
8905 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
8906 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00008907 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008908
Alp Toker2d57cea2014-05-17 04:53:25 +00008909 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008910 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008911 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008912
8913 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00008914 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00008915 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008916
Richard Smith20e883e2015-04-29 23:20:19 +00008917 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00008918 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00008919 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008920
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008921 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008922}
8923
Richard Smith66a81862015-05-04 02:25:31 +00008924MacroDefinitionRecord *
8925cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
8926 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008927 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008928 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008929
8930 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008931 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008932 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008933 Preprocessor &PP = Unit->getPreprocessor();
8934 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00008935 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008936 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
8937 Token Tok;
8938 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00008939 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008940
8941 return checkForMacroInMacroDefinition(MI, Tok, TU);
8942}
8943
Guy Benyei11169dd2012-12-18 14:30:41 +00008944CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008945 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00008946}
8947
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008948Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
8949 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008950 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008951 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00008952 if (Unit->isMainFileAST())
8953 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008954 return *this;
8955 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00008956 } else {
8957 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008958 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008959 return *this;
8960}
8961
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00008962Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
8963 *this << FE->getName();
8964 return *this;
8965}
8966
8967Logger &cxindex::Logger::operator<<(CXCursor cursor) {
8968 CXString cursorName = clang_getCursorDisplayName(cursor);
8969 *this << cursorName << "@" << clang_getCursorLocation(cursor);
8970 clang_disposeString(cursorName);
8971 return *this;
8972}
8973
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008974Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
8975 CXFile File;
8976 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00008977 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008978 CXString FileName = clang_getFileName(File);
8979 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
8980 clang_disposeString(FileName);
8981 return *this;
8982}
8983
8984Logger &cxindex::Logger::operator<<(CXSourceRange range) {
8985 CXSourceLocation BLoc = clang_getRangeStart(range);
8986 CXSourceLocation ELoc = clang_getRangeEnd(range);
8987
8988 CXFile BFile;
8989 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00008990 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008991
8992 CXFile EFile;
8993 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00008994 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00008995
8996 CXString BFileName = clang_getFileName(BFile);
8997 if (BFile == EFile) {
8998 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05008999 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009000 } else {
9001 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009002 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9003 BColumn)
9004 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9005 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009006 clang_disposeString(EFileName);
9007 }
9008 clang_disposeString(BFileName);
9009 return *this;
9010}
9011
9012Logger &cxindex::Logger::operator<<(CXString Str) {
9013 *this << clang_getCString(Str);
9014 return *this;
9015}
9016
9017Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9018 LogOS << Fmt;
9019 return *this;
9020}
9021
Benjamin Kramer762bc332019-08-07 14:44:40 +00009022static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009023
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009024cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009025 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009026
9027 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9028
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009029 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009030 OS << "[libclang:" << Name << ':';
9031
Alp Toker1a86ad22014-07-06 06:24:00 +00009032#ifdef USE_DARWIN_THREADS
9033 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009034 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9035 OS << tid << ':';
9036#endif
9037
9038 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9039 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009040 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009041
9042 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009043 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009044 OS << "--------------------------------------------------\n";
9045 }
9046}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009047
9048#ifdef CLANG_TOOL_EXTRA_BUILD
9049// This anchor is used to force the linker to link the clang-tidy plugin.
9050extern volatile int ClangTidyPluginAnchorSource;
9051static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9052 ClangTidyPluginAnchorSource;
9053
9054// This anchor is used to force the linker to link the clang-include-fixer
9055// plugin.
9056extern volatile int ClangIncludeFixerPluginAnchorSource;
9057static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9058 ClangIncludeFixerPluginAnchorSource;
9059#endif