blob: 93f9797a965ec81a20e5b9c859f201ec607849e3 [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"
Puyan Lotfi9721fbf2020-04-23 02:20:56 -040025#include "clang/AST/DeclObjCCommon.h"
Jan Korous7e36ecd2019-09-05 20:33:52 +000026#include "clang/AST/Mangle.h"
Alexey Bataev95598342020-02-10 15:49:05 -050027#include "clang/AST/OpenMPClause.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000028#include "clang/AST/StmtVisitor.h"
29#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000030#include "clang/Basic/DiagnosticCategories.h"
31#include "clang/Basic/DiagnosticIDs.h"
Richard Smith0a7b2972018-07-03 21:34:13 +000032#include "clang/Basic/Stack.h"
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +000033#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Basic/Version.h"
35#include "clang/Frontend/ASTUnit.h"
36#include "clang/Frontend/CompilerInstance.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000037#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000038#include "clang/Lex/HeaderSearch.h"
39#include "clang/Lex/Lexer.h"
40#include "clang/Lex/PreprocessingRecord.h"
41#include "clang/Lex/Preprocessor.h"
42#include "llvm/ADT/Optional.h"
43#include "llvm/ADT/STLExtras.h"
44#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000045#include "llvm/Config/llvm-config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000046#include "llvm/Support/Compiler.h"
47#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000048#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000049#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000050#include "llvm/Support/MemoryBuffer.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/Program.h"
52#include "llvm/Support/SaveAndRestore.h"
53#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000054#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000055#include "llvm/Support/Threading.h"
56#include "llvm/Support/Timer.h"
57#include "llvm/Support/raw_ostream.h"
Benjamin Kramer762bc332019-08-07 14:44:40 +000058#include <mutex>
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000059
Alp Toker1a86ad22014-07-06 06:24:00 +000060#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
61#define USE_DARWIN_THREADS
62#endif
63
64#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000065#include <pthread.h>
66#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000067
68using namespace clang;
69using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000070using namespace clang::cxtu;
71using namespace clang::cxindex;
72
David Blaikieea4395e2017-01-06 19:49:01 +000073CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,
74 std::unique_ptr<ASTUnit> AU) {
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000075 if (!AU)
Craig Topper69186e72014-06-08 08:38:04 +000076 return nullptr;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000077 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000078 CXTranslationUnit D = new CXTranslationUnitImpl();
79 D->CIdx = CIdx;
David Blaikieea4395e2017-01-06 19:49:01 +000080 D->TheASTUnit = AU.release();
Dmitri Gribenko74895212013-02-03 13:52:47 +000081 D->StringPool = new cxstring::CXStringPool();
Craig Topper69186e72014-06-08 08:38:04 +000082 D->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +000083 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Craig Topper69186e72014-06-08 08:38:04 +000084 D->CommentToXML = nullptr;
Alex Lorenz690f0e22017-12-07 20:37:50 +000085 D->ParsingOptions = 0;
86 D->Arguments = {};
Guy Benyei11169dd2012-12-18 14:30:41 +000087 return D;
88}
89
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000090bool cxtu::isASTReadError(ASTUnit *AU) {
91 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
92 DEnd = AU->stored_diag_end();
93 D != DEnd; ++D) {
94 if (D->getLevel() >= DiagnosticsEngine::Error &&
95 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
96 diag::DiagCat_AST_Deserialization_Issue)
97 return true;
98 }
99 return false;
100}
101
Guy Benyei11169dd2012-12-18 14:30:41 +0000102cxtu::CXTUOwner::~CXTUOwner() {
103 if (TU)
104 clang_disposeTranslationUnit(TU);
105}
106
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000107/// Compare two source ranges to determine their relative position in
Guy Benyei11169dd2012-12-18 14:30:41 +0000108/// the translation unit.
Michael Kruse7520cf02020-03-25 09:26:14 -0500109static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1,
Guy Benyei11169dd2012-12-18 14:30:41 +0000110 SourceRange R2) {
111 assert(R1.isValid() && "First range is invalid?");
112 assert(R2.isValid() && "Second range is invalid?");
113 if (R1.getEnd() != R2.getBegin() &&
114 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
115 return RangeBefore;
116 if (R2.getEnd() != R1.getBegin() &&
117 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
118 return RangeAfter;
119 return RangeOverlap;
120}
121
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000122/// Determine if a source location falls within, before, or after a
Guy Benyei11169dd2012-12-18 14:30:41 +0000123/// a given source range.
124static RangeComparisonResult LocationCompare(SourceManager &SM,
125 SourceLocation L, SourceRange R) {
126 assert(R.isValid() && "First range is invalid?");
127 assert(L.isValid() && "Second range is invalid?");
128 if (L == R.getBegin() || L == R.getEnd())
129 return RangeOverlap;
130 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
131 return RangeBefore;
132 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
133 return RangeAfter;
134 return RangeOverlap;
135}
136
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000137/// Translate a Clang source range into a CIndex source range.
Guy Benyei11169dd2012-12-18 14:30:41 +0000138///
139/// Clang internally represents ranges where the end location points to the
140/// start of the token at the end. However, for external clients it is more
141/// useful to have a CXSourceRange be a proper half-open interval. This routine
142/// does the appropriate translation.
143CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
144 const LangOptions &LangOpts,
145 const CharSourceRange &R) {
146 // We want the last character in this location, so we will adjust the
147 // location accordingly.
148 SourceLocation EndLoc = R.getEnd();
Richard Smithb5f81712018-04-30 05:25:48 +0000149 bool IsTokenRange = R.isTokenRange();
Michael Kruse7520cf02020-03-25 09:26:14 -0500150 if (EndLoc.isValid() && EndLoc.isMacroID() &&
151 !SM.isMacroArgExpansion(EndLoc)) {
Richard Smithb5f81712018-04-30 05:25:48 +0000152 CharSourceRange Expansion = SM.getExpansionRange(EndLoc);
153 EndLoc = Expansion.getEnd();
154 IsTokenRange = Expansion.isTokenRange();
155 }
156 if (IsTokenRange && EndLoc.isValid()) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500157 unsigned Length =
158 Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);
Guy Benyei11169dd2012-12-18 14:30:41 +0000159 EndLoc = EndLoc.getLocWithOffset(Length);
160 }
161
Bill Wendlingeade3622013-01-23 08:25:41 +0000162 CXSourceRange Result = {
Michael Kruse7520cf02020-03-25 09:26:14 -0500163 {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};
Guy Benyei11169dd2012-12-18 14:30:41 +0000164 return Result;
165}
166
167//===----------------------------------------------------------------------===//
168// Cursor visitor.
169//===----------------------------------------------------------------------===//
170
171static SourceRange getRawCursorExtent(CXCursor C);
172static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
173
Guy Benyei11169dd2012-12-18 14:30:41 +0000174RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
175 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
176}
177
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000178/// Visit the given cursor and, if requested by the visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +0000179/// its children.
180///
181/// \param Cursor the cursor to visit.
182///
183/// \param CheckedRegionOfInterest if true, then the caller already checked
184/// that this cursor is within the region of interest.
185///
186/// \returns true if the visitation should be aborted, false if it
187/// should continue.
188bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
189 if (clang_isInvalid(Cursor.kind))
190 return false;
191
192 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000193 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000194 if (!D) {
195 assert(0 && "Invalid declaration cursor");
196 return true; // abort.
197 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500198
Guy Benyei11169dd2012-12-18 14:30:41 +0000199 // Ignore implicit declarations, unless it's an objc method because
200 // currently we should report implicit methods for properties when indexing.
201 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
202 return false;
203 }
204
205 // If we have a range of interest, and this cursor doesn't intersect with it,
206 // we're done.
207 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
208 SourceRange Range = getRawCursorExtent(Cursor);
209 if (Range.isInvalid() || CompareRegionOfInterest(Range))
210 return false;
211 }
212
213 switch (Visitor(Cursor, Parent, ClientData)) {
214 case CXChildVisit_Break:
215 return true;
216
217 case CXChildVisit_Continue:
218 return false;
219
220 case CXChildVisit_Recurse: {
221 bool ret = VisitChildren(Cursor);
222 if (PostChildrenVisitor)
223 if (PostChildrenVisitor(Cursor, ClientData))
224 return true;
225 return ret;
226 }
227 }
228
229 llvm_unreachable("Invalid CXChildVisitResult!");
230}
231
232static bool visitPreprocessedEntitiesInRange(SourceRange R,
233 PreprocessingRecord &PPRec,
234 CursorVisitor &Visitor) {
235 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
236 FileID FID;
Michael Kruse7520cf02020-03-25 09:26:14 -0500237
Guy Benyei11169dd2012-12-18 14:30:41 +0000238 if (!Visitor.shouldVisitIncludedEntities()) {
239 // If the begin/end of the range lie in the same FileID, do the optimization
Michael Kruse7520cf02020-03-25 09:26:14 -0500240 // where we skip preprocessed entities that do not come from the same
241 // FileID.
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
243 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
244 FID = FileID();
245 }
246
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000247 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
248 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000249 PPRec, FID);
250}
251
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000252bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000253 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000254 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000255
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000256 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000257 SourceManager &SM = Unit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -0500258
259 std::pair<FileID, unsigned> Begin = SM.getDecomposedLoc(
260 SM.getFileLoc(RegionOfInterest.getBegin())),
261 End = SM.getDecomposedLoc(
262 SM.getFileLoc(RegionOfInterest.getEnd()));
Guy Benyei11169dd2012-12-18 14:30:41 +0000263
264 if (End.first != Begin.first) {
265 // If the end does not reside in the same file, try to recover by
266 // picking the end of the file of begin location.
267 End.first = Begin.first;
268 End.second = SM.getFileIDSize(Begin.first);
269 }
270
271 assert(Begin.first == End.first);
272 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000273 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -0500274
Guy Benyei11169dd2012-12-18 14:30:41 +0000275 FileID File = Begin.first;
276 unsigned Offset = Begin.second;
277 unsigned Length = End.second - Begin.second;
278
279 if (!VisitDeclsOnly && !VisitPreprocessorLast)
280 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000281 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000282
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 if (visitDeclsFromFileRegion(File, Offset, Length))
284 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000285
286 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000287 return visitPreprocessedEntitiesInRegion();
288
289 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000290}
291
292static bool isInLexicalContext(Decl *D, DeclContext *DC) {
293 if (!DC)
294 return false;
295
Michael Kruse7520cf02020-03-25 09:26:14 -0500296 for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;
297 DeclDC = DeclDC->getLexicalParent()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000298 if (DeclDC == DC)
299 return true;
300 }
301 return false;
302}
303
Michael Kruse7520cf02020-03-25 09:26:14 -0500304bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,
305 unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000306 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000307 SourceManager &SM = Unit->getSourceManager();
308 SourceRange Range = RegionOfInterest;
309
310 SmallVector<Decl *, 16> Decls;
311 Unit->findFileRegionDecls(File, Offset, Length, Decls);
312
313 // If we didn't find any file level decls for the file, try looking at the
314 // file that it was included from.
315 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
316 bool Invalid = false;
317 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
318 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000319 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000320
321 SourceLocation Outer;
322 if (SLEntry.isFile())
323 Outer = SLEntry.getFile().getIncludeLoc();
324 else
325 Outer = SLEntry.getExpansion().getExpansionLocStart();
326 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000327 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000328
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000329 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000330 Length = 0;
331 Unit->findFileRegionDecls(File, Offset, Length, Decls);
332 }
333
334 assert(!Decls.empty());
335
336 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000337 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000338 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
339 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000340 Decl *D = *DIt;
341 if (D->getSourceRange().isInvalid())
342 continue;
343
344 if (isInLexicalContext(D, CurDC))
345 continue;
346
347 CurDC = dyn_cast<DeclContext>(D);
348
349 if (TagDecl *TD = dyn_cast<TagDecl>(D))
350 if (!TD->isFreeStanding())
351 continue;
352
Michael Kruse7520cf02020-03-25 09:26:14 -0500353 RangeComparisonResult CompRes =
354 RangeCompare(SM, D->getSourceRange(), Range);
Guy Benyei11169dd2012-12-18 14:30:41 +0000355 if (CompRes == RangeBefore)
356 continue;
357 if (CompRes == RangeAfter)
358 break;
359
360 assert(CompRes == RangeOverlap);
361 VisitedAtLeastOnce = true;
362
363 if (isa<ObjCContainerDecl>(D)) {
364 FileDI_current = &DIt;
365 FileDE_current = DE;
366 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000367 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000368 }
369
370 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000371 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000372 }
373
374 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000375 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000376
377 // No Decls overlapped with the range. Move up the lexical context until there
378 // is a context that contains the range or we reach the translation unit
379 // level.
Michael Kruse7520cf02020-03-25 09:26:14 -0500380 DeclContext *DC = DIt == Decls.begin()
381 ? (*DIt)->getLexicalDeclContext()
382 : (*(DIt - 1))->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +0000383
384 while (DC && !DC->isTranslationUnit()) {
385 Decl *D = cast<Decl>(DC);
386 SourceRange CurDeclRange = D->getSourceRange();
387 if (CurDeclRange.isInvalid())
388 break;
389
390 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
392 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000393 }
394
395 DC = D->getLexicalDeclContext();
396 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000397
398 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000399}
400
401bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
402 if (!AU->getPreprocessor().getPreprocessingRecord())
403 return false;
404
Michael Kruse7520cf02020-03-25 09:26:14 -0500405 PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();
Guy Benyei11169dd2012-12-18 14:30:41 +0000406 SourceManager &SM = AU->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -0500407
Guy Benyei11169dd2012-12-18 14:30:41 +0000408 if (RegionOfInterest.isValid()) {
409 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
410 SourceLocation B = MappedRange.getBegin();
411 SourceLocation E = MappedRange.getEnd();
412
413 if (AU->isInPreambleFileID(B)) {
414 if (SM.isLoadedSourceLocation(E))
Michael Kruse7520cf02020-03-25 09:26:14 -0500415 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,
416 *this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000417
418 // Beginning of range lies in the preamble but it also extends beyond
419 // it into the main file. Split the range into 2 parts, one covering
420 // the preamble and another covering the main file. This allows subsequent
421 // calls to visitPreprocessedEntitiesInRange to accept a source range that
422 // lies in the same FileID, allowing it to skip preprocessed entities that
423 // do not come from the same FileID.
Michael Kruse7520cf02020-03-25 09:26:14 -0500424 bool breaked = visitPreprocessedEntitiesInRange(
425 SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);
426 if (breaked)
427 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000428 return visitPreprocessedEntitiesInRange(
Michael Kruse7520cf02020-03-25 09:26:14 -0500429 SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000430 }
431
432 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
433 }
434
Michael Kruse7520cf02020-03-25 09:26:14 -0500435 bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
436
Guy Benyei11169dd2012-12-18 14:30:41 +0000437 if (OnlyLocalDecls)
438 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
439 PPRec);
440
441 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
442}
443
Michael Kruse7520cf02020-03-25 09:26:14 -0500444template <typename InputIterator>
Guy Benyei11169dd2012-12-18 14:30:41 +0000445bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
446 InputIterator Last,
447 PreprocessingRecord &PPRec,
448 FileID FID) {
449 for (; First != Last; ++First) {
450 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
451 continue;
452
453 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000454 if (!PPE)
455 continue;
456
Guy Benyei11169dd2012-12-18 14:30:41 +0000457 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
458 if (Visit(MakeMacroExpansionCursor(ME, TU)))
459 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000460
Guy Benyei11169dd2012-12-18 14:30:41 +0000461 continue;
462 }
Richard Smith66a81862015-05-04 02:25:31 +0000463
464 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000465 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
466 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000467
Guy Benyei11169dd2012-12-18 14:30:41 +0000468 continue;
469 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500470
Guy Benyei11169dd2012-12-18 14:30:41 +0000471 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
472 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
473 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500474
Guy Benyei11169dd2012-12-18 14:30:41 +0000475 continue;
476 }
477 }
478
479 return false;
480}
481
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000482/// Visit the children of the given cursor.
Michael Kruse7520cf02020-03-25 09:26:14 -0500483///
Guy Benyei11169dd2012-12-18 14:30:41 +0000484/// \returns true if the visitation should be aborted, false if it
485/// should continue.
486bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500487 if (clang_isReference(Cursor.kind) &&
Guy Benyei11169dd2012-12-18 14:30:41 +0000488 Cursor.kind != CXCursor_CXXBaseSpecifier) {
489 // By definition, references have no children.
490 return false;
491 }
492
493 // Set the Parent field to Cursor, then back to its old value once we're
494 // done.
495 SetParentRAII SetParent(Parent, StmtParent, Cursor);
496
497 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000498 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000499 if (!D)
500 return false;
501
502 return VisitAttributes(D) || Visit(D);
503 }
504
505 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000506 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000507 return Visit(S);
508
509 return false;
510 }
511
512 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000513 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000514 return Visit(E);
515
516 return false;
517 }
518
519 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000520 CXTranslationUnit TU = getCursorTU(Cursor);
521 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -0500522
523 int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
Guy Benyei11169dd2012-12-18 14:30:41 +0000524 for (unsigned I = 0; I != 2; ++I) {
525 if (VisitOrder[I]) {
526 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
527 RegionOfInterest.isInvalid()) {
528 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -0500529 TLEnd = CXXUnit->top_level_end();
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 TL != TLEnd; ++TL) {
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000531 const Optional<bool> V = handleDeclForVisitation(*TL);
532 if (!V.hasValue())
533 continue;
534 return V.getValue();
Guy Benyei11169dd2012-12-18 14:30:41 +0000535 }
536 } else if (VisitDeclContext(
Michael Kruse7520cf02020-03-25 09:26:14 -0500537 CXXUnit->getASTContext().getTranslationUnitDecl()))
Guy Benyei11169dd2012-12-18 14:30:41 +0000538 return true;
539 continue;
540 }
541
542 // Walk the preprocessing record.
543 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
544 visitPreprocessedEntitiesInRegion();
545 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500546
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 return false;
548 }
549
550 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000551 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
553 return Visit(BaseTSInfo->getTypeLoc());
554 }
555 }
556 }
557
558 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000559 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -0500560 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000561 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000562 return Visit(cxcursor::MakeCursorObjCClassRef(
563 ObjT->getInterface(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000564 A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000565 }
566
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000567 // If pointing inside a macro definition, check if the token is an identifier
568 // that was ever defined as a macro. In such a case, create a "pseudo" macro
569 // expansion cursor for that token.
570 SourceLocation BeginLoc = RegionOfInterest.getBegin();
571 if (Cursor.kind == CXCursor_MacroDefinition &&
572 BeginLoc == RegionOfInterest.getEnd()) {
573 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000574 const MacroInfo *MI =
575 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000576 if (MacroDefinitionRecord *MacroDef =
577 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000578 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
579 }
580
Guy Benyei11169dd2012-12-18 14:30:41 +0000581 // Nothing to visit at the moment.
582 return false;
583}
584
585bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
586 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
587 if (Visit(TSInfo->getTypeLoc()))
Michael Kruse7520cf02020-03-25 09:26:14 -0500588 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 if (Stmt *Body = B->getBody())
591 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
592
593 return false;
594}
595
Ted Kremenek03325582013-02-21 01:29:01 +0000596Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000597 if (RegionOfInterest.isValid()) {
598 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
599 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000600 return None;
Michael Kruse7520cf02020-03-25 09:26:14 -0500601
Guy Benyei11169dd2012-12-18 14:30:41 +0000602 switch (CompareRegionOfInterest(Range)) {
603 case RangeBefore:
604 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000605 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000606
607 case RangeAfter:
608 // This declaration comes after the region of interest; we're done.
609 return false;
610
611 case RangeOverlap:
612 // This declaration overlaps the region of interest; visit it.
613 break;
614 }
615 }
616 return true;
617}
618
619bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
620 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
621
622 // FIXME: Eventually remove. This part of a hack to support proper
623 // iteration over all Decls contained lexically within an ObjC container.
Michael Kruse7520cf02020-03-25 09:26:14 -0500624 SaveAndRestore<DeclContext::decl_iterator *> DI_saved(DI_current, &I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000625 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
626
Michael Kruse7520cf02020-03-25 09:26:14 -0500627 for (; I != E; ++I) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000628 Decl *D = *I;
629 if (D->getLexicalDeclContext() != DC)
630 continue;
Adrian Prantl2073dd22019-11-04 14:28:14 -0800631 // Filter out synthesized property accessor redeclarations.
632 if (isa<ObjCImplDecl>(DC))
633 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
634 if (OMD->isSynthesizedAccessorStub())
635 continue;
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000636 const Optional<bool> V = handleDeclForVisitation(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000637 if (!V.hasValue())
638 continue;
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000639 return V.getValue();
Guy Benyei11169dd2012-12-18 14:30:41 +0000640 }
641 return false;
642}
643
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000644Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
645 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
646
647 // Ignore synthesized ivars here, otherwise if we have something like:
648 // @synthesize prop = _prop;
649 // and '_prop' is not declared, we will encounter a '_prop' ivar before
650 // encountering the 'prop' synthesize declaration and we will think that
651 // we passed the region-of-interest.
652 if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
653 if (ivarD->getSynthesize())
654 return None;
655 }
656
657 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
658 // declarations is a mismatch with the compiler semantics.
659 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
660 auto *ID = cast<ObjCInterfaceDecl>(D);
661 if (!ID->isThisDeclarationADefinition())
662 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
663
664 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
665 auto *PD = cast<ObjCProtocolDecl>(D);
666 if (!PD->isThisDeclarationADefinition())
667 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
668 }
669
670 const Optional<bool> V = shouldVisitCursor(Cursor);
671 if (!V.hasValue())
672 return None;
673 if (!V.getValue())
674 return false;
675 if (Visit(Cursor, true))
676 return true;
677 return None;
678}
679
Guy Benyei11169dd2012-12-18 14:30:41 +0000680bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
681 llvm_unreachable("Translation units are visited directly by Visit()");
682}
683
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000684bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500685 if (VisitTemplateParameters(D->getTemplateParameters()))
686 return true;
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000687
Michael Kruse7520cf02020-03-25 09:26:14 -0500688 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000689}
690
Guy Benyei11169dd2012-12-18 14:30:41 +0000691bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
692 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
693 return Visit(TSInfo->getTypeLoc());
694
695 return false;
696}
697
698bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
699 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
700 return Visit(TSInfo->getTypeLoc());
701
702 return false;
703}
704
Michael Kruse7520cf02020-03-25 09:26:14 -0500705bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }
Guy Benyei11169dd2012-12-18 14:30:41 +0000706
707bool CursorVisitor::VisitClassTemplateSpecializationDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -0500708 ClassTemplateSpecializationDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000709 bool ShouldVisitBody = false;
710 switch (D->getSpecializationKind()) {
711 case TSK_Undeclared:
712 case TSK_ImplicitInstantiation:
713 // Nothing to visit
714 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -0500715
Guy Benyei11169dd2012-12-18 14:30:41 +0000716 case TSK_ExplicitInstantiationDeclaration:
717 case TSK_ExplicitInstantiationDefinition:
718 break;
Michael Kruse7520cf02020-03-25 09:26:14 -0500719
Guy Benyei11169dd2012-12-18 14:30:41 +0000720 case TSK_ExplicitSpecialization:
721 ShouldVisitBody = true;
722 break;
723 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500724
Guy Benyei11169dd2012-12-18 14:30:41 +0000725 // Visit the template arguments used in the specialization.
726 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
727 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000728 if (TemplateSpecializationTypeLoc TSTLoc =
729 TL.getAs<TemplateSpecializationTypeLoc>()) {
730 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
731 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000732 return true;
733 }
734 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000735
736 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000737}
738
739bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -0500740 ClassTemplatePartialSpecializationDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000741 // FIXME: Visit the "outer" template parameter lists on the TagDecl
742 // before visiting these template parameters.
743 if (VisitTemplateParameters(D->getTemplateParameters()))
744 return true;
745
746 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000747 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
748 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
749 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000750 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
751 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 return VisitCXXRecordDecl(D);
754}
755
756bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Saar Razff1e0fc2020-01-15 02:48:42 +0200757 if (const auto *TC = D->getTypeConstraint())
758 if (Visit(MakeCXCursor(TC->getImmediatelyDeclaredConstraint(), StmtParent,
759 TU, RegionOfInterest)))
760 return true;
761
Guy Benyei11169dd2012-12-18 14:30:41 +0000762 // Visit the default argument.
763 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
764 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
765 if (Visit(DefArg->getTypeLoc()))
766 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500767
Guy Benyei11169dd2012-12-18 14:30:41 +0000768 return false;
769}
770
771bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
772 if (Expr *Init = D->getInitExpr())
773 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
774 return false;
775}
776
777bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000778 unsigned NumParamList = DD->getNumTemplateParameterLists();
779 for (unsigned i = 0; i < NumParamList; i++) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500780 TemplateParameterList *Params = DD->getTemplateParameterList(i);
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000781 if (VisitTemplateParameters(Params))
782 return true;
783 }
784
Guy Benyei11169dd2012-12-18 14:30:41 +0000785 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
786 if (Visit(TSInfo->getTypeLoc()))
787 return true;
788
789 // Visit the nested-name-specifier, if present.
790 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
791 if (VisitNestedNameSpecifierLoc(QualifierLoc))
792 return true;
793
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000794 return false;
795}
796
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000797static bool HasTrailingReturnType(FunctionDecl *ND) {
798 const QualType Ty = ND->getType();
799 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
800 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
801 return FT->hasTrailingReturn();
802 }
803
804 return false;
805}
806
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000807/// Compare two base or member initializers based on their source order.
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000808static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
809 CXXCtorInitializer *const *Y) {
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000810 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
811}
812
Guy Benyei11169dd2012-12-18 14:30:41 +0000813bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000814 unsigned NumParamList = ND->getNumTemplateParameterLists();
815 for (unsigned i = 0; i < NumParamList; i++) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500816 TemplateParameterList *Params = ND->getTemplateParameterList(i);
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000817 if (VisitTemplateParameters(Params))
818 return true;
819 }
820
Guy Benyei11169dd2012-12-18 14:30:41 +0000821 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
822 // Visit the function declaration's syntactic components in the order
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000823 // written. This requires a bit of work.
824 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
825 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000826 const bool HasTrailingRT = HasTrailingReturnType(ND);
Michael Kruse7520cf02020-03-25 09:26:14 -0500827
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000828 // If we have a function declared directly (without the use of a typedef),
829 // visit just the return type. Otherwise, just visit the function's type
830 // now.
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000831 if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
832 Visit(FTL.getReturnLoc())) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000833 (!FTL && Visit(TL)))
834 return true;
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000835
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000836 // Visit the nested-name-specifier, if present.
837 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
838 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +0000839 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500840
Guy Benyei11169dd2012-12-18 14:30:41 +0000841 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000842 if (!isa<CXXDestructorDecl>(ND))
843 if (VisitDeclarationNameInfo(ND->getNameInfo()))
844 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500845
Guy Benyei11169dd2012-12-18 14:30:41 +0000846 // FIXME: Visit explicitly-specified template arguments!
Michael Kruse7520cf02020-03-25 09:26:14 -0500847
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000848 // Visit the function parameters, if we have a function type.
849 if (FTL && VisitFunctionTypeLoc(FTL, true))
850 return true;
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000851
852 // Visit the function's trailing return type.
853 if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
854 return true;
855
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000856 // FIXME: Attributes?
857 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500858
Guy Benyei11169dd2012-12-18 14:30:41 +0000859 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
860 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
861 // Find the initializers that were written in the source.
862 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000863 for (auto *I : Constructor->inits()) {
864 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000865 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -0500866
Aaron Ballman0ad78302014-03-13 17:34:31 +0000867 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000868 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500869
Guy Benyei11169dd2012-12-18 14:30:41 +0000870 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000871 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
872 &CompareCXXCtorInitializers);
Michael Kruse7520cf02020-03-25 09:26:14 -0500873
Guy Benyei11169dd2012-12-18 14:30:41 +0000874 // Visit the initializers in source order
875 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
876 CXXCtorInitializer *Init = WrittenInits[I];
877 if (Init->isAnyMemberInitializer()) {
878 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
879 Init->getMemberLocation(), TU)))
880 return true;
881 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
882 if (Visit(TInfo->getTypeLoc()))
883 return true;
884 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500885
Guy Benyei11169dd2012-12-18 14:30:41 +0000886 // Visit the initializer value.
887 if (Expr *Initializer = Init->getInit())
888 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
889 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500890 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000891 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500892
Guy Benyei11169dd2012-12-18 14:30:41 +0000893 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
894 return true;
895 }
896
897 return false;
898}
899
900bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
901 if (VisitDeclaratorDecl(D))
902 return true;
903
904 if (Expr *BitWidth = D->getBitWidth())
905 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
906
Benjamin Kramer99f97592017-11-15 12:20:41 +0000907 if (Expr *Init = D->getInClassInitializer())
908 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
909
Guy Benyei11169dd2012-12-18 14:30:41 +0000910 return false;
911}
912
913bool CursorVisitor::VisitVarDecl(VarDecl *D) {
914 if (VisitDeclaratorDecl(D))
915 return true;
916
917 if (Expr *Init = D->getInit())
918 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
919
920 return false;
921}
922
923bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
924 if (VisitDeclaratorDecl(D))
925 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500926
Guy Benyei11169dd2012-12-18 14:30:41 +0000927 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
928 if (Expr *DefArg = D->getDefaultArgument())
929 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
Michael Kruse7520cf02020-03-25 09:26:14 -0500930
931 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000932}
933
934bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
935 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
936 // before visiting these template parameters.
937 if (VisitTemplateParameters(D->getTemplateParameters()))
938 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500939
940 auto *FD = D->getTemplatedDecl();
Jonathan Coe578ac7a2017-10-16 23:43:02 +0000941 return VisitAttributes(FD) || VisitFunctionDecl(FD);
Guy Benyei11169dd2012-12-18 14:30:41 +0000942}
943
944bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
945 // FIXME: Visit the "outer" template parameter lists on the TagDecl
946 // before visiting these template parameters.
947 if (VisitTemplateParameters(D->getTemplateParameters()))
948 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500949
950 auto *CD = D->getTemplatedDecl();
Jonathan Coe578ac7a2017-10-16 23:43:02 +0000951 return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
Guy Benyei11169dd2012-12-18 14:30:41 +0000952}
953
954bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
955 if (VisitTemplateParameters(D->getTemplateParameters()))
956 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500957
Guy Benyei11169dd2012-12-18 14:30:41 +0000958 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
959 VisitTemplateArgumentLoc(D->getDefaultArgument()))
960 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500961
Guy Benyei11169dd2012-12-18 14:30:41 +0000962 return false;
963}
964
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000965bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
966 // Visit the bound, if it's explicit.
967 if (D->hasExplicitBound()) {
968 if (auto TInfo = D->getTypeSourceInfo()) {
969 if (Visit(TInfo->getTypeLoc()))
970 return true;
971 }
972 }
973
974 return false;
975}
976
Guy Benyei11169dd2012-12-18 14:30:41 +0000977bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000978 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000979 if (Visit(TSInfo->getTypeLoc()))
980 return true;
981
David Majnemer59f77922016-06-24 04:05:48 +0000982 for (const auto *P : ND->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +0000983 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000984 return true;
985 }
986
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000987 return ND->isThisDeclarationADefinition() &&
988 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000989}
990
991template <typename DeclIt>
992static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
993 SourceManager &SM, SourceLocation EndLoc,
994 SmallVectorImpl<Decl *> &Decls) {
995 DeclIt next = *DI_current;
996 while (++next != DE_current) {
997 Decl *D_next = *next;
998 if (!D_next)
999 break;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001000 SourceLocation L = D_next->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00001001 if (!L.isValid())
1002 break;
1003 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
1004 *DI_current = next;
1005 Decls.push_back(D_next);
1006 continue;
1007 }
1008 break;
1009 }
1010}
1011
Guy Benyei11169dd2012-12-18 14:30:41 +00001012bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
1013 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
1014 // an @implementation can lexically contain Decls that are not properly
1015 // nested in the AST. When we identify such cases, we need to retrofit
1016 // this nesting here.
1017 if (!DI_current && !FileDI_current)
1018 return VisitDeclContext(D);
1019
1020 // Scan the Decls that immediately come after the container
1021 // in the current DeclContext. If any fall within the
1022 // container's lexical region, stash them into a vector
1023 // for later processing.
1024 SmallVector<Decl *, 24> DeclsInContainer;
1025 SourceLocation EndLoc = D->getSourceRange().getEnd();
1026 SourceManager &SM = AU->getSourceManager();
1027 if (EndLoc.isValid()) {
1028 if (DI_current) {
1029 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
1030 DeclsInContainer);
1031 } else {
1032 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
1033 DeclsInContainer);
1034 }
1035 }
1036
1037 // The common case.
1038 if (DeclsInContainer.empty())
1039 return VisitDeclContext(D);
1040
1041 // Get all the Decls in the DeclContext, and sort them with the
1042 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001043 for (auto *SubDecl : D->decls()) {
1044 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001045 SubDecl->getBeginLoc().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001046 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001047 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001048 }
1049
1050 // Now sort the Decls so that they appear in lexical order.
Michael Kruse7520cf02020-03-25 09:26:14 -05001051 llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {
1052 SourceLocation L_A = A->getBeginLoc();
1053 SourceLocation L_B = B->getBeginLoc();
1054 return L_A != L_B
1055 ? SM.isBeforeInTranslationUnit(L_A, L_B)
1056 : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());
1057 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001058
1059 // Now visit the decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05001060 for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),
1061 E = DeclsInContainer.end();
1062 I != E; ++I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001063 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001064 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001065 if (!V.hasValue())
1066 continue;
1067 if (!V.getValue())
1068 return false;
1069 if (Visit(Cursor, true))
1070 return true;
1071 }
1072 return false;
1073}
1074
1075bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1076 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1077 TU)))
1078 return true;
1079
Douglas Gregore9d95f12015-07-07 03:57:35 +00001080 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1081 return true;
1082
Guy Benyei11169dd2012-12-18 14:30:41 +00001083 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1084 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001085 E = ND->protocol_end();
1086 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001087 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1088 return true;
1089
1090 return VisitObjCContainerDecl(ND);
1091}
1092
1093bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1094 if (!PID->isThisDeclarationADefinition())
1095 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001096
Guy Benyei11169dd2012-12-18 14:30:41 +00001097 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1098 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001099 E = PID->protocol_end();
1100 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001101 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1102 return true;
1103
1104 return VisitObjCContainerDecl(PID);
1105}
1106
1107bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1108 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1109 return true;
1110
1111 // FIXME: This implements a workaround with @property declarations also being
1112 // installed in the DeclContext for the @interface. Eventually this code
1113 // should be removed.
1114 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1115 if (!CDecl || !CDecl->IsClassExtension())
1116 return false;
1117
1118 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1119 if (!ID)
1120 return false;
1121
1122 IdentifierInfo *PropertyId = PD->getIdentifier();
Michael Kruse7520cf02020-03-25 09:26:14 -05001123 ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
1124 cast<DeclContext>(ID), PropertyId, PD->getQueryKind());
Guy Benyei11169dd2012-12-18 14:30:41 +00001125
1126 if (!prevDecl)
1127 return false;
1128
1129 // Visit synthesized methods since they will be skipped when visiting
1130 // the @interface.
1131 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1132 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1133 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1134 return true;
1135
1136 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1137 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1138 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1139 return true;
1140
1141 return false;
1142}
1143
Douglas Gregore9d95f12015-07-07 03:57:35 +00001144bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1145 if (!typeParamList)
1146 return false;
1147
1148 for (auto *typeParam : *typeParamList) {
1149 // Visit the type parameter.
1150 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1151 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001152 }
1153
1154 return false;
1155}
1156
Guy Benyei11169dd2012-12-18 14:30:41 +00001157bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1158 if (!D->isThisDeclarationADefinition()) {
1159 // Forward declaration is treated like a reference.
1160 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1161 }
1162
Douglas Gregore9d95f12015-07-07 03:57:35 +00001163 // Objective-C type parameters.
1164 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1165 return true;
1166
Guy Benyei11169dd2012-12-18 14:30:41 +00001167 // Issue callbacks for super class.
Michael Kruse7520cf02020-03-25 09:26:14 -05001168 if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
1169 D->getSuperClass(), D->getSuperClassLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001170 return true;
1171
Douglas Gregore9d95f12015-07-07 03:57:35 +00001172 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1173 if (Visit(SuperClassTInfo->getTypeLoc()))
1174 return true;
1175
Guy Benyei11169dd2012-12-18 14:30:41 +00001176 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1177 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001178 E = D->protocol_end();
1179 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001180 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1181 return true;
1182
1183 return VisitObjCContainerDecl(D);
1184}
1185
1186bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1187 return VisitObjCContainerDecl(D);
1188}
1189
1190bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1191 // 'ID' could be null when dealing with invalid code.
1192 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1193 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1194 return true;
1195
1196 return VisitObjCImplDecl(D);
1197}
1198
1199bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1200#if 0
1201 // Issue callbacks for super class.
1202 // FIXME: No source location information!
1203 if (D->getSuperClass() &&
1204 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1205 D->getSuperClassLoc(),
1206 TU)))
1207 return true;
1208#endif
1209
1210 return VisitObjCImplDecl(D);
1211}
1212
1213bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1214 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1215 if (PD->isIvarNameSpecified())
1216 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001217
Guy Benyei11169dd2012-12-18 14:30:41 +00001218 return false;
1219}
1220
1221bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1222 return VisitDeclContext(D);
1223}
1224
1225bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1226 // Visit nested-name-specifier.
1227 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1228 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1229 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001230
1231 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001232 D->getTargetNameLoc(), TU));
1233}
1234
1235bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1236 // Visit nested-name-specifier.
1237 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1238 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1239 return true;
1240 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001241
Guy Benyei11169dd2012-12-18 14:30:41 +00001242 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1243 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001244
Guy Benyei11169dd2012-12-18 14:30:41 +00001245 return VisitDeclarationNameInfo(D->getNameInfo());
1246}
1247
1248bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1249 // Visit nested-name-specifier.
1250 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1251 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1252 return true;
1253
1254 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1255 D->getIdentLocation(), TU));
1256}
1257
1258bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1259 // Visit nested-name-specifier.
1260 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1261 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1262 return true;
1263 }
1264
1265 return VisitDeclarationNameInfo(D->getNameInfo());
1266}
1267
1268bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -05001269 UnresolvedUsingTypenameDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001270 // Visit nested-name-specifier.
1271 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1272 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1273 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001274
Guy Benyei11169dd2012-12-18 14:30:41 +00001275 return false;
1276}
1277
Olivier Goffart81978012016-06-09 16:15:55 +00001278bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
1279 if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
1280 return true;
Richard Trieuf3b77662016-09-13 01:37:01 +00001281 if (StringLiteral *Message = D->getMessage())
1282 if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
1283 return true;
Olivier Goffart81978012016-06-09 16:15:55 +00001284 return false;
1285}
1286
Olivier Goffartd211c642016-11-04 06:29:27 +00001287bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {
1288 if (NamedDecl *FriendD = D->getFriendDecl()) {
1289 if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))
1290 return true;
1291 } else if (TypeSourceInfo *TI = D->getFriendType()) {
1292 if (Visit(TI->getTypeLoc()))
1293 return true;
1294 }
1295 return false;
1296}
1297
Milian Wolff4597e3b2020-05-02 22:17:59 +02001298bool CursorVisitor::VisitDecompositionDecl(DecompositionDecl *D) {
1299 for (auto *B : D->bindings()) {
1300 if (Visit(MakeCXCursor(B, TU, RegionOfInterest)))
1301 return true;
1302 }
1303 return VisitVarDecl(D);
1304}
1305
Guy Benyei11169dd2012-12-18 14:30:41 +00001306bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1307 switch (Name.getName().getNameKind()) {
1308 case clang::DeclarationName::Identifier:
1309 case clang::DeclarationName::CXXLiteralOperatorName:
Richard Smith35845152017-02-07 01:37:30 +00001310 case clang::DeclarationName::CXXDeductionGuideName:
Guy Benyei11169dd2012-12-18 14:30:41 +00001311 case clang::DeclarationName::CXXOperatorName:
1312 case clang::DeclarationName::CXXUsingDirective:
1313 return false;
Richard Smith35845152017-02-07 01:37:30 +00001314
Guy Benyei11169dd2012-12-18 14:30:41 +00001315 case clang::DeclarationName::CXXConstructorName:
1316 case clang::DeclarationName::CXXDestructorName:
1317 case clang::DeclarationName::CXXConversionFunctionName:
1318 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1319 return Visit(TSInfo->getTypeLoc());
1320 return false;
1321
1322 case clang::DeclarationName::ObjCZeroArgSelector:
1323 case clang::DeclarationName::ObjCOneArgSelector:
1324 case clang::DeclarationName::ObjCMultiArgSelector:
1325 // FIXME: Per-identifier location info?
1326 return false;
1327 }
1328
1329 llvm_unreachable("Invalid DeclarationName::Kind!");
1330}
1331
Michael Kruse7520cf02020-03-25 09:26:14 -05001332bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
Guy Benyei11169dd2012-12-18 14:30:41 +00001333 SourceRange Range) {
1334 // FIXME: This whole routine is a hack to work around the lack of proper
1335 // source information in nested-name-specifiers (PR5791). Since we do have
1336 // a beginning source location, we can visit the first component of the
1337 // nested-name-specifier, if it's a single-token component.
1338 if (!NNS)
1339 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001340
Guy Benyei11169dd2012-12-18 14:30:41 +00001341 // Get the first component in the nested-name-specifier.
1342 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1343 NNS = Prefix;
Michael Kruse7520cf02020-03-25 09:26:14 -05001344
Guy Benyei11169dd2012-12-18 14:30:41 +00001345 switch (NNS->getKind()) {
1346 case NestedNameSpecifier::Namespace:
Michael Kruse7520cf02020-03-25 09:26:14 -05001347 return Visit(
1348 MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001349
1350 case NestedNameSpecifier::NamespaceAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05001351 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001352 Range.getBegin(), TU));
1353
1354 case NestedNameSpecifier::TypeSpec: {
1355 // If the type has a form where we know that the beginning of the source
1356 // range matches up with a reference cursor. Visit the appropriate reference
1357 // cursor.
1358 const Type *T = NNS->getAsType();
1359 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1360 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1361 if (const TagType *Tag = dyn_cast<TagType>(T))
1362 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001363 if (const TemplateSpecializationType *TST =
1364 dyn_cast<TemplateSpecializationType>(T))
Guy Benyei11169dd2012-12-18 14:30:41 +00001365 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1366 break;
1367 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001368
Guy Benyei11169dd2012-12-18 14:30:41 +00001369 case NestedNameSpecifier::TypeSpecWithTemplate:
1370 case NestedNameSpecifier::Global:
1371 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001372 case NestedNameSpecifier::Super:
Michael Kruse7520cf02020-03-25 09:26:14 -05001373 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001374 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001375
Guy Benyei11169dd2012-12-18 14:30:41 +00001376 return false;
1377}
1378
Michael Kruse7520cf02020-03-25 09:26:14 -05001379bool CursorVisitor::VisitNestedNameSpecifierLoc(
1380 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001381 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1382 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1383 Qualifiers.push_back(Qualifier);
Michael Kruse7520cf02020-03-25 09:26:14 -05001384
Guy Benyei11169dd2012-12-18 14:30:41 +00001385 while (!Qualifiers.empty()) {
1386 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1387 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1388 switch (NNS->getKind()) {
1389 case NestedNameSpecifier::Namespace:
Michael Kruse7520cf02020-03-25 09:26:14 -05001390 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1391 Q.getLocalBeginLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001392 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001393
Guy Benyei11169dd2012-12-18 14:30:41 +00001394 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001395
Guy Benyei11169dd2012-12-18 14:30:41 +00001396 case NestedNameSpecifier::NamespaceAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05001397 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1398 Q.getLocalBeginLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001399 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001400
Guy Benyei11169dd2012-12-18 14:30:41 +00001401 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001402
Guy Benyei11169dd2012-12-18 14:30:41 +00001403 case NestedNameSpecifier::TypeSpec:
1404 case NestedNameSpecifier::TypeSpecWithTemplate:
1405 if (Visit(Q.getTypeLoc()))
1406 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001407
Guy Benyei11169dd2012-12-18 14:30:41 +00001408 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001409
Guy Benyei11169dd2012-12-18 14:30:41 +00001410 case NestedNameSpecifier::Global:
1411 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001412 case NestedNameSpecifier::Super:
Michael Kruse7520cf02020-03-25 09:26:14 -05001413 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001414 }
1415 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001416
Guy Benyei11169dd2012-12-18 14:30:41 +00001417 return false;
1418}
1419
1420bool CursorVisitor::VisitTemplateParameters(
Michael Kruse7520cf02020-03-25 09:26:14 -05001421 const TemplateParameterList *Params) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001422 if (!Params)
1423 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001424
Guy Benyei11169dd2012-12-18 14:30:41 +00001425 for (TemplateParameterList::const_iterator P = Params->begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001426 PEnd = Params->end();
Guy Benyei11169dd2012-12-18 14:30:41 +00001427 P != PEnd; ++P) {
1428 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1429 return true;
1430 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001431
Guy Benyei11169dd2012-12-18 14:30:41 +00001432 return false;
1433}
1434
1435bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1436 switch (Name.getKind()) {
1437 case TemplateName::Template:
1438 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1439
1440 case TemplateName::OverloadedTemplate:
1441 // Visit the overloaded template set.
1442 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1443 return true;
1444
1445 return false;
1446
Richard Smithb23c5e82019-05-09 03:31:27 +00001447 case TemplateName::AssumedTemplate:
1448 // FIXME: Visit DeclarationName?
1449 return false;
1450
Guy Benyei11169dd2012-12-18 14:30:41 +00001451 case TemplateName::DependentTemplate:
1452 // FIXME: Visit nested-name-specifier.
1453 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001454
Guy Benyei11169dd2012-12-18 14:30:41 +00001455 case TemplateName::QualifiedTemplate:
1456 // FIXME: Visit nested-name-specifier.
1457 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001458 Name.getAsQualifiedTemplateName()->getDecl(), Loc, TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001459
1460 case TemplateName::SubstTemplateTemplateParm:
1461 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001462 Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));
1463
Guy Benyei11169dd2012-12-18 14:30:41 +00001464 case TemplateName::SubstTemplateTemplateParmPack:
1465 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001466 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
1467 TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001468 }
1469
1470 llvm_unreachable("Invalid TemplateName::Kind!");
1471}
1472
1473bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1474 switch (TAL.getArgument().getKind()) {
1475 case TemplateArgument::Null:
1476 case TemplateArgument::Integral:
1477 case TemplateArgument::Pack:
1478 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001479
Guy Benyei11169dd2012-12-18 14:30:41 +00001480 case TemplateArgument::Type:
1481 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1482 return Visit(TSInfo->getTypeLoc());
1483 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001484
Guy Benyei11169dd2012-12-18 14:30:41 +00001485 case TemplateArgument::Declaration:
1486 if (Expr *E = TAL.getSourceDeclExpression())
1487 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1488 return false;
1489
1490 case TemplateArgument::NullPtr:
1491 if (Expr *E = TAL.getSourceNullPtrExpression())
1492 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1493 return false;
1494
1495 case TemplateArgument::Expression:
1496 if (Expr *E = TAL.getSourceExpression())
1497 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1498 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001499
Guy Benyei11169dd2012-12-18 14:30:41 +00001500 case TemplateArgument::Template:
1501 case TemplateArgument::TemplateExpansion:
1502 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1503 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001504
1505 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001506 TAL.getTemplateNameLoc());
1507 }
1508
1509 llvm_unreachable("Invalid TemplateArgument::Kind!");
1510}
1511
1512bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1513 return VisitDeclContext(D);
1514}
1515
1516bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1517 return Visit(TL.getUnqualifiedLoc());
1518}
1519
1520bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1521 ASTContext &Context = AU->getASTContext();
1522
1523 // Some builtin types (such as Objective-C's "id", "sel", and
1524 // "Class") have associated declarations. Create cursors for those.
1525 QualType VisitType;
1526 switch (TL.getTypePtr()->getKind()) {
1527
1528 case BuiltinType::Void:
1529 case BuiltinType::NullPtr:
1530 case BuiltinType::Dependent:
Michael Kruse7520cf02020-03-25 09:26:14 -05001531#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
Alexey Bader954ba212016-04-08 13:40:33 +00001532 case BuiltinType::Id:
Alexey Baderb62f1442016-04-13 08:33:41 +00001533#include "clang/Basic/OpenCLImageTypes.def"
Michael Kruse7520cf02020-03-25 09:26:14 -05001534#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
Andrew Savonichev3fee3512018-11-08 11:25:41 +00001535#include "clang/Basic/OpenCLExtensionTypes.def"
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001536 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001537 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001538 case BuiltinType::OCLClkEvent:
1539 case BuiltinType::OCLQueue:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001540 case BuiltinType::OCLReserveID:
Michael Kruse7520cf02020-03-25 09:26:14 -05001541#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
Richard Sandifordeb485fb2019-08-09 08:52:54 +00001542#include "clang/Basic/AArch64SVEACLETypes.def"
Guy Benyei11169dd2012-12-18 14:30:41 +00001543#define BUILTIN_TYPE(Id, SingletonId)
1544#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1545#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1546#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1547#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1548#include "clang/AST/BuiltinTypes.def"
1549 break;
1550
1551 case BuiltinType::ObjCId:
1552 VisitType = Context.getObjCIdType();
1553 break;
1554
1555 case BuiltinType::ObjCClass:
1556 VisitType = Context.getObjCClassType();
1557 break;
1558
1559 case BuiltinType::ObjCSel:
1560 VisitType = Context.getObjCSelType();
1561 break;
1562 }
1563
1564 if (!VisitType.isNull()) {
1565 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Michael Kruse7520cf02020-03-25 09:26:14 -05001566 return Visit(
1567 MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001568 }
1569
1570 return false;
1571}
1572
1573bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1574 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1575}
1576
1577bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1578 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1579}
1580
1581bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1582 if (TL.isDefinition())
1583 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1584
1585 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1586}
1587
1588bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1589 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1590}
1591
1592bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001593 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001594}
1595
Manman Rene6be26c2016-09-13 17:25:08 +00001596bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001597 if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
Manman Rene6be26c2016-09-13 17:25:08 +00001598 return true;
1599 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1600 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1601 TU)))
1602 return true;
1603 }
1604
1605 return false;
1606}
1607
Guy Benyei11169dd2012-12-18 14:30:41 +00001608bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1609 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1610 return true;
1611
Douglas Gregore9d95f12015-07-07 03:57:35 +00001612 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1613 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1614 return true;
1615 }
1616
Guy Benyei11169dd2012-12-18 14:30:41 +00001617 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1618 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1619 TU)))
1620 return true;
1621 }
1622
1623 return false;
1624}
1625
1626bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1627 return Visit(TL.getPointeeLoc());
1628}
1629
1630bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1631 return Visit(TL.getInnerLoc());
1632}
1633
Leonard Chanc72aaf62019-05-07 03:20:17 +00001634bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
1635 return Visit(TL.getInnerLoc());
1636}
1637
Guy Benyei11169dd2012-12-18 14:30:41 +00001638bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1639 return Visit(TL.getPointeeLoc());
1640}
1641
1642bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1643 return Visit(TL.getPointeeLoc());
1644}
1645
1646bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1647 return Visit(TL.getPointeeLoc());
1648}
1649
1650bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1651 return Visit(TL.getPointeeLoc());
1652}
1653
1654bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1655 return Visit(TL.getPointeeLoc());
1656}
1657
1658bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1659 return Visit(TL.getModifiedLoc());
1660}
1661
Michael Kruse7520cf02020-03-25 09:26:14 -05001662bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
Guy Benyei11169dd2012-12-18 14:30:41 +00001663 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001664 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001665 return true;
1666
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001667 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1668 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001669 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1670 return true;
1671
1672 return false;
1673}
1674
1675bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1676 if (Visit(TL.getElementLoc()))
1677 return true;
1678
1679 if (Expr *Size = TL.getSizeExpr())
1680 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1681
1682 return false;
1683}
1684
Reid Kleckner8a365022013-06-24 17:51:48 +00001685bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1686 return Visit(TL.getOriginalLoc());
1687}
1688
Reid Kleckner0503a872013-12-05 01:23:43 +00001689bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1690 return Visit(TL.getOriginalLoc());
1691}
1692
Richard Smith600b5262017-01-26 20:40:47 +00001693bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
1694 DeducedTemplateSpecializationTypeLoc TL) {
Michael Kruse7520cf02020-03-25 09:26:14 -05001695 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Richard Smith600b5262017-01-26 20:40:47 +00001696 TL.getTemplateNameLoc()))
1697 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001698
Richard Smith600b5262017-01-26 20:40:47 +00001699 return false;
1700}
1701
Guy Benyei11169dd2012-12-18 14:30:41 +00001702bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001703 TemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001704 // Visit the template name.
Michael Kruse7520cf02020-03-25 09:26:14 -05001705 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001706 TL.getTemplateNameLoc()))
1707 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001708
Guy Benyei11169dd2012-12-18 14:30:41 +00001709 // Visit the template arguments.
1710 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1711 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1712 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001713
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 return false;
1715}
1716
1717bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1718 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1719}
1720
1721bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1722 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1723 return Visit(TSInfo->getTypeLoc());
1724
1725 return false;
1726}
1727
1728bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1729 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1730 return Visit(TSInfo->getTypeLoc());
1731
1732 return false;
1733}
1734
1735bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001736 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001737}
1738
1739bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001740 DependentTemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001741 // Visit the nested-name-specifier, if there is one.
Michael Kruse7520cf02020-03-25 09:26:14 -05001742 if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001743 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001744
Guy Benyei11169dd2012-12-18 14:30:41 +00001745 // Visit the template arguments.
1746 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1747 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1748 return true;
1749
1750 return false;
1751}
1752
1753bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1754 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1755 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001756
Guy Benyei11169dd2012-12-18 14:30:41 +00001757 return Visit(TL.getNamedTypeLoc());
1758}
1759
1760bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1761 return Visit(TL.getPatternLoc());
1762}
1763
1764bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1765 if (Expr *E = TL.getUnderlyingExpr())
1766 return Visit(MakeCXCursor(E, StmtParent, TU));
1767
1768 return false;
1769}
1770
1771bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1772 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1773}
1774
1775bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1776 return Visit(TL.getValueLoc());
1777}
1778
Xiuli Pan9c14e282016-01-09 12:53:17 +00001779bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1780 return Visit(TL.getValueLoc());
1781}
1782
Michael Kruse7520cf02020-03-25 09:26:14 -05001783#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1784 bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1785 return Visit##PARENT##Loc(TL); \
1786 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001787
1788DEFAULT_TYPELOC_IMPL(Complex, Type)
1789DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1790DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1791DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1792DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
Andrew Gozillon572bbb02017-10-02 06:25:51 +00001793DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
Erich Keanef702b022018-07-13 19:46:04 +00001794DEFAULT_TYPELOC_IMPL(DependentVector, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001795DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1796DEFAULT_TYPELOC_IMPL(Vector, Type)
1797DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
Florian Hahn10658692020-05-11 17:45:51 +01001798DEFAULT_TYPELOC_IMPL(ConstantMatrix, MatrixType)
1799DEFAULT_TYPELOC_IMPL(DependentSizedMatrix, MatrixType)
Guy Benyei11169dd2012-12-18 14:30:41 +00001800DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1801DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1802DEFAULT_TYPELOC_IMPL(Record, TagType)
1803DEFAULT_TYPELOC_IMPL(Enum, TagType)
1804DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1805DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1806DEFAULT_TYPELOC_IMPL(Auto, Type)
Erich Keane5f0903e2020-04-17 10:44:19 -07001807DEFAULT_TYPELOC_IMPL(ExtInt, Type)
1808DEFAULT_TYPELOC_IMPL(DependentExtInt, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001809
1810bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1811 // Visit the nested-name-specifier, if present.
1812 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1813 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1814 return true;
1815
1816 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001817 for (const auto &I : D->bases()) {
1818 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001819 return true;
1820 }
1821 }
1822
1823 return VisitTagDecl(D);
1824}
1825
1826bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001827 for (const auto *I : D->attrs())
Michael Wu40ff1052018-08-03 05:20:23 +00001828 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1829 !I->isImplicit()) &&
1830 Visit(MakeCXCursor(I, D, TU)))
Michael Kruse7520cf02020-03-25 09:26:14 -05001831 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00001832
1833 return false;
1834}
1835
1836//===----------------------------------------------------------------------===//
1837// Data-recursive visitor methods.
1838//===----------------------------------------------------------------------===//
1839
1840namespace {
Michael Kruse7520cf02020-03-25 09:26:14 -05001841#define DEF_JOB(NAME, DATA, KIND) \
1842 class NAME : public VisitorJob { \
1843 public: \
1844 NAME(const DATA *d, CXCursor parent) \
1845 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1846 static bool classof(const VisitorJob *VJ) { \
1847 return VJ->getKind() == KIND; \
1848 } \
1849 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1850 };
Guy Benyei11169dd2012-12-18 14:30:41 +00001851
1852DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1853DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1854DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1855DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001856DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1857DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1858DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1859#undef DEF_JOB
1860
James Y Knight04ec5bf2015-12-24 02:59:37 +00001861class ExplicitTemplateArgsVisit : public VisitorJob {
1862public:
1863 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1864 const TemplateArgumentLoc *End, CXCursor parent)
1865 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1866 End) {}
1867 static bool classof(const VisitorJob *VJ) {
1868 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1869 }
1870 const TemplateArgumentLoc *begin() const {
1871 return static_cast<const TemplateArgumentLoc *>(data[0]);
1872 }
1873 const TemplateArgumentLoc *end() {
1874 return static_cast<const TemplateArgumentLoc *>(data[1]);
1875 }
1876};
Guy Benyei11169dd2012-12-18 14:30:41 +00001877class DeclVisit : public VisitorJob {
1878public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001879 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1880 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1881 isFirst ? (void *)1 : (void *)nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 static bool classof(const VisitorJob *VJ) {
1883 return VJ->getKind() == DeclVisitKind;
1884 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001886 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001887};
1888class TypeLocVisit : public VisitorJob {
1889public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001890 TypeLocVisit(TypeLoc tl, CXCursor parent)
1891 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1892 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001893
1894 static bool classof(const VisitorJob *VJ) {
1895 return VJ->getKind() == TypeLocVisitKind;
1896 }
1897
Michael Kruse7520cf02020-03-25 09:26:14 -05001898 TypeLoc get() const {
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 }
1902};
1903
1904class LabelRefVisit : public VisitorJob {
1905public:
1906 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001907 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1908 labelLoc.getPtrEncoding()) {}
1909
Guy Benyei11169dd2012-12-18 14:30:41 +00001910 static bool classof(const VisitorJob *VJ) {
1911 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1912 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001913 const LabelDecl *get() const {
1914 return static_cast<const LabelDecl *>(data[0]);
1915 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001916 SourceLocation getLoc() const {
1917 return SourceLocation::getFromPtrEncoding(data[1]);
1918 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001919};
Michael Kruse7520cf02020-03-25 09:26:14 -05001920
Guy Benyei11169dd2012-12-18 14:30:41 +00001921class NestedNameSpecifierLocVisit : public VisitorJob {
1922public:
1923 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001924 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1925 Qualifier.getNestedNameSpecifier(),
1926 Qualifier.getOpaqueData()) {}
1927
Guy Benyei11169dd2012-12-18 14:30:41 +00001928 static bool classof(const VisitorJob *VJ) {
1929 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1930 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001931
Guy Benyei11169dd2012-12-18 14:30:41 +00001932 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001933 return NestedNameSpecifierLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001934 const_cast<NestedNameSpecifier *>(
1935 static_cast<const NestedNameSpecifier *>(data[0])),
1936 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001937 }
1938};
Michael Kruse7520cf02020-03-25 09:26:14 -05001939
Guy Benyei11169dd2012-12-18 14:30:41 +00001940class DeclarationNameInfoVisit : public VisitorJob {
1941public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001942 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001943 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001944 static bool classof(const VisitorJob *VJ) {
1945 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1946 }
1947 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001948 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001949 switch (S->getStmtClass()) {
1950 default:
1951 llvm_unreachable("Unhandled Stmt");
1952 case clang::Stmt::MSDependentExistsStmtClass:
1953 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1954 case Stmt::CXXDependentScopeMemberExprClass:
1955 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1956 case Stmt::DependentScopeDeclRefExprClass:
1957 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001958 case Stmt::OMPCriticalDirectiveClass:
1959 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001960 }
1961 }
1962};
1963class MemberRefVisit : public VisitorJob {
1964public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001965 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001966 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1967 L.getPtrEncoding()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001968 static bool classof(const VisitorJob *VJ) {
1969 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1970 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971 const FieldDecl *get() const {
1972 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001973 }
1974 SourceLocation getLoc() const {
Michael Kruse7520cf02020-03-25 09:26:14 -05001975 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 }
1977};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001979 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001980 VisitorWorkList &WL;
1981 CXCursor Parent;
Michael Kruse7520cf02020-03-25 09:26:14 -05001982
Guy Benyei11169dd2012-12-18 14:30:41 +00001983public:
1984 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001985 : WL(wl), Parent(parent) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001986
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001987 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1988 void VisitBlockExpr(const BlockExpr *B);
1989 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1990 void VisitCompoundStmt(const CompoundStmt *S);
Michael Kruse7520cf02020-03-25 09:26:14 -05001991 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
1992 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1994 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1995 void VisitCXXNewExpr(const CXXNewExpr *E);
1996 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1997 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1998 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1999 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
2000 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
2001 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
2002 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
2003 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002004 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002005 void VisitDeclRefExpr(const DeclRefExpr *D);
2006 void VisitDeclStmt(const DeclStmt *S);
2007 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
2008 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
2009 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
2010 void VisitForStmt(const ForStmt *FS);
2011 void VisitGotoStmt(const GotoStmt *GS);
2012 void VisitIfStmt(const IfStmt *If);
2013 void VisitInitListExpr(const InitListExpr *IE);
2014 void VisitMemberExpr(const MemberExpr *M);
2015 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2016 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2017 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2018 void VisitOverloadExpr(const OverloadExpr *E);
2019 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2020 void VisitStmt(const Stmt *S);
2021 void VisitSwitchStmt(const SwitchStmt *S);
2022 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002023 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2024 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2025 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2026 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2027 void VisitVAArgExpr(const VAArgExpr *E);
2028 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2029 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2030 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2031 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002032 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00002033 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002034 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002035 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002036 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00002037 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002038 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002039 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002040 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00002041 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002042 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002043 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002044 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
cchen47d60942019-12-05 13:43:48 -05002045 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002046 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002047 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00002048 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002049 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00002050 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002051 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002052 void
2053 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00002054 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00002055 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataevc112e942020-02-28 09:52:15 -05002056 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002057 void VisitOMPScanDirective(const OMPScanDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002058 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00002059 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002060 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00002061 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00002062 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00002063 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002064 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002065 void
2066 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00002067 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00002068 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002069 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Alexey Bataev60e51c42019-10-10 20:13:02 +00002070 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002071 void
2072 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002073 void VisitOMPParallelMasterTaskLoopDirective(
2074 const OMPParallelMasterTaskLoopDirective *D);
Alexey Bataev14a388f2019-10-25 10:27:13 -04002075 void VisitOMPParallelMasterTaskLoopSimdDirective(
2076 const OMPParallelMasterTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002077 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002078 void VisitOMPDistributeParallelForDirective(
2079 const OMPDistributeParallelForDirective *D);
Kelvin Li4a39add2016-07-05 05:00:15 +00002080 void VisitOMPDistributeParallelForSimdDirective(
2081 const OMPDistributeParallelForSimdDirective *D);
Kelvin Li787f3fc2016-07-06 04:45:38 +00002082 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
Kelvin Lia579b912016-07-14 02:54:56 +00002083 void VisitOMPTargetParallelForSimdDirective(
2084 const OMPTargetParallelForSimdDirective *D);
Kelvin Li986330c2016-07-20 22:57:10 +00002085 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
Kelvin Li02532872016-08-05 14:37:37 +00002086 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
Kelvin Li4e325f72016-10-25 12:50:55 +00002087 void VisitOMPTeamsDistributeSimdDirective(
2088 const OMPTeamsDistributeSimdDirective *D);
Kelvin Li579e41c2016-11-30 23:51:03 +00002089 void VisitOMPTeamsDistributeParallelForSimdDirective(
2090 const OMPTeamsDistributeParallelForSimdDirective *D);
Kelvin Li7ade93f2016-12-09 03:24:30 +00002091 void VisitOMPTeamsDistributeParallelForDirective(
2092 const OMPTeamsDistributeParallelForDirective *D);
Kelvin Libf594a52016-12-17 05:48:59 +00002093 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
Kelvin Li83c451e2016-12-25 04:52:54 +00002094 void VisitOMPTargetTeamsDistributeDirective(
2095 const OMPTargetTeamsDistributeDirective *D);
Kelvin Li80e8f562016-12-29 22:16:30 +00002096 void VisitOMPTargetTeamsDistributeParallelForDirective(
2097 const OMPTargetTeamsDistributeParallelForDirective *D);
Kelvin Li1851df52017-01-03 05:23:48 +00002098 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2099 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
Kelvin Lida681182017-01-10 18:08:18 +00002100 void VisitOMPTargetTeamsDistributeSimdDirective(
2101 const OMPTargetTeamsDistributeSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102
Guy Benyei11169dd2012-12-18 14:30:41 +00002103private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002104 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002105 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00002106 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2107 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2109 void AddStmt(const Stmt *S);
2110 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002113 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002114};
Michael Kruse7520cf02020-03-25 09:26:14 -05002115} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00002116
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002117void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 // 'S' should always be non-null, since it comes from the
2119 // statement we are visiting.
2120 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2121}
2122
Michael Kruse7520cf02020-03-25 09:26:14 -05002123void EnqueueVisitor::AddNestedNameSpecifierLoc(
2124 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 if (Qualifier)
2126 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2127}
2128
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 if (S)
2131 WL.push_back(StmtVisit(S, Parent));
2132}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002133void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002134 if (D)
2135 WL.push_back(DeclVisit(D, Parent, isFirst));
2136}
James Y Knight04ec5bf2015-12-24 02:59:37 +00002137void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2138 unsigned NumTemplateArgs) {
2139 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 if (D)
2143 WL.push_back(MemberRefVisit(D, L, Parent));
2144}
2145void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2146 if (TI)
2147 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002151 for (const Stmt *SubStmt : S->children()) {
2152 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 }
2154 if (size == WL.size())
2155 return;
2156 // Now reverse the entries we just added. This will match the DFS
2157 // ordering performed by the worklist.
2158 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2159 std::reverse(I, E);
2160}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002161namespace {
2162class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2163 EnqueueVisitor *Visitor;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002164 /// Process clauses with list of variables.
Michael Kruse7520cf02020-03-25 09:26:14 -05002165 template <typename T> void VisitOMPClauseList(T *Node);
2166
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002167public:
Michael Kruse7520cf02020-03-25 09:26:14 -05002168 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
Johannes Doerfert419a5592020-03-30 19:58:40 -05002169#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2170#include "llvm/Frontend/OpenMP/OMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002171 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002172 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002173};
2174
Alexey Bataev3392d762016-02-16 11:18:12 +00002175void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2176 const OMPClauseWithPreInit *C) {
2177 Visitor->AddStmt(C->getPreInitStmt());
2178}
2179
Alexey Bataev005248a2016-02-25 05:25:57 +00002180void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2181 const OMPClauseWithPostUpdate *C) {
Alexey Bataev37e594c2016-03-04 07:21:16 +00002182 VisitOMPClauseWithPreInit(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002183 Visitor->AddStmt(C->getPostUpdateExpr());
2184}
2185
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002186void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00002187 VisitOMPClauseWithPreInit(C);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002188 Visitor->AddStmt(C->getCondition());
2189}
2190
Alexey Bataev3778b602014-07-17 07:32:53 +00002191void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2192 Visitor->AddStmt(C->getCondition());
2193}
2194
Alexey Bataev568a8332014-03-06 06:15:19 +00002195void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00002196 VisitOMPClauseWithPreInit(C);
Alexey Bataev568a8332014-03-06 06:15:19 +00002197 Visitor->AddStmt(C->getNumThreads());
2198}
2199
Alexey Bataev62c87d22014-03-21 04:51:18 +00002200void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2201 Visitor->AddStmt(C->getSafelen());
2202}
2203
Alexey Bataev66b15b52015-08-21 11:14:16 +00002204void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2205 Visitor->AddStmt(C->getSimdlen());
2206}
2207
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002208void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2209 Visitor->AddStmt(C->getAllocator());
2210}
2211
Alexander Musman8bd31e62014-05-27 15:12:19 +00002212void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2213 Visitor->AddStmt(C->getNumForLoops());
2214}
2215
Michael Kruse7520cf02020-03-25 09:26:14 -05002216void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
Alexey Bataev756c1962013-09-24 03:17:45 +00002217
Michael Kruse7520cf02020-03-25 09:26:14 -05002218void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002219
Alexey Bataev56dafe82014-06-20 07:16:17 +00002220void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002221 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002222 Visitor->AddStmt(C->getChunkSize());
2223}
2224
Alexey Bataev10e775f2015-07-30 11:36:16 +00002225void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2226 Visitor->AddStmt(C->getNumForLoops());
2227}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002228
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002229void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2230 Visitor->AddStmt(C->getEventHandler());
2231}
2232
Alexey Bataev236070f2014-06-20 11:19:47 +00002233void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2234
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002235void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2236
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002237void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2238
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002239void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2240
Alexey Bataevdea47612014-07-23 07:46:59 +00002241void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2242
Alexey Bataev67a4f222014-07-23 10:25:33 +00002243void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2244
Alexey Bataev459dec02014-07-24 06:46:57 +00002245void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2246
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002247void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2248
Alexey Bataevea9166b2020-02-06 16:30:23 -05002249void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2250
Alexey Bataev04a830f2020-02-10 14:30:39 -05002251void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2252
Alexey Bataev95598342020-02-10 15:49:05 -05002253void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2254
Alexey Bataev9a8defc2020-02-11 11:10:43 -05002255void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2256
Alexey Bataev346265e2015-09-25 10:37:12 +00002257void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2258
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002259void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2260
Alexey Bataevb825de12015-12-07 10:51:44 +00002261void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2262
Alexey Bataev375437a2020-03-02 14:21:20 -05002263void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {}
2264
Kelvin Li1408f912018-09-26 04:28:39 +00002265void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2266 const OMPUnifiedAddressClause *) {}
2267
Patrick Lyster4a370b92018-10-01 13:47:43 +00002268void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2269 const OMPUnifiedSharedMemoryClause *) {}
2270
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00002271void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2272 const OMPReverseOffloadClause *) {}
2273
Patrick Lyster3fe9e392018-10-11 14:41:10 +00002274void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2275 const OMPDynamicAllocatorsClause *) {}
2276
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002277void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2278 const OMPAtomicDefaultMemOrderClause *) {}
2279
Michael Wonge710d542015-08-07 16:16:36 +00002280void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2281 Visitor->AddStmt(C->getDevice());
2282}
2283
Kelvin Li099bb8c2015-11-24 20:50:12 +00002284void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00002285 VisitOMPClauseWithPreInit(C);
Kelvin Li099bb8c2015-11-24 20:50:12 +00002286 Visitor->AddStmt(C->getNumTeams());
2287}
2288
Michael Kruse7520cf02020-03-25 09:26:14 -05002289void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2290 const OMPThreadLimitClause *C) {
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00002291 VisitOMPClauseWithPreInit(C);
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002292 Visitor->AddStmt(C->getThreadLimit());
2293}
2294
Alexey Bataeva0569352015-12-01 10:17:31 +00002295void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2296 Visitor->AddStmt(C->getPriority());
2297}
2298
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002299void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2300 Visitor->AddStmt(C->getGrainsize());
2301}
2302
Alexey Bataev382967a2015-12-08 12:06:20 +00002303void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2304 Visitor->AddStmt(C->getNumTasks());
2305}
2306
Alexey Bataev28c75412015-12-15 08:19:24 +00002307void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2308 Visitor->AddStmt(C->getHint());
2309}
2310
Michael Kruse7520cf02020-03-25 09:26:14 -05002311template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002312 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002313 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002314 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002315}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002316
Alexey Bataev06dea732020-03-20 09:41:22 -04002317void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2318 VisitOMPClauseList(C);
2319}
Alexey Bataev63828a32020-03-23 10:41:08 -04002320void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2321 VisitOMPClauseList(C);
2322}
Alexey Bataeve04483e2019-03-27 14:14:31 +00002323void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2324 VisitOMPClauseList(C);
2325 Visitor->AddStmt(C->getAllocator());
2326}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002327void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002328 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002329 for (const auto *E : C->private_copies()) {
2330 Visitor->AddStmt(E);
2331 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002332}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002333void OMPClauseEnqueue::VisitOMPFirstprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002334 const OMPFirstprivateClause *C) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002335 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002336 VisitOMPClauseWithPreInit(C);
2337 for (const auto *E : C->private_copies()) {
2338 Visitor->AddStmt(E);
2339 }
2340 for (const auto *E : C->inits()) {
2341 Visitor->AddStmt(E);
2342 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002343}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002344void OMPClauseEnqueue::VisitOMPLastprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002345 const OMPLastprivateClause *C) {
Alexander Musman1bb328c2014-06-04 13:06:39 +00002346 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002347 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002348 for (auto *E : C->private_copies()) {
2349 Visitor->AddStmt(E);
2350 }
2351 for (auto *E : C->source_exprs()) {
2352 Visitor->AddStmt(E);
2353 }
2354 for (auto *E : C->destination_exprs()) {
2355 Visitor->AddStmt(E);
2356 }
2357 for (auto *E : C->assignment_ops()) {
2358 Visitor->AddStmt(E);
2359 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002360}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002361void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002362 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002363}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002364void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2365 VisitOMPClauseList(C);
Alexey Bataev61205072016-03-02 04:57:40 +00002366 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002367 for (auto *E : C->privates()) {
2368 Visitor->AddStmt(E);
2369 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002370 for (auto *E : C->lhs_exprs()) {
2371 Visitor->AddStmt(E);
2372 }
2373 for (auto *E : C->rhs_exprs()) {
2374 Visitor->AddStmt(E);
2375 }
2376 for (auto *E : C->reduction_ops()) {
2377 Visitor->AddStmt(E);
2378 }
Alexey Bataevbd1c03d2020-05-04 16:19:31 -04002379 if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
2380 for (auto *E : C->copy_ops()) {
2381 Visitor->AddStmt(E);
2382 }
2383 for (auto *E : C->copy_array_temps()) {
2384 Visitor->AddStmt(E);
2385 }
2386 for (auto *E : C->copy_array_elems()) {
2387 Visitor->AddStmt(E);
2388 }
2389 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002390}
Alexey Bataev169d96a2017-07-18 20:17:46 +00002391void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2392 const OMPTaskReductionClause *C) {
2393 VisitOMPClauseList(C);
2394 VisitOMPClauseWithPostUpdate(C);
2395 for (auto *E : C->privates()) {
2396 Visitor->AddStmt(E);
2397 }
2398 for (auto *E : C->lhs_exprs()) {
2399 Visitor->AddStmt(E);
2400 }
2401 for (auto *E : C->rhs_exprs()) {
2402 Visitor->AddStmt(E);
2403 }
2404 for (auto *E : C->reduction_ops()) {
2405 Visitor->AddStmt(E);
2406 }
2407}
Alexey Bataevfa312f32017-07-21 18:48:21 +00002408void OMPClauseEnqueue::VisitOMPInReductionClause(
2409 const OMPInReductionClause *C) {
2410 VisitOMPClauseList(C);
2411 VisitOMPClauseWithPostUpdate(C);
2412 for (auto *E : C->privates()) {
2413 Visitor->AddStmt(E);
2414 }
2415 for (auto *E : C->lhs_exprs()) {
2416 Visitor->AddStmt(E);
2417 }
2418 for (auto *E : C->rhs_exprs()) {
2419 Visitor->AddStmt(E);
2420 }
2421 for (auto *E : C->reduction_ops()) {
2422 Visitor->AddStmt(E);
2423 }
Alexey Bataev88202be2017-07-27 13:20:36 +00002424 for (auto *E : C->taskgroup_descriptors())
2425 Visitor->AddStmt(E);
Alexey Bataevfa312f32017-07-21 18:48:21 +00002426}
Alexander Musman8dba6642014-04-22 13:09:42 +00002427void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2428 VisitOMPClauseList(C);
Alexey Bataev78849fb2016-03-09 09:49:00 +00002429 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002430 for (const auto *E : C->privates()) {
2431 Visitor->AddStmt(E);
2432 }
Alexander Musman3276a272015-03-21 10:12:56 +00002433 for (const auto *E : C->inits()) {
2434 Visitor->AddStmt(E);
2435 }
2436 for (const auto *E : C->updates()) {
2437 Visitor->AddStmt(E);
2438 }
2439 for (const auto *E : C->finals()) {
2440 Visitor->AddStmt(E);
2441 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002442 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002443 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002444}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002445void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2446 VisitOMPClauseList(C);
2447 Visitor->AddStmt(C->getAlignment());
2448}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002449void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2450 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002451 for (auto *E : C->source_exprs()) {
2452 Visitor->AddStmt(E);
2453 }
2454 for (auto *E : C->destination_exprs()) {
2455 Visitor->AddStmt(E);
2456 }
2457 for (auto *E : C->assignment_ops()) {
2458 Visitor->AddStmt(E);
2459 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002460}
Michael Kruse7520cf02020-03-25 09:26:14 -05002461void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2462 const OMPCopyprivateClause *C) {
Alexey Bataevbae9a792014-06-27 10:37:06 +00002463 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002464 for (auto *E : C->source_exprs()) {
2465 Visitor->AddStmt(E);
2466 }
2467 for (auto *E : C->destination_exprs()) {
2468 Visitor->AddStmt(E);
2469 }
2470 for (auto *E : C->assignment_ops()) {
2471 Visitor->AddStmt(E);
2472 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002473}
Alexey Bataev6125da92014-07-21 11:26:11 +00002474void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2475 VisitOMPClauseList(C);
2476}
Alexey Bataevc112e942020-02-28 09:52:15 -05002477void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2478 Visitor->AddStmt(C->getDepobj());
2479}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002480void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2481 VisitOMPClauseList(C);
2482}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002483void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2484 VisitOMPClauseList(C);
2485}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002486void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2487 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002488 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002489 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002490}
Alexey Bataev3392d762016-02-16 11:18:12 +00002491void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2492 const OMPDefaultmapClause * /*C*/) {}
Samuel Antao661c0902016-05-26 17:39:58 +00002493void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2494 VisitOMPClauseList(C);
2495}
Samuel Antaoec172c62016-05-26 17:49:04 +00002496void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2497 VisitOMPClauseList(C);
2498}
Michael Kruse7520cf02020-03-25 09:26:14 -05002499void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2500 const OMPUseDevicePtrClause *C) {
Carlo Bertolli2404b172016-07-13 15:37:16 +00002501 VisitOMPClauseList(C);
2502}
Alexey Bataeva888fc62020-05-21 08:30:23 -04002503void OMPClauseEnqueue::VisitOMPUseDeviceAddrClause(
2504 const OMPUseDeviceAddrClause *C) {
2505 VisitOMPClauseList(C);
2506}
Michael Kruse7520cf02020-03-25 09:26:14 -05002507void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2508 const OMPIsDevicePtrClause *C) {
Carlo Bertolli70594e92016-07-13 17:16:49 +00002509 VisitOMPClauseList(C);
2510}
Alexey Bataevb6e70842019-12-16 15:54:17 -05002511void OMPClauseEnqueue::VisitOMPNontemporalClause(
2512 const OMPNontemporalClause *C) {
2513 VisitOMPClauseList(C);
Alexey Bataev0860db92019-12-19 10:01:10 -05002514 for (const auto *E : C->private_refs())
2515 Visitor->AddStmt(E);
Alexey Bataevb6e70842019-12-16 15:54:17 -05002516}
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002517void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
Alexey Bataevb5be1c52020-04-21 13:21:00 -04002518void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
2519 const OMPUsesAllocatorsClause *C) {
2520 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
2521 const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);
2522 Visitor->AddStmt(D.Allocator);
2523 Visitor->AddStmt(D.AllocatorTraits);
2524 }
2525}
Alexey Bataev2e499ee2020-05-18 13:37:53 -04002526void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) {
2527 Visitor->AddStmt(C->getModifier());
2528 for (const Expr *E : C->varlists())
2529 Visitor->AddStmt(E);
2530}
Michael Kruse7520cf02020-03-25 09:26:14 -05002531} // namespace
Alexey Bataev756c1962013-09-24 03:17:45 +00002532
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002533void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2534 unsigned size = WL.size();
2535 OMPClauseEnqueue Visitor(this);
2536 Visitor.Visit(S);
2537 if (size == WL.size())
2538 return;
2539 // Now reverse the entries we just added. This will match the DFS
2540 // ordering performed by the worklist.
2541 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2542 std::reverse(I, E);
2543}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002544void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002545 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2546}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002547void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002548 AddDecl(B->getBlockDecl());
2549}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002550void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002551 EnqueueChildren(E);
2552 AddTypeLoc(E->getTypeSourceInfo());
2553}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002554void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002555 for (auto &I : llvm::reverse(S->body()))
2556 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002557}
Michael Kruse7520cf02020-03-25 09:26:14 -05002558void EnqueueVisitor::VisitMSDependentExistsStmt(
2559 const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002560 AddStmt(S->getSubStmt());
2561 AddDeclarationNameInfo(S);
2562 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2563 AddNestedNameSpecifierLoc(QualifierLoc);
2564}
2565
Michael Kruse7520cf02020-03-25 09:26:14 -05002566void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2567 const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002568 if (E->hasExplicitTemplateArgs())
2569 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002570 AddDeclarationNameInfo(E);
2571 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2572 AddNestedNameSpecifierLoc(QualifierLoc);
2573 if (!E->isImplicitAccess())
2574 AddStmt(E->getBase());
2575}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002576void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002577 // Enqueue the initializer , if any.
2578 AddStmt(E->getInitializer());
2579 // Enqueue the array size, if any.
Richard Smithb9fb1212019-05-06 03:47:15 +00002580 AddStmt(E->getArraySize().getValueOr(nullptr));
Guy Benyei11169dd2012-12-18 14:30:41 +00002581 // Enqueue the allocated type.
2582 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2583 // Enqueue the placement arguments.
2584 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002585 AddStmt(E->getPlacementArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002586}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002587void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002588 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002589 AddStmt(CE->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002590 AddStmt(CE->getCallee());
2591 AddStmt(CE->getArg(0));
2592}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002593void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002594 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002595 // Visit the name of the type being destroyed.
2596 AddTypeLoc(E->getDestroyedTypeInfo());
2597 // Visit the scope type that looks disturbingly like the nested-name-specifier
2598 // but isn't.
2599 AddTypeLoc(E->getScopeTypeInfo());
2600 // Visit the nested-name-specifier.
2601 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2602 AddNestedNameSpecifierLoc(QualifierLoc);
2603 // Visit base expression.
2604 AddStmt(E->getBase());
2605}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002606void EnqueueVisitor::VisitCXXScalarValueInitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002607 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002608 AddTypeLoc(E->getTypeSourceInfo());
2609}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002610void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002611 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002612 EnqueueChildren(E);
2613 AddTypeLoc(E->getTypeSourceInfo());
2614}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002615void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002616 EnqueueChildren(E);
2617 if (E->isTypeOperand())
2618 AddTypeLoc(E->getTypeOperandSourceInfo());
2619}
2620
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002621void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002622 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002623 EnqueueChildren(E);
2624 AddTypeLoc(E->getTypeSourceInfo());
2625}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002626void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002627 EnqueueChildren(E);
2628 if (E->isTypeOperand())
2629 AddTypeLoc(E->getTypeOperandSourceInfo());
2630}
2631
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002632void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002633 EnqueueChildren(S);
2634 AddDecl(S->getExceptionDecl());
2635}
2636
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002637void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002638 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002639 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002640 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002641}
2642
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002643void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002644 if (DR->hasExplicitTemplateArgs())
2645 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002646 WL.push_back(DeclRefExprParts(DR, Parent));
2647}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002648void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002649 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002650 if (E->hasExplicitTemplateArgs())
2651 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002652 AddDeclarationNameInfo(E);
2653 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2654}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002655void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002656 unsigned size = WL.size();
2657 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002658 for (const auto *D : S->decls()) {
2659 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002660 isFirst = false;
2661 }
2662 if (size == WL.size())
2663 return;
2664 // Now reverse the entries we just added. This will match the DFS
2665 // ordering performed by the worklist.
2666 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2667 std::reverse(I, E);
2668}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002669void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002670 AddStmt(E->getInit());
David Majnemerf7e36092016-06-23 00:15:04 +00002671 for (const DesignatedInitExpr::Designator &D :
2672 llvm::reverse(E->designators())) {
2673 if (D.isFieldDesignator()) {
2674 if (FieldDecl *Field = D.getField())
2675 AddMemberRef(Field, D.getFieldLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00002676 continue;
2677 }
David Majnemerf7e36092016-06-23 00:15:04 +00002678 if (D.isArrayDesignator()) {
2679 AddStmt(E->getArrayIndex(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002680 continue;
2681 }
David Majnemerf7e36092016-06-23 00:15:04 +00002682 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2683 AddStmt(E->getArrayRangeEnd(D));
2684 AddStmt(E->getArrayRangeStart(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002685 }
2686}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002687void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002688 EnqueueChildren(E);
2689 AddTypeLoc(E->getTypeInfoAsWritten());
2690}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002691void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002692 AddStmt(FS->getBody());
2693 AddStmt(FS->getInc());
2694 AddStmt(FS->getCond());
2695 AddDecl(FS->getConditionVariable());
2696 AddStmt(FS->getInit());
2697}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002698void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002699 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2700}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002701void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002702 AddStmt(If->getElse());
2703 AddStmt(If->getThen());
2704 AddStmt(If->getCond());
Milian Wolff08e18122020-05-02 22:18:09 +02002705 AddStmt(If->getInit());
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 AddDecl(If->getConditionVariable());
2707}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002708void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002709 // We care about the syntactic form of the initializer list, only.
2710 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2711 IE = Syntactic;
2712 EnqueueChildren(IE);
2713}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002714void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 WL.push_back(MemberExprParts(M, Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002716
Guy Benyei11169dd2012-12-18 14:30:41 +00002717 // If the base of the member access expression is an implicit 'this', don't
2718 // visit it.
2719 // FIXME: If we ever want to show these implicit accesses, this will be
2720 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002721 if (M->isImplicitAccess())
2722 return;
2723
2724 // Ignore base anonymous struct/union fields, otherwise they will shadow the
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00002725 // real field that we are interested in.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002726 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2727 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2728 if (FD->isAnonymousStructOrUnion()) {
2729 AddStmt(SubME->getBase());
2730 return;
2731 }
2732 }
2733 }
2734
2735 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002736}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002737void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002738 AddTypeLoc(E->getEncodedTypeSourceInfo());
2739}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002740void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002741 EnqueueChildren(M);
2742 AddTypeLoc(M->getClassReceiverTypeInfo());
2743}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002744void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002745 // Visit the components of the offsetof expression.
2746 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Michael Kruse7520cf02020-03-25 09:26:14 -05002747 const OffsetOfNode &Node = E->getComponent(I - 1);
Guy Benyei11169dd2012-12-18 14:30:41 +00002748 switch (Node.getKind()) {
2749 case OffsetOfNode::Array:
2750 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2751 break;
2752 case OffsetOfNode::Field:
2753 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2754 break;
2755 case OffsetOfNode::Identifier:
2756 case OffsetOfNode::Base:
2757 continue;
2758 }
2759 }
2760 // Visit the type into which we're computing the offset.
2761 AddTypeLoc(E->getTypeSourceInfo());
2762}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002763void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002764 if (E->hasExplicitTemplateArgs())
2765 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002766 WL.push_back(OverloadExprParts(E, Parent));
2767}
2768void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002769 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002770 EnqueueChildren(E);
2771 if (E->isArgumentType())
2772 AddTypeLoc(E->getArgumentTypeInfo());
2773}
Michael Kruse7520cf02020-03-25 09:26:14 -05002774void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002775void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002776 AddStmt(S->getBody());
2777 AddStmt(S->getCond());
2778 AddDecl(S->getConditionVariable());
2779}
2780
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002781void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002782 AddStmt(W->getBody());
2783 AddStmt(W->getCond());
2784 AddDecl(W->getConditionVariable());
2785}
2786
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002787void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 for (unsigned I = E->getNumArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002789 AddTypeLoc(E->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002790}
2791
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002792void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002793 AddTypeLoc(E->getQueriedTypeSourceInfo());
2794}
2795
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002796void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002797 EnqueueChildren(E);
2798}
2799
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002800void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002801 VisitOverloadExpr(U);
2802 if (!U->isImplicitAccess())
2803 AddStmt(U->getBase());
2804}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002805void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002806 AddStmt(E->getSubExpr());
2807 AddTypeLoc(E->getWrittenTypeInfo());
2808}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002809void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002810 WL.push_back(SizeOfPackExprParts(E, Parent));
2811}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002812void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002813 // If the opaque value has a source expression, just transparently
2814 // visit that. This is useful for (e.g.) pseudo-object expressions.
2815 if (Expr *SourceExpr = E->getSourceExpr())
2816 return Visit(SourceExpr);
2817}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002818void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002819 AddStmt(E->getBody());
2820 WL.push_back(LambdaExprParts(E, Parent));
2821}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002822void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002823 // Treat the expression like its syntactic form.
2824 Visit(E->getSyntacticForm());
2825}
2826
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002827void EnqueueVisitor::VisitOMPExecutableDirective(
Michael Kruse7520cf02020-03-25 09:26:14 -05002828 const OMPExecutableDirective *D) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002829 EnqueueChildren(D);
2830 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2831 E = D->clauses().end();
2832 I != E; ++I)
2833 EnqueueChildren(*I);
2834}
2835
Alexander Musman3aaab662014-08-19 11:27:13 +00002836void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2837 VisitOMPExecutableDirective(D);
2838}
2839
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002840void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2841 VisitOMPExecutableDirective(D);
2842}
2843
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002844void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002845 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002846}
2847
Alexey Bataevf29276e2014-06-18 04:14:57 +00002848void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002849 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002850}
2851
Alexander Musmanf82886e2014-09-18 05:12:34 +00002852void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2853 VisitOMPLoopDirective(D);
2854}
2855
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002856void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2857 VisitOMPExecutableDirective(D);
2858}
2859
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002860void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2861 VisitOMPExecutableDirective(D);
2862}
2863
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002864void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2865 VisitOMPExecutableDirective(D);
2866}
2867
Alexander Musman80c22892014-07-17 08:54:58 +00002868void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2869 VisitOMPExecutableDirective(D);
2870}
2871
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002872void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2873 VisitOMPExecutableDirective(D);
2874 AddDeclarationNameInfo(D);
2875}
2876
Michael Kruse7520cf02020-03-25 09:26:14 -05002877void EnqueueVisitor::VisitOMPParallelForDirective(
2878 const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002879 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002880}
2881
Alexander Musmane4e893b2014-09-23 09:33:00 +00002882void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2883 const OMPParallelForSimdDirective *D) {
2884 VisitOMPLoopDirective(D);
2885}
2886
cchen47d60942019-12-05 13:43:48 -05002887void EnqueueVisitor::VisitOMPParallelMasterDirective(
2888 const OMPParallelMasterDirective *D) {
2889 VisitOMPExecutableDirective(D);
2890}
2891
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002892void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2893 const OMPParallelSectionsDirective *D) {
2894 VisitOMPExecutableDirective(D);
2895}
2896
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002897void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2898 VisitOMPExecutableDirective(D);
2899}
2900
Michael Kruse7520cf02020-03-25 09:26:14 -05002901void EnqueueVisitor::VisitOMPTaskyieldDirective(
2902 const OMPTaskyieldDirective *D) {
Alexey Bataev68446b72014-07-18 07:47:19 +00002903 VisitOMPExecutableDirective(D);
2904}
2905
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002906void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2907 VisitOMPExecutableDirective(D);
2908}
2909
Alexey Bataev2df347a2014-07-18 10:17:07 +00002910void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2911 VisitOMPExecutableDirective(D);
2912}
2913
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002914void EnqueueVisitor::VisitOMPTaskgroupDirective(
2915 const OMPTaskgroupDirective *D) {
2916 VisitOMPExecutableDirective(D);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00002917 if (const Expr *E = D->getReductionRef())
2918 VisitStmt(E);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002919}
2920
Alexey Bataev6125da92014-07-21 11:26:11 +00002921void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2922 VisitOMPExecutableDirective(D);
2923}
2924
Alexey Bataevc112e942020-02-28 09:52:15 -05002925void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
2926 VisitOMPExecutableDirective(D);
2927}
2928
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002929void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
2930 VisitOMPExecutableDirective(D);
2931}
2932
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002933void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2934 VisitOMPExecutableDirective(D);
2935}
2936
Alexey Bataev0162e452014-07-22 10:10:35 +00002937void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2938 VisitOMPExecutableDirective(D);
2939}
2940
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002941void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2942 VisitOMPExecutableDirective(D);
2943}
2944
Alexey Bataevc112e942020-02-28 09:52:15 -05002945void EnqueueVisitor::VisitOMPTargetDataDirective(
2946 const OMPTargetDataDirective *D) {
Michael Wong65f367f2015-07-21 13:44:28 +00002947 VisitOMPExecutableDirective(D);
2948}
2949
Samuel Antaodf67fc42016-01-19 19:15:56 +00002950void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2951 const OMPTargetEnterDataDirective *D) {
2952 VisitOMPExecutableDirective(D);
2953}
2954
Samuel Antao72590762016-01-19 20:04:50 +00002955void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2956 const OMPTargetExitDataDirective *D) {
2957 VisitOMPExecutableDirective(D);
2958}
2959
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002960void EnqueueVisitor::VisitOMPTargetParallelDirective(
2961 const OMPTargetParallelDirective *D) {
2962 VisitOMPExecutableDirective(D);
2963}
2964
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002965void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2966 const OMPTargetParallelForDirective *D) {
2967 VisitOMPLoopDirective(D);
2968}
2969
Alexey Bataev13314bf2014-10-09 04:18:56 +00002970void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2971 VisitOMPExecutableDirective(D);
2972}
2973
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002974void EnqueueVisitor::VisitOMPCancellationPointDirective(
2975 const OMPCancellationPointDirective *D) {
2976 VisitOMPExecutableDirective(D);
2977}
2978
Alexey Bataev80909872015-07-02 11:25:17 +00002979void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2980 VisitOMPExecutableDirective(D);
2981}
2982
Alexey Bataev49f6e782015-12-01 04:18:41 +00002983void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2984 VisitOMPLoopDirective(D);
2985}
2986
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002987void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2988 const OMPTaskLoopSimdDirective *D) {
2989 VisitOMPLoopDirective(D);
2990}
2991
Alexey Bataev60e51c42019-10-10 20:13:02 +00002992void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
2993 const OMPMasterTaskLoopDirective *D) {
2994 VisitOMPLoopDirective(D);
2995}
2996
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002997void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
2998 const OMPMasterTaskLoopSimdDirective *D) {
2999 VisitOMPLoopDirective(D);
3000}
3001
Alexey Bataev5bbcead2019-10-14 17:17:41 +00003002void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
3003 const OMPParallelMasterTaskLoopDirective *D) {
3004 VisitOMPLoopDirective(D);
3005}
3006
Alexey Bataev14a388f2019-10-25 10:27:13 -04003007void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
3008 const OMPParallelMasterTaskLoopSimdDirective *D) {
3009 VisitOMPLoopDirective(D);
3010}
3011
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003012void EnqueueVisitor::VisitOMPDistributeDirective(
3013 const OMPDistributeDirective *D) {
3014 VisitOMPLoopDirective(D);
3015}
3016
Carlo Bertolli9925f152016-06-27 14:55:37 +00003017void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
3018 const OMPDistributeParallelForDirective *D) {
3019 VisitOMPLoopDirective(D);
3020}
3021
Kelvin Li4a39add2016-07-05 05:00:15 +00003022void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
3023 const OMPDistributeParallelForSimdDirective *D) {
3024 VisitOMPLoopDirective(D);
3025}
3026
Kelvin Li787f3fc2016-07-06 04:45:38 +00003027void EnqueueVisitor::VisitOMPDistributeSimdDirective(
3028 const OMPDistributeSimdDirective *D) {
3029 VisitOMPLoopDirective(D);
3030}
3031
Kelvin Lia579b912016-07-14 02:54:56 +00003032void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
3033 const OMPTargetParallelForSimdDirective *D) {
3034 VisitOMPLoopDirective(D);
3035}
3036
Kelvin Li986330c2016-07-20 22:57:10 +00003037void EnqueueVisitor::VisitOMPTargetSimdDirective(
3038 const OMPTargetSimdDirective *D) {
3039 VisitOMPLoopDirective(D);
3040}
3041
Kelvin Li02532872016-08-05 14:37:37 +00003042void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3043 const OMPTeamsDistributeDirective *D) {
3044 VisitOMPLoopDirective(D);
3045}
3046
Kelvin Li4e325f72016-10-25 12:50:55 +00003047void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3048 const OMPTeamsDistributeSimdDirective *D) {
3049 VisitOMPLoopDirective(D);
3050}
3051
Kelvin Li579e41c2016-11-30 23:51:03 +00003052void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3053 const OMPTeamsDistributeParallelForSimdDirective *D) {
3054 VisitOMPLoopDirective(D);
3055}
3056
Kelvin Li7ade93f2016-12-09 03:24:30 +00003057void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3058 const OMPTeamsDistributeParallelForDirective *D) {
3059 VisitOMPLoopDirective(D);
3060}
3061
Kelvin Libf594a52016-12-17 05:48:59 +00003062void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3063 const OMPTargetTeamsDirective *D) {
3064 VisitOMPExecutableDirective(D);
3065}
3066
Kelvin Li83c451e2016-12-25 04:52:54 +00003067void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3068 const OMPTargetTeamsDistributeDirective *D) {
3069 VisitOMPLoopDirective(D);
3070}
3071
Kelvin Li80e8f562016-12-29 22:16:30 +00003072void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3073 const OMPTargetTeamsDistributeParallelForDirective *D) {
3074 VisitOMPLoopDirective(D);
3075}
3076
Kelvin Li1851df52017-01-03 05:23:48 +00003077void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3078 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3079 VisitOMPLoopDirective(D);
3080}
3081
Kelvin Lida681182017-01-10 18:08:18 +00003082void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3083 const OMPTargetTeamsDistributeSimdDirective *D) {
3084 VisitOMPLoopDirective(D);
3085}
3086
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003087void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003088 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3089 .Visit(S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003090}
3091
3092bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3093 if (RegionOfInterest.isValid()) {
3094 SourceRange Range = getRawCursorExtent(C);
3095 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3096 return false;
3097 }
3098 return true;
3099}
3100
3101bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3102 while (!WL.empty()) {
3103 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00003104 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00003105
3106 // Set the Parent field, then back to its old value once we're done.
3107 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
Michael Kruse7520cf02020-03-25 09:26:14 -05003108
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 switch (LI.getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003110 case VisitorJob::DeclVisitKind: {
3111 const Decl *D = cast<DeclVisit>(&LI)->get();
3112 if (!D)
3113 continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00003114
Michael Kruse7520cf02020-03-25 09:26:14 -05003115 // For now, perform default visitation for Decls.
3116 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3117 cast<DeclVisit>(&LI)->isFirst())))
3118 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003119
Michael Kruse7520cf02020-03-25 09:26:14 -05003120 continue;
3121 }
3122 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3123 for (const TemplateArgumentLoc &Arg :
3124 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3125 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003127 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003128 continue;
3129 }
3130 case VisitorJob::TypeLocVisitKind: {
3131 // Perform default visitation for TypeLocs.
3132 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3133 return true;
3134 continue;
3135 }
3136 case VisitorJob::LabelRefVisitKind: {
3137 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3138 if (LabelStmt *stmt = LS->getStmt()) {
3139 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3140 TU))) {
3141 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003144 continue;
3145 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003146
Michael Kruse7520cf02020-03-25 09:26:14 -05003147 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3148 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3149 if (VisitNestedNameSpecifierLoc(V->get()))
3150 return true;
3151 continue;
3152 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003153
Michael Kruse7520cf02020-03-25 09:26:14 -05003154 case VisitorJob::DeclarationNameInfoVisitKind: {
3155 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3156 return true;
3157 continue;
3158 }
3159 case VisitorJob::MemberRefVisitKind: {
3160 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3161 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3162 return true;
3163 continue;
3164 }
3165 case VisitorJob::StmtVisitKind: {
3166 const Stmt *S = cast<StmtVisit>(&LI)->get();
3167 if (!S)
Guy Benyei11169dd2012-12-18 14:30:41 +00003168 continue;
Richard Smithba71c082013-05-16 06:20:58 +00003169
Michael Kruse7520cf02020-03-25 09:26:14 -05003170 // Update the current cursor.
3171 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3172 if (!IsInRegionOfInterest(Cursor))
3173 continue;
3174 switch (Visitor(Cursor, Parent, ClientData)) {
3175 case CXChildVisit_Break:
3176 return true;
3177 case CXChildVisit_Continue:
3178 break;
3179 case CXChildVisit_Recurse:
3180 if (PostChildrenVisitor)
3181 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3182 EnqueueWorkList(WL, S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 break;
3184 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003185 continue;
3186 }
3187 case VisitorJob::MemberExprPartsKind: {
3188 // Handle the other pieces in the MemberExpr besides the base.
3189 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00003190
Michael Kruse7520cf02020-03-25 09:26:14 -05003191 // Visit the nested-name-specifier
3192 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3193 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05003195
3196 // Visit the declaration name.
3197 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3198 return true;
3199
3200 // Visit the explicitly-specified template arguments, if any.
3201 if (M->hasExplicitTemplateArgs()) {
3202 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3203 *ArgEnd = Arg + M->getNumTemplateArgs();
3204 Arg != ArgEnd; ++Arg) {
3205 if (VisitTemplateArgumentLoc(*Arg))
3206 return true;
3207 }
3208 }
3209 continue;
3210 }
3211 case VisitorJob::DeclRefExprPartsKind: {
3212 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3213 // Visit nested-name-specifier, if present.
3214 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3215 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3216 return true;
3217 // Visit declaration name.
3218 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3219 return true;
3220 continue;
3221 }
3222 case VisitorJob::OverloadExprPartsKind: {
3223 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3224 // Visit the nested-name-specifier.
3225 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3226 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3227 return true;
3228 // Visit the declaration name.
3229 if (VisitDeclarationNameInfo(O->getNameInfo()))
3230 return true;
3231 // Visit the overloaded declaration reference.
3232 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3233 return true;
3234 continue;
3235 }
3236 case VisitorJob::SizeOfPackExprPartsKind: {
3237 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3238 NamedDecl *Pack = E->getPack();
3239 if (isa<TemplateTypeParmDecl>(Pack)) {
3240 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3241 E->getPackLoc(), TU)))
3242 return true;
3243
3244 continue;
3245 }
3246
3247 if (isa<TemplateTemplateParmDecl>(Pack)) {
3248 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3249 E->getPackLoc(), TU)))
3250 return true;
3251
3252 continue;
3253 }
3254
3255 // Non-type template parameter packs and function parameter packs are
3256 // treated like DeclRefExpr cursors.
3257 continue;
3258 }
3259
3260 case VisitorJob::LambdaExprPartsKind: {
3261 // Visit non-init captures.
3262 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3263 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3264 CEnd = E->explicit_capture_end();
3265 C != CEnd; ++C) {
3266 if (!C->capturesVariable())
3267 continue;
3268
3269 if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
3270 TU)))
3271 return true;
3272 }
3273 // Visit init captures
3274 for (auto InitExpr : E->capture_inits()) {
Christian Kandeler6e089e92020-07-08 12:19:49 -07003275 if (InitExpr && Visit(InitExpr))
Michael Kruse7520cf02020-03-25 09:26:14 -05003276 return true;
3277 }
3278
3279 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3280 // Visit parameters and return type, if present.
3281 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3282 if (E->hasExplicitParameters()) {
3283 // Visit parameters.
3284 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3285 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3286 return true;
3287 }
3288 if (E->hasExplicitResultType()) {
3289 // Visit result type.
3290 if (Visit(Proto.getReturnLoc()))
3291 return true;
3292 }
3293 }
3294 break;
3295 }
3296
3297 case VisitorJob::PostChildrenVisitKind:
3298 if (PostChildrenVisitor(Parent, ClientData))
3299 return true;
3300 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 }
3302 }
3303 return false;
3304}
3305
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003306bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00003307 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 if (!WorkListFreeList.empty()) {
3309 WL = WorkListFreeList.back();
3310 WL->clear();
3311 WorkListFreeList.pop_back();
Michael Kruse7520cf02020-03-25 09:26:14 -05003312 } else {
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 WL = new VisitorWorkList();
3314 WorkListCache.push_back(WL);
3315 }
3316 EnqueueWorkList(*WL, S);
3317 bool result = RunVisitorWorkList(*WL);
3318 WorkListFreeList.push_back(WL);
3319 return result;
3320}
3321
3322namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003323typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00003324RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3325 const DeclarationNameInfo &NI, SourceRange QLoc,
3326 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3328 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3329 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
Michael Kruse7520cf02020-03-25 09:26:14 -05003330
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
Michael Kruse7520cf02020-03-25 09:26:14 -05003332
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 RefNamePieces Pieces;
3334
3335 if (WantQualifier && QLoc.isValid())
3336 Pieces.push_back(QLoc);
Michael Kruse7520cf02020-03-25 09:26:14 -05003337
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3339 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00003340
3341 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3342 Pieces.push_back(*TemplateArgsLoc);
3343
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 if (Kind == DeclarationName::CXXOperatorName) {
3345 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003346 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003348 NI.getInfo().CXXOperatorName.EndOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003350
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 if (WantSinglePiece) {
3352 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3353 Pieces.clear();
3354 Pieces.push_back(R);
Michael Kruse7520cf02020-03-25 09:26:14 -05003355 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003356
Michael Kruse7520cf02020-03-25 09:26:14 -05003357 return Pieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00003358}
Michael Kruse7520cf02020-03-25 09:26:14 -05003359} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00003360
3361//===----------------------------------------------------------------------===//
3362// Misc. API hooks.
Michael Kruse7520cf02020-03-25 09:26:14 -05003363//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00003364
Chandler Carruth66660742014-06-27 16:37:27 +00003365namespace {
3366struct RegisterFatalErrorHandler {
3367 RegisterFatalErrorHandler() {
Jan Korousf7d23762019-09-12 22:55:55 +00003368 clang_install_aborting_llvm_fatal_error_handler();
Chandler Carruth66660742014-06-27 16:37:27 +00003369 }
3370};
Michael Kruse7520cf02020-03-25 09:26:14 -05003371} // namespace
Chandler Carruth66660742014-06-27 16:37:27 +00003372
Michael Kruse7520cf02020-03-25 09:26:14 -05003373static llvm::ManagedStatic<RegisterFatalErrorHandler>
3374 RegisterFatalErrorHandlerOnce;
Chandler Carruth66660742014-06-27 16:37:27 +00003375
Guy Benyei11169dd2012-12-18 14:30:41 +00003376CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3377 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 // We use crash recovery to make some of our APIs more reliable, implicitly
3379 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003380 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3381 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003382
Chandler Carruth66660742014-06-27 16:37:27 +00003383 // Look through the managed static to trigger construction of the managed
3384 // static which registers our fatal error handler. This ensures it is only
3385 // registered once.
3386 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003387
Adrian Prantlbc068582015-07-08 01:00:30 +00003388 // Initialize targets for clang module support.
3389 llvm::InitializeAllTargets();
3390 llvm::InitializeAllTargetMCs();
3391 llvm::InitializeAllAsmPrinters();
3392 llvm::InitializeAllAsmParsers();
3393
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003394 CIndexer *CIdxr = new CIndexer();
3395
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 if (excludeDeclarationsFromPCH)
3397 CIdxr->setOnlyLocalDecls();
3398 if (displayDiagnostics)
3399 CIdxr->setDisplayDiagnostics();
3400
3401 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3402 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3403 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3404 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3405 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3406 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3407
3408 return CIdxr;
3409}
3410
3411void clang_disposeIndex(CXIndex CIdx) {
3412 if (CIdx)
3413 delete static_cast<CIndexer *>(CIdx);
3414}
3415
3416void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3417 if (CIdx)
3418 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3419}
3420
3421unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3422 if (CIdx)
3423 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3424 return 0;
3425}
3426
Alex Lorenz08615792017-12-04 21:56:36 +00003427void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
3428 const char *Path) {
3429 if (CIdx)
3430 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
3431}
3432
Guy Benyei11169dd2012-12-18 14:30:41 +00003433void clang_toggleCrashRecovery(unsigned isEnabled) {
3434 if (isEnabled)
3435 llvm::CrashRecoveryContext::Enable();
3436 else
3437 llvm::CrashRecoveryContext::Disable();
3438}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003439
Guy Benyei11169dd2012-12-18 14:30:41 +00003440CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3441 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003442 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003443 enum CXErrorCode Result =
3444 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003445 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003446 assert((TU && Result == CXError_Success) ||
3447 (!TU && Result != CXError_Success));
3448 return TU;
3449}
3450
3451enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3452 const char *ast_filename,
3453 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003454 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003455 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003456
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003457 if (!CIdx || !ast_filename || !out_TU)
3458 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003459
Michael Kruse7520cf02020-03-25 09:26:14 -05003460 LOG_FUNC_SECTION { *Log << ast_filename; }
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003461
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3463 FileSystemOptions FileSystemOpts;
3464
Justin Bognerd512c1e2014-10-15 00:33:06 +00003465 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3466 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003467 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Richard Smithdbafb6c2017-06-29 23:23:46 +00003468 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
Michael Kruse7520cf02020-03-25 09:26:14 -05003469 ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3470 CXXIdx->getOnlyLocalDecls(), None, CaptureDiagsKind::All,
David Blaikie6f7382d2014-08-10 19:08:04 +00003471 /*AllowPCHWithCompilerErrors=*/true,
3472 /*UserFilesAreVolatile=*/true);
David Blaikieea4395e2017-01-06 19:49:01 +00003473 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003474 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003475}
3476
3477unsigned clang_defaultEditingTranslationUnitOptions() {
Michael Kruse7520cf02020-03-25 09:26:14 -05003478 return CXTranslationUnit_PrecompiledPreamble |
Guy Benyei11169dd2012-12-18 14:30:41 +00003479 CXTranslationUnit_CacheCompletionResults;
3480}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003481
Michael Kruse7520cf02020-03-25 09:26:14 -05003482CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3483 CXIndex CIdx, const char *source_filename, int num_command_line_args,
3484 const char *const *command_line_args, unsigned num_unsaved_files,
3485 struct CXUnsavedFile *unsaved_files) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
Michael Kruse7520cf02020-03-25 09:26:14 -05003487 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3488 num_command_line_args, unsaved_files,
3489 num_unsaved_files, Options);
Guy Benyei11169dd2012-12-18 14:30:41 +00003490}
3491
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003492static CXErrorCode
3493clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3494 const char *const *command_line_args,
3495 int num_command_line_args,
3496 ArrayRef<CXUnsavedFile> unsaved_files,
3497 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003498 // Set up the initial return values.
3499 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003500 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003501
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003502 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003503 if (!CIdx || !out_TU)
3504 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003505
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3507
3508 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3509 setThreadBackgroundPriority();
3510
3511 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003512 bool CreatePreambleOnFirstParse =
3513 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 // FIXME: Add a flag for modules.
Michael Kruse7520cf02020-03-25 09:26:14 -05003515 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3516 CXTranslationUnit_SingleFileParse))
3517 ? TU_Prefix
3518 : TU_Complete;
3519 bool CacheCodeCompletionResults =
3520 options & CXTranslationUnit_CacheCompletionResults;
3521 bool IncludeBriefCommentsInCodeCompletion =
3522 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003523 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
3524 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
Michael Kruse7520cf02020-03-25 09:26:14 -05003525 bool RetainExcludedCB =
3526 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
Ivan Donchevskii6e895282018-05-17 09:24:37 +00003527 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
3528 if (options & CXTranslationUnit_SkipFunctionBodies) {
3529 SkipFunctionBodies =
3530 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
3531 ? SkipFunctionBodiesScope::Preamble
3532 : SkipFunctionBodiesScope::PreambleAndMainFile;
3533 }
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003534
3535 // Configure the diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05003536 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3537 CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003538
Manuel Klimek016c0242016-03-01 10:56:19 +00003539 if (options & CXTranslationUnit_KeepGoing)
Ivan Donchevskii878271b2019-03-07 10:13:50 +00003540 Diags->setFatalsAsError(true);
Manuel Klimek016c0242016-03-01 10:56:19 +00003541
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003542 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
3543 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
3544 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
3545
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003547 llvm::CrashRecoveryContextCleanupRegistrar<
3548 DiagnosticsEngine,
3549 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
3550 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003551
Ahmed Charlesb8984322014-03-07 20:03:18 +00003552 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3553 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003554
3555 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003556 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3557 RemappedCleanup(RemappedFiles.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003558
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003559 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003560 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003561 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003562 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 }
3564
Ahmed Charlesb8984322014-03-07 20:03:18 +00003565 std::unique_ptr<std::vector<const char *>> Args(
3566 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003567
3568 // Recover resources if we crash before exiting this method.
Michael Kruse7520cf02020-03-25 09:26:14 -05003569 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
3570 ArgsCleanup(Args.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003571
3572 // Since the Clang C library is primarily used by batch tools dealing with
3573 // (often very broken) source code, where spell-checking can have a
Michael Kruse7520cf02020-03-25 09:26:14 -05003574 // significant negative impact on performance (particularly when
Guy Benyei11169dd2012-12-18 14:30:41 +00003575 // precompiled headers are involved), we disable it by default.
3576 // Only do this if we haven't found a spell-checking-related argument.
3577 bool FoundSpellCheckingArgument = false;
3578 for (int I = 0; I != num_command_line_args; ++I) {
3579 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3580 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3581 FoundSpellCheckingArgument = true;
3582 break;
3583 }
3584 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 Args->insert(Args->end(), command_line_args,
3586 command_line_args + num_command_line_args);
3587
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003588 if (!FoundSpellCheckingArgument)
3589 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3590
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 // The 'source_filename' argument is optional. If the caller does not
3592 // specify it then it is assumed that the source file is specified
3593 // in the actual argument list.
3594 // Put the source file after command_line_args otherwise if '-x' flag is
3595 // present it will be unused.
3596 if (source_filename)
3597 Args->push_back(source_filename);
3598
3599 // Do we need the detailed preprocessing record?
3600 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3601 Args->push_back("-Xclang");
3602 Args->push_back("-detailed-preprocessing-record");
3603 }
Alex Lorenzcb006402017-04-27 13:47:03 +00003604
3605 // Suppress any editor placeholder diagnostics.
3606 Args->push_back("-fallow-editor-placeholders");
3607
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003609 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003610 // Unless the user specified that they want the preamble on the first parse
3611 // set it up to be created on the first reparse. This makes the first parse
3612 // faster, trading for a slower (first) reparse.
3613 unsigned PrecompilePreambleAfterNParses =
3614 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Alex Lorenz08615792017-12-04 21:56:36 +00003615
Alex Lorenz08615792017-12-04 21:56:36 +00003616 LibclangInvocationReporter InvocationReporter(
3617 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
Alex Lorenz690f0e22017-12-07 20:37:50 +00003618 options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
3619 unsaved_files);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003620 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003621 Args->data(), Args->data() + Args->size(),
3622 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003623 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003624 CaptureDiagnostics, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003625 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3626 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Argyrios Kyrtzidis735e92c2017-06-09 01:20:48 +00003627 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
Evgeny Mankov2ed2e622019-08-27 22:15:32 +00003628 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003629 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3630 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003631
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003632 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003633 if (!Unit && !ErrUnit)
3634 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003635
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 if (NumErrors != Diags->getClient()->getNumErrors()) {
3637 // Make sure to check that 'Unit' is non-NULL.
3638 if (CXXIdx->getDisplayDiagnostics())
3639 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3640 }
3641
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003642 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3643 return CXError_ASTReadError;
3644
David Blaikieea4395e2017-01-06 19:49:01 +00003645 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
Alex Lorenz690f0e22017-12-07 20:37:50 +00003646 if (CXTranslationUnitImpl *TU = *out_TU) {
3647 TU->ParsingOptions = options;
3648 TU->Arguments.reserve(Args->size());
3649 for (const char *Arg : *Args)
3650 TU->Arguments.push_back(Arg);
3651 return CXError_Success;
3652 }
3653 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003654}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003655
3656CXTranslationUnit
Michael Kruse7520cf02020-03-25 09:26:14 -05003657clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003658 const char *const *command_line_args,
3659 int num_command_line_args,
3660 struct CXUnsavedFile *unsaved_files,
Michael Kruse7520cf02020-03-25 09:26:14 -05003661 unsigned num_unsaved_files, unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003662 CXTranslationUnit TU;
3663 enum CXErrorCode Result = clang_parseTranslationUnit2(
3664 CIdx, source_filename, command_line_args, num_command_line_args,
3665 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003666 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003667 assert((TU && Result == CXError_Success) ||
3668 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003669 return TU;
3670}
3671
3672enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003673 CXIndex CIdx, const char *source_filename,
3674 const char *const *command_line_args, int num_command_line_args,
3675 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3676 unsigned options, CXTranslationUnit *out_TU) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003677 noteBottomOfStack();
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003678 SmallVector<const char *, 4> Args;
3679 Args.push_back("clang");
3680 Args.append(command_line_args, command_line_args + num_command_line_args);
3681 return clang_parseTranslationUnit2FullArgv(
3682 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3683 num_unsaved_files, options, out_TU);
3684}
3685
3686enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3687 CXIndex CIdx, const char *source_filename,
3688 const char *const *command_line_args, int num_command_line_args,
3689 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3690 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003691 LOG_FUNC_SECTION {
3692 *Log << source_filename << ": ";
3693 for (int i = 0; i != num_command_line_args; ++i)
3694 *Log << command_line_args[i] << " ";
3695 }
3696
Alp Toker9d85b182014-07-07 01:23:14 +00003697 if (num_unsaved_files && !unsaved_files)
3698 return CXError_InvalidArguments;
3699
Alp Toker5c532982014-07-07 22:42:03 +00003700 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003701 auto ParseTranslationUnitImpl = [=, &result] {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003702 noteBottomOfStack();
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003703 result = clang_parseTranslationUnit_Impl(
3704 CIdx, source_filename, command_line_args, num_command_line_args,
3705 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3706 };
Erik Verbruggen284848d2017-08-29 09:08:02 +00003707
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 llvm::CrashRecoveryContext CRC;
3709
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003710 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3712 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3713 fprintf(stderr, " 'command_line_args' : [");
3714 for (int i = 0; i != num_command_line_args; ++i) {
3715 if (i)
3716 fprintf(stderr, ", ");
3717 fprintf(stderr, "'%s'", command_line_args[i]);
3718 }
3719 fprintf(stderr, "],\n");
3720 fprintf(stderr, " 'unsaved_files' : [");
3721 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3722 if (i)
3723 fprintf(stderr, ", ");
3724 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3725 unsaved_files[i].Length);
3726 }
3727 fprintf(stderr, "],\n");
3728 fprintf(stderr, " 'options' : %d,\n", options);
3729 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003730
3731 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003733 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003734 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 }
Alp Toker5c532982014-07-07 22:42:03 +00003736
3737 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003738}
3739
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003740CXString clang_Type_getObjCEncoding(CXType CT) {
3741 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3742 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3743 std::string encoding;
Michael Kruse7520cf02020-03-25 09:26:14 -05003744 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003745
3746 return cxstring::createDup(encoding);
3747}
3748
3749static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3750 if (C.kind == CXCursor_MacroDefinition) {
3751 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3752 return MDR->getName();
3753 } else if (C.kind == CXCursor_MacroExpansion) {
3754 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3755 return ME.getName();
3756 }
3757 return nullptr;
3758}
3759
3760unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3761 const IdentifierInfo *II = getMacroIdentifier(C);
3762 if (!II) {
3763 return false;
3764 }
3765 ASTUnit *ASTU = getCursorASTUnit(C);
3766 Preprocessor &PP = ASTU->getPreprocessor();
3767 if (const MacroInfo *MI = PP.getMacroInfo(II))
3768 return MI->isFunctionLike();
3769 return false;
3770}
3771
3772unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3773 const IdentifierInfo *II = getMacroIdentifier(C);
3774 if (!II) {
3775 return false;
3776 }
3777 ASTUnit *ASTU = getCursorASTUnit(C);
3778 Preprocessor &PP = ASTU->getPreprocessor();
3779 if (const MacroInfo *MI = PP.getMacroInfo(II))
3780 return MI->isBuiltinMacro();
3781 return false;
3782}
3783
3784unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3785 const Decl *D = getCursorDecl(C);
3786 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3787 if (!FD) {
3788 return false;
3789 }
3790 return FD->isInlined();
3791}
3792
Michael Kruse7520cf02020-03-25 09:26:14 -05003793static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003794 if (callExpr->getNumArgs() != 1) {
3795 return nullptr;
3796 }
3797
3798 StringLiteral *S = nullptr;
3799 auto *arg = callExpr->getArg(0);
3800 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3801 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3802 auto *subExpr = I->getSubExprAsWritten();
3803
Michael Kruse7520cf02020-03-25 09:26:14 -05003804 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003805 return nullptr;
3806 }
3807
3808 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3809 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3810 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3811 } else {
3812 return nullptr;
3813 }
3814 return S;
3815}
3816
David Blaikie59272572016-04-13 18:23:33 +00003817struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003818 CXEvalResultKind EvalType;
3819 union {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003820 unsigned long long unsignedVal;
3821 long long intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003822 double floatVal;
3823 char *stringVal;
3824 } EvalData;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003825 bool IsUnsignedInt;
David Blaikie59272572016-04-13 18:23:33 +00003826 ~ExprEvalResult() {
3827 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3828 EvalType != CXEval_Int) {
Alex Lorenza19cb2e2019-01-08 23:28:37 +00003829 delete[] EvalData.stringVal;
David Blaikie59272572016-04-13 18:23:33 +00003830 }
3831 }
3832};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003833
3834void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003835 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003836}
3837
3838CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3839 if (!E) {
3840 return CXEval_UnExposed;
3841 }
3842 return ((ExprEvalResult *)E)->EvalType;
3843}
3844
3845int clang_EvalResult_getAsInt(CXEvalResult E) {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003846 return clang_EvalResult_getAsLongLong(E);
3847}
3848
3849long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003850 if (!E) {
3851 return 0;
3852 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003853 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003854 if (Result->IsUnsignedInt)
3855 return Result->EvalData.unsignedVal;
3856 return Result->EvalData.intVal;
3857}
3858
3859unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
3860 return ((ExprEvalResult *)E)->IsUnsignedInt;
3861}
3862
3863unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
3864 if (!E) {
3865 return 0;
3866 }
3867
Michael Kruse7520cf02020-03-25 09:26:14 -05003868 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003869 if (Result->IsUnsignedInt)
3870 return Result->EvalData.unsignedVal;
3871 return Result->EvalData.intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003872}
3873
3874double clang_EvalResult_getAsDouble(CXEvalResult E) {
3875 if (!E) {
3876 return 0;
3877 }
3878 return ((ExprEvalResult *)E)->EvalData.floatVal;
3879}
3880
Michael Kruse7520cf02020-03-25 09:26:14 -05003881const char *clang_EvalResult_getAsStr(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003882 if (!E) {
3883 return nullptr;
3884 }
3885 return ((ExprEvalResult *)E)->EvalData.stringVal;
3886}
3887
Michael Kruse7520cf02020-03-25 09:26:14 -05003888static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003889 Expr::EvalResult ER;
3890 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003891 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003892 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003893
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003894 expr = expr->IgnoreParens();
Emilio Cobos Alvarez74375452019-07-09 14:27:01 +00003895 if (expr->isValueDependent())
3896 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003897 if (!expr->EvaluateAsRValue(ER, ctx))
3898 return nullptr;
3899
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003900 QualType rettype;
3901 CallExpr *callExpr;
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00003902 auto result = std::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003903 result->EvalType = CXEval_UnExposed;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003904 result->IsUnsignedInt = false;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003905
David Blaikiebbc00882016-04-13 18:36:19 +00003906 if (ER.Val.isInt()) {
3907 result->EvalType = CXEval_Int;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003908
Michael Kruse7520cf02020-03-25 09:26:14 -05003909 auto &val = ER.Val.getInt();
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003910 if (val.isUnsigned()) {
3911 result->IsUnsignedInt = true;
3912 result->EvalData.unsignedVal = val.getZExtValue();
3913 } else {
3914 result->EvalData.intVal = val.getExtValue();
3915 }
3916
David Blaikiebbc00882016-04-13 18:36:19 +00003917 return result.release();
3918 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003919
David Blaikiebbc00882016-04-13 18:36:19 +00003920 if (ER.Val.isFloat()) {
3921 llvm::SmallVector<char, 100> Buffer;
3922 ER.Val.getFloat().toString(Buffer);
3923 std::string floatStr(Buffer.data(), Buffer.size());
3924 result->EvalType = CXEval_Float;
3925 bool ignored;
3926 llvm::APFloat apFloat = ER.Val.getFloat();
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003927 apFloat.convert(llvm::APFloat::IEEEdouble(),
David Blaikiebbc00882016-04-13 18:36:19 +00003928 llvm::APFloat::rmNearestTiesToEven, &ignored);
3929 result->EvalData.floatVal = apFloat.convertToDouble();
3930 return result.release();
3931 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003932
David Blaikiebbc00882016-04-13 18:36:19 +00003933 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3934 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3935 auto *subExpr = I->getSubExprAsWritten();
3936 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3937 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003938 const StringLiteral *StrE = nullptr;
3939 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003940 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003941
3942 if (ObjCExpr) {
3943 StrE = ObjCExpr->getString();
3944 result->EvalType = CXEval_ObjCStrLiteral;
3945 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003946 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003947 result->EvalType = CXEval_StrLiteral;
3948 }
3949
3950 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003951 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003952 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3953 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003954 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003955 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003956 }
3957 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3958 expr->getStmtClass() == Stmt::StringLiteralClass) {
3959 const StringLiteral *StrE = nullptr;
3960 const ObjCStringLiteral *ObjCExpr;
3961 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003962
David Blaikiebbc00882016-04-13 18:36:19 +00003963 if (ObjCExpr) {
3964 StrE = ObjCExpr->getString();
3965 result->EvalType = CXEval_ObjCStrLiteral;
3966 } else {
3967 StrE = cast<StringLiteral>(expr);
3968 result->EvalType = CXEval_StrLiteral;
3969 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003970
David Blaikiebbc00882016-04-13 18:36:19 +00003971 std::string strRef(StrE->getString().str());
3972 result->EvalData.stringVal = new char[strRef.size() + 1];
3973 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3974 result->EvalData.stringVal[strRef.size()] = '\0';
3975 return result.release();
3976 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003977
David Blaikiebbc00882016-04-13 18:36:19 +00003978 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3979 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003980
David Blaikiebbc00882016-04-13 18:36:19 +00003981 rettype = CC->getType();
3982 if (rettype.getAsString() == "CFStringRef" &&
3983 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003984
David Blaikiebbc00882016-04-13 18:36:19 +00003985 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3986 StringLiteral *S = getCFSTR_value(callExpr);
3987 if (S) {
3988 std::string strLiteral(S->getString().str());
3989 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003990
David Blaikiebbc00882016-04-13 18:36:19 +00003991 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3992 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3993 strLiteral.size());
3994 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003995 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003996 }
3997 }
3998
David Blaikiebbc00882016-04-13 18:36:19 +00003999 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
4000 callExpr = static_cast<CallExpr *>(expr);
4001 rettype = callExpr->getCallReturnType(ctx);
4002
4003 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
4004 return nullptr;
4005
4006 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
4007 if (callExpr->getNumArgs() == 1 &&
4008 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
4009 return nullptr;
4010 } else if (rettype.getAsString() == "CFStringRef") {
4011
4012 StringLiteral *S = getCFSTR_value(callExpr);
4013 if (S) {
4014 std::string strLiteral(S->getString().str());
4015 result->EvalType = CXEval_CFStr;
4016 result->EvalData.stringVal = new char[strLiteral.size() + 1];
4017 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
4018 strLiteral.size());
4019 result->EvalData.stringVal[strLiteral.size()] = '\0';
4020 return result.release();
4021 }
4022 }
4023 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
4024 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
4025 ValueDecl *V = D->getDecl();
4026 if (V->getKind() == Decl::Function) {
4027 std::string strName = V->getNameAsString();
4028 result->EvalType = CXEval_Other;
4029 result->EvalData.stringVal = new char[strName.size() + 1];
4030 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
4031 result->EvalData.stringVal[strName.size()] = '\0';
4032 return result.release();
4033 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004034 }
4035
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004036 return nullptr;
4037}
4038
Alex Lorenz65317e12019-01-08 22:32:51 +00004039static const Expr *evaluateDeclExpr(const Decl *D) {
4040 if (!D)
Evgeniy Stepanov9b871492018-07-10 19:48:53 +00004041 return nullptr;
Alex Lorenz65317e12019-01-08 22:32:51 +00004042 if (auto *Var = dyn_cast<VarDecl>(D))
4043 return Var->getInit();
4044 else if (auto *Field = dyn_cast<FieldDecl>(D))
4045 return Field->getInClassInitializer();
4046 return nullptr;
4047}
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004048
Alex Lorenz65317e12019-01-08 22:32:51 +00004049static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4050 assert(CS && "invalid compound statement");
4051 for (auto *bodyIterator : CS->body()) {
4052 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4053 return E;
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004054 }
Alex Lorenzc4cf96e2018-07-09 19:56:45 +00004055 return nullptr;
4056}
4057
Alex Lorenz65317e12019-01-08 22:32:51 +00004058CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
Christian Kandeler72131422020-06-24 11:56:45 +01004059 const Expr *E = nullptr;
4060 if (clang_getCursorKind(C) == CXCursor_CompoundStmt)
4061 E = evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)));
4062 else if (clang_isDeclaration(C.kind))
4063 E = evaluateDeclExpr(getCursorDecl(C));
4064 else if (clang_isExpression(C.kind))
4065 E = getCursorExpr(C);
4066 if (E)
Alex Lorenz65317e12019-01-08 22:32:51 +00004067 return const_cast<CXEvalResult>(
4068 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4069 return nullptr;
4070}
4071
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004072unsigned clang_Cursor_hasAttrs(CXCursor C) {
4073 const Decl *D = getCursorDecl(C);
4074 if (!D) {
4075 return 0;
4076 }
4077
4078 if (D->hasAttrs()) {
4079 return 1;
4080 }
4081
4082 return 0;
4083}
Guy Benyei11169dd2012-12-18 14:30:41 +00004084unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4085 return CXSaveTranslationUnit_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05004086}
Guy Benyei11169dd2012-12-18 14:30:41 +00004087
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004088static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4089 const char *FileName,
4090 unsigned options) {
4091 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4093 setThreadBackgroundPriority();
4094
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004095 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4096 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00004097}
4098
4099int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4100 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004101 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004102
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004103 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004104 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004106 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004107
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004108 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4110 if (!CXXUnit->hasSema())
4111 return CXSaveError_InvalidTU;
4112
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004113 CXSaveError result;
4114 auto SaveTranslationUnitImpl = [=, &result]() {
4115 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4116 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004117
Erik Verbruggen3cc39112017-11-14 09:34:39 +00004118 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004119 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00004120
4121 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4122 PrintLibclangResourceUsage(TU);
4123
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004124 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 }
4126
4127 // We have an AST that has invalid nodes due to compiler errors.
4128 // Use a crash recovery thread for protection.
4129
4130 llvm::CrashRecoveryContext CRC;
4131
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004132 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4134 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4135 fprintf(stderr, " 'options' : %d,\n", options);
4136 fprintf(stderr, "}\n");
4137
4138 return CXSaveError_Unknown;
4139
4140 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4141 PrintLibclangResourceUsage(TU);
4142 }
4143
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004144 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004145}
4146
4147void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4148 if (CTUnit) {
4149 // If the translation unit has been marked as unsafe to free, just discard
4150 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004151 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4152 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 return;
4154
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004155 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00004156 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4158 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00004159 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00004160 delete CTUnit;
4161 }
4162}
4163
Erik Verbruggen346066b2017-05-30 14:25:54 +00004164unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4165 if (CTUnit) {
4166 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4167
4168 if (Unit && Unit->isUnsafeToFree())
4169 return false;
4170
4171 Unit->ResetForParse();
4172 return true;
4173 }
4174
4175 return false;
4176}
4177
Guy Benyei11169dd2012-12-18 14:30:41 +00004178unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4179 return CXReparse_None;
4180}
4181
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004182static CXErrorCode
4183clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4184 ArrayRef<CXUnsavedFile> unsaved_files,
4185 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004186 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004187 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004188 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004189 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004190 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004191
4192 // Reset the associated diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05004193 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00004194 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004195
Dmitri Gribenko183436e2013-01-26 21:49:50 +00004196 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4198 setThreadBackgroundPriority();
4199
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004200 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00004202
4203 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4204 new std::vector<ASTUnit::RemappedFile>());
4205
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05004207 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4208 RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00004209
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004210 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004211 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00004212 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004213 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004215
Adrian Prantlbb165fb2015-06-20 18:53:08 +00004216 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4217 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004218 return CXError_Success;
4219 if (isASTReadError(CXXUnit))
4220 return CXError_ASTReadError;
4221 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00004222}
4223
4224int clang_reparseTranslationUnit(CXTranslationUnit TU,
4225 unsigned num_unsaved_files,
4226 struct CXUnsavedFile *unsaved_files,
4227 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004228 LOG_FUNC_SECTION { *Log << TU; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004229
Alp Toker9d85b182014-07-07 01:23:14 +00004230 if (num_unsaved_files && !unsaved_files)
4231 return CXError_InvalidArguments;
4232
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004233 CXErrorCode result;
4234 auto ReparseTranslationUnitImpl = [=, &result]() {
4235 result = clang_reparseTranslationUnit_Impl(
4236 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
4237 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004238
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 llvm::CrashRecoveryContext CRC;
4240
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004241 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004242 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004243 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004244 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4246 PrintLibclangResourceUsage(TU);
4247
Alp Toker5c532982014-07-07 22:42:03 +00004248 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004249}
4250
Guy Benyei11169dd2012-12-18 14:30:41 +00004251CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004252 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004253 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004254 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004255 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004256
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004257 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004258 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004259}
4260
4261CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004262 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004263 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004264 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004265 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004266
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004267 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4269}
4270
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004271CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4272 if (isNotUsableTU(CTUnit)) {
4273 LOG_BAD_TU(CTUnit);
4274 return nullptr;
4275 }
4276
Michael Kruse7520cf02020-03-25 09:26:14 -05004277 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004278 impl->TranslationUnit = CTUnit;
4279 return impl;
4280}
4281
4282CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4283 if (!TargetInfo)
4284 return cxstring::createEmpty();
4285
4286 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4287 assert(!isNotUsableTU(CTUnit) &&
4288 "Unexpected unusable translation unit in TargetInfo");
4289
4290 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4291 std::string Triple =
Michael Kruse7520cf02020-03-25 09:26:14 -05004292 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004293 return cxstring::createDup(Triple);
4294}
4295
4296int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4297 if (!TargetInfo)
4298 return -1;
4299
4300 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4301 assert(!isNotUsableTU(CTUnit) &&
4302 "Unexpected unusable translation unit in TargetInfo");
4303
4304 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4305 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4306}
4307
4308void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4309 if (!TargetInfo)
4310 return;
4311
4312 delete TargetInfo;
4313}
4314
Guy Benyei11169dd2012-12-18 14:30:41 +00004315//===----------------------------------------------------------------------===//
4316// CXFile Operations.
4317//===----------------------------------------------------------------------===//
4318
Guy Benyei11169dd2012-12-18 14:30:41 +00004319CXString clang_getFileName(CXFile SFile) {
4320 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00004321 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00004322
4323 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004324 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004325}
4326
4327time_t clang_getFileTime(CXFile SFile) {
4328 if (!SFile)
4329 return 0;
4330
4331 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4332 return FEnt->getModificationTime();
4333}
4334
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004335CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004336 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004337 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00004338 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004339 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004340
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004341 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004342
4343 FileManager &FMgr = CXXUnit->getFileManager();
Harlan Haskins8d323d12019-08-01 21:31:56 +00004344 auto File = FMgr.getFile(file_name);
4345 if (!File)
4346 return nullptr;
4347 return const_cast<FileEntry *>(*File);
Guy Benyei11169dd2012-12-18 14:30:41 +00004348}
4349
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004350const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4351 size_t *size) {
4352 if (isNotUsableTU(TU)) {
4353 LOG_BAD_TU(TU);
4354 return nullptr;
4355 }
4356
4357 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4358 FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
4359 bool Invalid = true;
Nico Weber04347d82019-04-04 21:06:41 +00004360 const llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid);
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004361 if (Invalid) {
4362 if (size)
4363 *size = 0;
4364 return nullptr;
4365 }
4366 if (size)
4367 *size = buf->getBufferSize();
4368 return buf->getBufferStart();
4369}
4370
Michael Kruse7520cf02020-03-25 09:26:14 -05004371unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004372 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004373 LOG_BAD_TU(TU);
4374 return 0;
4375 }
4376
4377 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00004378 return 0;
4379
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004380 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004381 FileEntry *FEnt = static_cast<FileEntry *>(file);
Michael Kruse7520cf02020-03-25 09:26:14 -05004382 return CXXUnit->getPreprocessor()
4383 .getHeaderSearchInfo()
4384 .isFileMultipleIncludeGuarded(FEnt);
Guy Benyei11169dd2012-12-18 14:30:41 +00004385}
4386
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004387int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
4388 if (!file || !outID)
4389 return 1;
4390
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004391 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00004392 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
4393 outID->data[0] = ID.getDevice();
4394 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004395 outID->data[2] = FEnt->getModificationTime();
4396 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004397}
4398
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00004399int clang_File_isEqual(CXFile file1, CXFile file2) {
4400 if (file1 == file2)
4401 return true;
4402
4403 if (!file1 || !file2)
4404 return false;
4405
4406 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
4407 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
4408 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
4409}
4410
Fangrui Songe46ac5f2018-04-07 20:50:35 +00004411CXString clang_File_tryGetRealPathName(CXFile SFile) {
4412 if (!SFile)
4413 return cxstring::createNull();
4414
4415 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4416 return cxstring::createRef(FEnt->tryGetRealPathName());
4417}
4418
Guy Benyei11169dd2012-12-18 14:30:41 +00004419//===----------------------------------------------------------------------===//
4420// CXCursor Operations.
4421//===----------------------------------------------------------------------===//
4422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004423static const Decl *getDeclFromExpr(const Stmt *E) {
4424 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004425 return getDeclFromExpr(CE->getSubExpr());
4426
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004427 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004428 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004429 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004431 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004433 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 if (PRE->isExplicitProperty())
4435 return PRE->getExplicitProperty();
4436 // It could be messaging both getter and setter as in:
4437 // ++myobj.myprop;
4438 // in which case prefer to associate the setter since it is less obvious
4439 // from inspecting the source that the setter is going to get called.
4440 if (PRE->isMessagingSetter())
4441 return PRE->getImplicitPropertySetter();
4442 return PRE->getImplicitPropertyGetter();
4443 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004444 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004445 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004446 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004447 if (Expr *Src = OVE->getSourceExpr())
4448 return getDeclFromExpr(Src);
Michael Kruse7520cf02020-03-25 09:26:14 -05004449
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004450 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004452 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 if (!CE->isElidable())
Michael Kruse7520cf02020-03-25 09:26:14 -05004454 return CE->getConstructor();
Richard Smith5179eb72016-06-28 19:03:57 +00004455 if (const CXXInheritedCtorInitExpr *CE =
4456 dyn_cast<CXXInheritedCtorInitExpr>(E))
4457 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004458 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 return OME->getMethodDecl();
4460
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004461 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004462 return PE->getProtocol();
Michael Kruse7520cf02020-03-25 09:26:14 -05004463 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4464 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004466 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004467 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 isa<ParmVarDecl>(SizeOfPack->getPack()))
4469 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00004470
4471 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004472}
4473
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004474static SourceLocation getLocationFromExpr(const Expr *E) {
4475 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004476 return getLocationFromExpr(CE->getSubExpr());
4477
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004478 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004479 return /*FIXME:*/ Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004480 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004482 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004484 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004486 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004488 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 return PropRef->getLocation();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004490
4491 return E->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00004492}
4493
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00004494extern "C" {
4495
Michael Kruse7520cf02020-03-25 09:26:14 -05004496unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 CXClientData client_data) {
4498 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4499 /*VisitPreprocessorLast=*/false);
4500 return CursorVis.VisitChildren(parent);
4501}
4502
4503#ifndef __has_feature
4504#define __has_feature(x) 0
4505#endif
4506#if __has_feature(blocks)
Michael Kruse7520cf02020-03-25 09:26:14 -05004507typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4508 CXCursor parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00004509
4510static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004511 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4513 return block(cursor, parent);
4514}
4515#else
4516// If we are compiled with a compiler that doesn't have native blocks support,
Michael Kruse7520cf02020-03-25 09:26:14 -05004517// define and call the block manually, so the
4518typedef struct _CXChildVisitResult {
4519 void *isa;
4520 int flags;
4521 int reserved;
4522 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
4523 CXCursor);
4524} * CXCursorVisitorBlock;
Guy Benyei11169dd2012-12-18 14:30:41 +00004525
4526static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004527 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4529 return block->invoke(block, cursor, parent);
4530}
4531#endif
4532
Guy Benyei11169dd2012-12-18 14:30:41 +00004533unsigned clang_visitChildrenWithBlock(CXCursor parent,
4534 CXCursorVisitorBlock block) {
4535 return clang_visitChildren(parent, visitWithBlock, block);
4536}
4537
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004538static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004540 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004541
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004542 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004544 if (const ObjCPropertyImplDecl *PropImpl =
4545 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004547 return cxstring::createDup(Property->getIdentifier()->getName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004548
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004549 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004551 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004552
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004553 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004555
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004556 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004557 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004558
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004559 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4561 // and returns different names. NamedDecl returns the class name and
4562 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004563 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004564
4565 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004566 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05004567
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 SmallString<1024> S;
4569 llvm::raw_svector_ostream os(S);
4570 ND->printName(os);
Michael Kruse7520cf02020-03-25 09:26:14 -05004571
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004572 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004573}
4574
4575CXString clang_getCursorSpelling(CXCursor C) {
4576 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004577 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004578
4579 if (clang_isReference(C.kind)) {
4580 switch (C.kind) {
4581 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004582 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004583 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004584 }
4585 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004586 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004587 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 }
4589 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004590 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004592 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004593 }
4594 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004595 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004596 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 }
4598 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004599 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 assert(Type && "Missing type decl");
4601
Michael Kruse7520cf02020-03-25 09:26:14 -05004602 return cxstring::createDup(
4603 getCursorContext(C).getTypeDeclType(Type).getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 }
4605 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004606 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 assert(Template && "Missing template decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004608
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004609 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004611
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004613 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 assert(NS && "Missing namespace decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004615
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004616 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 }
4618
4619 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004620 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 assert(Field && "Missing member decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004622
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004623 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 }
4625
4626 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004627 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 assert(Label && "Missing label");
Michael Kruse7520cf02020-03-25 09:26:14 -05004629
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004630 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 }
4632
4633 case CXCursor_OverloadedDeclRef: {
4634 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004635 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4636 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004637 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004638 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004639 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004640 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004641 return cxstring::createDup(E->getName().getAsString());
Michael Kruse7520cf02020-03-25 09:26:14 -05004642 OverloadedTemplateStorage *Ovl =
4643 Storage.get<OverloadedTemplateStorage *>();
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004645 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004646 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004648
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004650 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 assert(Var && "Missing variable decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004652
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004653 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004655
Guy Benyei11169dd2012-12-18 14:30:41 +00004656 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004657 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 }
4659 }
4660
4661 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004662 const Expr *E = getCursorExpr(C);
4663
4664 if (C.kind == CXCursor_ObjCStringLiteral ||
4665 C.kind == CXCursor_StringLiteral) {
4666 const StringLiteral *SLit;
4667 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4668 SLit = OSL->getString();
4669 } else {
4670 SLit = cast<StringLiteral>(E);
4671 }
4672 SmallString<256> Buf;
4673 llvm::raw_svector_ostream OS(Buf);
4674 SLit->outputString(OS);
4675 return cxstring::createDup(OS.str());
4676 }
4677
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004678 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 if (D)
4680 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004681 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004682 }
4683
4684 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004685 const Stmt *S = getCursorStmt(C);
4686 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004687 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004688
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004689 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004691
Guy Benyei11169dd2012-12-18 14:30:41 +00004692 if (C.kind == CXCursor_MacroExpansion)
Michael Kruse7520cf02020-03-25 09:26:14 -05004693 return cxstring::createRef(
4694 getCursorMacroExpansion(C).getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004695
4696 if (C.kind == CXCursor_MacroDefinition)
Michael Kruse7520cf02020-03-25 09:26:14 -05004697 return cxstring::createRef(
4698 getCursorMacroDefinition(C)->getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004699
4700 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004701 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004702
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 if (clang_isDeclaration(C.kind))
4704 return getDeclSpelling(getCursorDecl(C));
4705
4706 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004707 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004708 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 }
4710
4711 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004712 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004713 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004714 }
4715
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004716 if (C.kind == CXCursor_PackedAttr) {
4717 return cxstring::createRef("packed");
4718 }
4719
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004720 if (C.kind == CXCursor_VisibilityAttr) {
4721 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4722 switch (AA->getVisibility()) {
4723 case VisibilityAttr::VisibilityType::Default:
4724 return cxstring::createRef("default");
4725 case VisibilityAttr::VisibilityType::Hidden:
4726 return cxstring::createRef("hidden");
4727 case VisibilityAttr::VisibilityType::Protected:
4728 return cxstring::createRef("protected");
4729 }
4730 llvm_unreachable("unknown visibility type");
4731 }
4732
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004733 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004734}
4735
Michael Kruse7520cf02020-03-25 09:26:14 -05004736CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 unsigned options) {
4738 if (clang_Cursor_isNull(C))
4739 return clang_getNullRange();
4740
4741 ASTContext &Ctx = getCursorContext(C);
4742
4743 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004744 const Stmt *S = getCursorStmt(C);
4745 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 if (pieceIndex > 0)
4747 return clang_getNullRange();
4748 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4749 }
4750
4751 return clang_getNullRange();
4752 }
4753
4754 if (C.kind == CXCursor_ObjCMessageExpr) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004755 if (const ObjCMessageExpr *ME =
4756 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 if (pieceIndex >= ME->getNumSelectorLocs())
4758 return clang_getNullRange();
4759 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4760 }
4761 }
4762
4763 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4764 C.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004765 if (const ObjCMethodDecl *MD =
4766 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 if (pieceIndex >= MD->getNumSelectorLocs())
4768 return clang_getNullRange();
4769 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4770 }
4771 }
4772
4773 if (C.kind == CXCursor_ObjCCategoryDecl ||
4774 C.kind == CXCursor_ObjCCategoryImplDecl) {
4775 if (pieceIndex > 0)
4776 return clang_getNullRange();
Michael Kruse7520cf02020-03-25 09:26:14 -05004777 if (const ObjCCategoryDecl *CD =
4778 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Michael Kruse7520cf02020-03-25 09:26:14 -05004780 if (const ObjCCategoryImplDecl *CID =
4781 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4783 }
4784
4785 if (C.kind == CXCursor_ModuleImportDecl) {
4786 if (pieceIndex > 0)
4787 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004788 if (const ImportDecl *ImportD =
4789 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004790 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4791 if (!Locs.empty())
Michael Kruse7520cf02020-03-25 09:26:14 -05004792 return cxloc::translateSourceRange(
4793 Ctx, SourceRange(Locs.front(), Locs.back()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004794 }
4795 return clang_getNullRange();
4796 }
4797
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004798 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
Kevin Funk4be5d672016-12-20 09:56:56 +00004799 C.kind == CXCursor_ConversionFunction ||
4800 C.kind == CXCursor_FunctionDecl) {
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004801 if (pieceIndex > 0)
4802 return clang_getNullRange();
4803 if (const FunctionDecl *FD =
4804 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4805 DeclarationNameInfo FunctionName = FD->getNameInfo();
4806 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4807 }
4808 return clang_getNullRange();
4809 }
4810
Guy Benyei11169dd2012-12-18 14:30:41 +00004811 // FIXME: A CXCursor_InclusionDirective should give the location of the
4812 // filename, but we don't keep track of this.
4813
4814 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4815 // but we don't keep track of this.
4816
4817 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4818 // but we don't keep track of this.
4819
4820 // Default handling, give the location of the cursor.
4821
4822 if (pieceIndex > 0)
4823 return clang_getNullRange();
4824
4825 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4826 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4827 return cxloc::translateSourceRange(Ctx, Loc);
4828}
4829
Eli Bendersky44a206f2014-07-31 18:04:56 +00004830CXString clang_Cursor_getMangling(CXCursor C) {
4831 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4832 return cxstring::createEmpty();
4833
Eli Bendersky44a206f2014-07-31 18:04:56 +00004834 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004835 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004836 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4837 return cxstring::createEmpty();
4838
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004839 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004840 ASTNameGenerator ASTNameGen(Ctx);
4841 return cxstring::createDup(ASTNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004842}
4843
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004844CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4845 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4846 return nullptr;
4847
4848 const Decl *D = getCursorDecl(C);
4849 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4850 return nullptr;
4851
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004852 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004853 ASTNameGenerator ASTNameGen(Ctx);
4854 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004855 return cxstring::createSet(Manglings);
4856}
4857
Dave Lee1a532c92017-09-22 16:58:57 +00004858CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
4859 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4860 return nullptr;
4861
4862 const Decl *D = getCursorDecl(C);
4863 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
4864 return nullptr;
4865
4866 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004867 ASTNameGenerator ASTNameGen(Ctx);
4868 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Dave Lee1a532c92017-09-22 16:58:57 +00004869 return cxstring::createSet(Manglings);
4870}
4871
Jonathan Coe45ef5032018-01-16 10:19:56 +00004872CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
4873 if (clang_Cursor_isNull(C))
4874 return 0;
4875 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
4876}
4877
4878void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
4879 if (Policy)
4880 delete static_cast<PrintingPolicy *>(Policy);
4881}
4882
4883unsigned
4884clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
4885 enum CXPrintingPolicyProperty Property) {
4886 if (!Policy)
4887 return 0;
4888
4889 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4890 switch (Property) {
4891 case CXPrintingPolicy_Indentation:
4892 return P->Indentation;
4893 case CXPrintingPolicy_SuppressSpecifiers:
4894 return P->SuppressSpecifiers;
4895 case CXPrintingPolicy_SuppressTagKeyword:
4896 return P->SuppressTagKeyword;
4897 case CXPrintingPolicy_IncludeTagDefinition:
4898 return P->IncludeTagDefinition;
4899 case CXPrintingPolicy_SuppressScope:
4900 return P->SuppressScope;
4901 case CXPrintingPolicy_SuppressUnwrittenScope:
4902 return P->SuppressUnwrittenScope;
4903 case CXPrintingPolicy_SuppressInitializers:
4904 return P->SuppressInitializers;
4905 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4906 return P->ConstantArraySizeAsWritten;
4907 case CXPrintingPolicy_AnonymousTagLocations:
4908 return P->AnonymousTagLocations;
4909 case CXPrintingPolicy_SuppressStrongLifetime:
4910 return P->SuppressStrongLifetime;
4911 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4912 return P->SuppressLifetimeQualifiers;
4913 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4914 return P->SuppressTemplateArgsInCXXConstructors;
4915 case CXPrintingPolicy_Bool:
4916 return P->Bool;
4917 case CXPrintingPolicy_Restrict:
4918 return P->Restrict;
4919 case CXPrintingPolicy_Alignof:
4920 return P->Alignof;
4921 case CXPrintingPolicy_UnderscoreAlignof:
4922 return P->UnderscoreAlignof;
4923 case CXPrintingPolicy_UseVoidForZeroParams:
4924 return P->UseVoidForZeroParams;
4925 case CXPrintingPolicy_TerseOutput:
4926 return P->TerseOutput;
4927 case CXPrintingPolicy_PolishForDeclaration:
4928 return P->PolishForDeclaration;
4929 case CXPrintingPolicy_Half:
4930 return P->Half;
4931 case CXPrintingPolicy_MSWChar:
4932 return P->MSWChar;
4933 case CXPrintingPolicy_IncludeNewlines:
4934 return P->IncludeNewlines;
4935 case CXPrintingPolicy_MSVCFormatting:
4936 return P->MSVCFormatting;
4937 case CXPrintingPolicy_ConstantsAsWritten:
4938 return P->ConstantsAsWritten;
4939 case CXPrintingPolicy_SuppressImplicitBase:
4940 return P->SuppressImplicitBase;
4941 case CXPrintingPolicy_FullyQualifiedName:
4942 return P->FullyQualifiedName;
4943 }
4944
4945 assert(false && "Invalid CXPrintingPolicyProperty");
4946 return 0;
4947}
4948
4949void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
4950 enum CXPrintingPolicyProperty Property,
4951 unsigned Value) {
4952 if (!Policy)
4953 return;
4954
4955 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4956 switch (Property) {
4957 case CXPrintingPolicy_Indentation:
4958 P->Indentation = Value;
4959 return;
4960 case CXPrintingPolicy_SuppressSpecifiers:
4961 P->SuppressSpecifiers = Value;
4962 return;
4963 case CXPrintingPolicy_SuppressTagKeyword:
4964 P->SuppressTagKeyword = Value;
4965 return;
4966 case CXPrintingPolicy_IncludeTagDefinition:
4967 P->IncludeTagDefinition = Value;
4968 return;
4969 case CXPrintingPolicy_SuppressScope:
4970 P->SuppressScope = Value;
4971 return;
4972 case CXPrintingPolicy_SuppressUnwrittenScope:
4973 P->SuppressUnwrittenScope = Value;
4974 return;
4975 case CXPrintingPolicy_SuppressInitializers:
4976 P->SuppressInitializers = Value;
4977 return;
4978 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4979 P->ConstantArraySizeAsWritten = Value;
4980 return;
4981 case CXPrintingPolicy_AnonymousTagLocations:
4982 P->AnonymousTagLocations = Value;
4983 return;
4984 case CXPrintingPolicy_SuppressStrongLifetime:
4985 P->SuppressStrongLifetime = Value;
4986 return;
4987 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4988 P->SuppressLifetimeQualifiers = Value;
4989 return;
4990 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4991 P->SuppressTemplateArgsInCXXConstructors = Value;
4992 return;
4993 case CXPrintingPolicy_Bool:
4994 P->Bool = Value;
4995 return;
4996 case CXPrintingPolicy_Restrict:
4997 P->Restrict = Value;
4998 return;
4999 case CXPrintingPolicy_Alignof:
5000 P->Alignof = Value;
5001 return;
5002 case CXPrintingPolicy_UnderscoreAlignof:
5003 P->UnderscoreAlignof = Value;
5004 return;
5005 case CXPrintingPolicy_UseVoidForZeroParams:
5006 P->UseVoidForZeroParams = Value;
5007 return;
5008 case CXPrintingPolicy_TerseOutput:
5009 P->TerseOutput = Value;
5010 return;
5011 case CXPrintingPolicy_PolishForDeclaration:
5012 P->PolishForDeclaration = Value;
5013 return;
5014 case CXPrintingPolicy_Half:
5015 P->Half = Value;
5016 return;
5017 case CXPrintingPolicy_MSWChar:
5018 P->MSWChar = Value;
5019 return;
5020 case CXPrintingPolicy_IncludeNewlines:
5021 P->IncludeNewlines = Value;
5022 return;
5023 case CXPrintingPolicy_MSVCFormatting:
5024 P->MSVCFormatting = Value;
5025 return;
5026 case CXPrintingPolicy_ConstantsAsWritten:
5027 P->ConstantsAsWritten = Value;
5028 return;
5029 case CXPrintingPolicy_SuppressImplicitBase:
5030 P->SuppressImplicitBase = Value;
5031 return;
5032 case CXPrintingPolicy_FullyQualifiedName:
5033 P->FullyQualifiedName = Value;
5034 return;
5035 }
5036
5037 assert(false && "Invalid CXPrintingPolicyProperty");
5038}
5039
5040CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
5041 if (clang_Cursor_isNull(C))
5042 return cxstring::createEmpty();
5043
5044 if (clang_isDeclaration(C.kind)) {
5045 const Decl *D = getCursorDecl(C);
5046 if (!D)
5047 return cxstring::createEmpty();
5048
5049 SmallString<128> Str;
5050 llvm::raw_svector_ostream OS(Str);
5051 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5052 D->print(OS, UserPolicy ? *UserPolicy
5053 : getCursorContext(C).getPrintingPolicy());
5054
5055 return cxstring::createDup(OS.str());
5056 }
5057
5058 return cxstring::createEmpty();
5059}
5060
Guy Benyei11169dd2012-12-18 14:30:41 +00005061CXString clang_getCursorDisplayName(CXCursor C) {
5062 if (!clang_isDeclaration(C.kind))
5063 return clang_getCursorSpelling(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05005064
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005065 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005066 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005067 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005068
5069 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005070 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005071 D = FunTmpl->getTemplatedDecl();
Michael Kruse7520cf02020-03-25 09:26:14 -05005072
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005073 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005074 SmallString<64> Str;
5075 llvm::raw_svector_ostream OS(Str);
5076 OS << *Function;
5077 if (Function->getPrimaryTemplate())
5078 OS << "<>";
5079 OS << "(";
5080 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5081 if (I)
5082 OS << ", ";
5083 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5084 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005085
Guy Benyei11169dd2012-12-18 14:30:41 +00005086 if (Function->isVariadic()) {
5087 if (Function->getNumParams())
5088 OS << ", ";
5089 OS << "...";
5090 }
5091 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005092 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005093 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005094
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005095 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005096 SmallString<64> Str;
5097 llvm::raw_svector_ostream OS(Str);
5098 OS << *ClassTemplate;
5099 OS << "<";
5100 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5101 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5102 if (I)
5103 OS << ", ";
Michael Kruse7520cf02020-03-25 09:26:14 -05005104
Guy Benyei11169dd2012-12-18 14:30:41 +00005105 NamedDecl *Param = Params->getParam(I);
5106 if (Param->getIdentifier()) {
5107 OS << Param->getIdentifier()->getName();
5108 continue;
5109 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005110
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 // There is no parameter name, which makes this tricky. Try to come up
5112 // with something useful that isn't too long.
5113 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
Saar Razff1e0fc2020-01-15 02:48:42 +02005114 if (const auto *TC = TTP->getTypeConstraint()) {
5115 TC->getConceptNameInfo().printName(OS, Policy);
5116 if (TC->hasExplicitTemplateArgs())
5117 OS << "<...>";
5118 } else
Michael Kruse7520cf02020-03-25 09:26:14 -05005119 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5120 else if (NonTypeTemplateParmDecl *NTTP =
5121 dyn_cast<NonTypeTemplateParmDecl>(Param))
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 OS << NTTP->getType().getAsString(Policy);
5123 else
5124 OS << "template<...> class";
5125 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005126
Guy Benyei11169dd2012-12-18 14:30:41 +00005127 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005128 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005129 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005130
5131 if (const ClassTemplateSpecializationDecl *ClassSpec =
5132 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005133 // If the type was explicitly written, use that.
5134 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005135 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Serge Pavlov03e672c2017-11-28 16:14:14 +00005136
Benjamin Kramer9170e912013-02-22 15:46:01 +00005137 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 llvm::raw_svector_ostream OS(Str);
5139 OS << *ClassSpec;
Serge Pavlov03e672c2017-11-28 16:14:14 +00005140 printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
5141 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005142 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005143 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005144
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 return clang_getCursorSpelling(C);
5146}
Michael Kruse7520cf02020-03-25 09:26:14 -05005147
Guy Benyei11169dd2012-12-18 14:30:41 +00005148CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5149 switch (Kind) {
5150 case CXCursor_FunctionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005151 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 case CXCursor_TypedefDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005153 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 case CXCursor_EnumDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005155 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 case CXCursor_EnumConstantDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005157 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 case CXCursor_StructDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005159 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 case CXCursor_UnionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005161 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 case CXCursor_ClassDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005163 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 case CXCursor_FieldDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005165 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 case CXCursor_VarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005167 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 case CXCursor_ParmDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005169 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 case CXCursor_ObjCInterfaceDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005171 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 case CXCursor_ObjCCategoryDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005173 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 case CXCursor_ObjCProtocolDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005175 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 case CXCursor_ObjCPropertyDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005177 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 case CXCursor_ObjCIvarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005179 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 case CXCursor_ObjCInstanceMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005181 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 case CXCursor_ObjCClassMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005183 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 case CXCursor_ObjCImplementationDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005185 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 case CXCursor_ObjCCategoryImplDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005187 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 case CXCursor_CXXMethod:
Michael Kruse7520cf02020-03-25 09:26:14 -05005189 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 case CXCursor_UnexposedDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005191 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005193 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 case CXCursor_ObjCProtocolRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005195 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 case CXCursor_ObjCClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005197 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 case CXCursor_TypeRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005199 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 case CXCursor_TemplateRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005201 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005203 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005205 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005207 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005209 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005211 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 case CXCursor_IntegerLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005213 return cxstring::createRef("IntegerLiteral");
Leonard Chandb01c3a2018-06-20 17:19:40 +00005214 case CXCursor_FixedPointLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005215 return cxstring::createRef("FixedPointLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 case CXCursor_FloatingLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005217 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 case CXCursor_ImaginaryLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005219 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 case CXCursor_StringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005221 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 case CXCursor_CharacterLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005223 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 case CXCursor_ParenExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005225 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 case CXCursor_UnaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005227 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 case CXCursor_ArraySubscriptExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005229 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00005230 case CXCursor_OMPArraySectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005231 return cxstring::createRef("OMPArraySectionExpr");
Alexey Bataev7ac9efb2020-02-05 09:33:05 -05005232 case CXCursor_OMPArrayShapingExpr:
5233 return cxstring::createRef("OMPArrayShapingExpr");
Alexey Bataev13a15042020-04-01 15:06:38 -04005234 case CXCursor_OMPIteratorExpr:
5235 return cxstring::createRef("OMPIteratorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 case CXCursor_BinaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005237 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 case CXCursor_CompoundAssignOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005239 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 case CXCursor_ConditionalOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005241 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 case CXCursor_CStyleCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005243 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 case CXCursor_CompoundLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005245 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 case CXCursor_InitListExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005247 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 case CXCursor_AddrLabelExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005249 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 case CXCursor_StmtExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005251 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 case CXCursor_GenericSelectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005253 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 case CXCursor_GNUNullExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005255 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 case CXCursor_CXXStaticCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005257 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 case CXCursor_CXXDynamicCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005259 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 case CXCursor_CXXReinterpretCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005261 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 case CXCursor_CXXConstCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005263 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 case CXCursor_CXXFunctionalCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005265 return cxstring::createRef("CXXFunctionalCastExpr");
Anastasia Stulovaa6a237f2020-05-18 11:02:01 +01005266 case CXCursor_CXXAddrspaceCastExpr:
5267 return cxstring::createRef("CXXAddrspaceCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 case CXCursor_CXXTypeidExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005269 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 case CXCursor_CXXBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005271 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005272 case CXCursor_CXXNullPtrLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005273 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 case CXCursor_CXXThisExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005275 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 case CXCursor_CXXThrowExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005277 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 case CXCursor_CXXNewExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005279 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 case CXCursor_CXXDeleteExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005281 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 case CXCursor_UnaryExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005283 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 case CXCursor_ObjCStringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005285 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 case CXCursor_ObjCBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005287 return cxstring::createRef("ObjCBoolLiteralExpr");
Erik Pilkington29099de2016-07-16 00:35:23 +00005288 case CXCursor_ObjCAvailabilityCheckExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005289 return cxstring::createRef("ObjCAvailabilityCheckExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00005290 case CXCursor_ObjCSelfExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005291 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 case CXCursor_ObjCEncodeExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005293 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 case CXCursor_ObjCSelectorExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005295 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 case CXCursor_ObjCProtocolExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005297 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 case CXCursor_ObjCBridgedCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005299 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 case CXCursor_BlockExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005301 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 case CXCursor_PackExpansionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005303 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 case CXCursor_SizeOfPackExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005305 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005307 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 case CXCursor_UnexposedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005309 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 case CXCursor_DeclRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005311 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 case CXCursor_MemberRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005313 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005315 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 case CXCursor_ObjCMessageExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005317 return cxstring::createRef("ObjCMessageExpr");
Erik Pilkingtoneee944e2019-07-02 18:28:13 +00005318 case CXCursor_BuiltinBitCastExpr:
5319 return cxstring::createRef("BuiltinBitCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 case CXCursor_UnexposedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005321 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 case CXCursor_DeclStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005323 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 case CXCursor_LabelStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005325 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 case CXCursor_CompoundStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005327 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 case CXCursor_CaseStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005329 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 case CXCursor_DefaultStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005331 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 case CXCursor_IfStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005333 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 case CXCursor_SwitchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005335 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 case CXCursor_WhileStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005337 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 case CXCursor_DoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005339 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 case CXCursor_ForStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005341 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 case CXCursor_GotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005343 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 case CXCursor_IndirectGotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005345 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 case CXCursor_ContinueStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005347 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 case CXCursor_BreakStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005349 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 case CXCursor_ReturnStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005351 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 case CXCursor_GCCAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005353 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 case CXCursor_MSAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005355 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 case CXCursor_ObjCAtTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005357 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 case CXCursor_ObjCAtCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005359 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 case CXCursor_ObjCAtFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005361 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 case CXCursor_ObjCAtThrowStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005363 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 case CXCursor_ObjCAtSynchronizedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005365 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 case CXCursor_ObjCAutoreleasePoolStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005367 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005368 case CXCursor_ObjCForCollectionStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005369 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 case CXCursor_CXXCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005371 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 case CXCursor_CXXTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005373 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 case CXCursor_CXXForRangeStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005375 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 case CXCursor_SEHTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005377 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 case CXCursor_SEHExceptStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005379 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 case CXCursor_SEHFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005381 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00005382 case CXCursor_SEHLeaveStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005383 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005384 case CXCursor_NullStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005385 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005386 case CXCursor_InvalidFile:
Michael Kruse7520cf02020-03-25 09:26:14 -05005387 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00005388 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005389 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00005390 case CXCursor_NoDeclFound:
Michael Kruse7520cf02020-03-25 09:26:14 -05005391 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00005392 case CXCursor_NotImplemented:
Michael Kruse7520cf02020-03-25 09:26:14 -05005393 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00005394 case CXCursor_TranslationUnit:
Michael Kruse7520cf02020-03-25 09:26:14 -05005395 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00005396 case CXCursor_UnexposedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005397 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005398 case CXCursor_IBActionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005399 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005400 case CXCursor_IBOutletAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005401 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005402 case CXCursor_IBOutletCollectionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005403 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005404 case CXCursor_CXXFinalAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005405 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005406 case CXCursor_CXXOverrideAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005407 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005409 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005410 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005411 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005412 case CXCursor_PackedAttr:
5413 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00005414 case CXCursor_PureAttr:
5415 return cxstring::createRef("attribute(pure)");
5416 case CXCursor_ConstAttr:
5417 return cxstring::createRef("attribute(const)");
5418 case CXCursor_NoDuplicateAttr:
5419 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00005420 case CXCursor_CUDAConstantAttr:
5421 return cxstring::createRef("attribute(constant)");
5422 case CXCursor_CUDADeviceAttr:
5423 return cxstring::createRef("attribute(device)");
5424 case CXCursor_CUDAGlobalAttr:
5425 return cxstring::createRef("attribute(global)");
5426 case CXCursor_CUDAHostAttr:
5427 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00005428 case CXCursor_CUDASharedAttr:
5429 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00005430 case CXCursor_VisibilityAttr:
5431 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00005432 case CXCursor_DLLExport:
5433 return cxstring::createRef("attribute(dllexport)");
5434 case CXCursor_DLLImport:
5435 return cxstring::createRef("attribute(dllimport)");
Michael Wud092d0b2018-08-03 05:03:22 +00005436 case CXCursor_NSReturnsRetained:
5437 return cxstring::createRef("attribute(ns_returns_retained)");
5438 case CXCursor_NSReturnsNotRetained:
5439 return cxstring::createRef("attribute(ns_returns_not_retained)");
5440 case CXCursor_NSReturnsAutoreleased:
5441 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5442 case CXCursor_NSConsumesSelf:
5443 return cxstring::createRef("attribute(ns_consumes_self)");
5444 case CXCursor_NSConsumed:
5445 return cxstring::createRef("attribute(ns_consumed)");
5446 case CXCursor_ObjCException:
5447 return cxstring::createRef("attribute(objc_exception)");
5448 case CXCursor_ObjCNSObject:
5449 return cxstring::createRef("attribute(NSObject)");
5450 case CXCursor_ObjCIndependentClass:
5451 return cxstring::createRef("attribute(objc_independent_class)");
5452 case CXCursor_ObjCPreciseLifetime:
5453 return cxstring::createRef("attribute(objc_precise_lifetime)");
5454 case CXCursor_ObjCReturnsInnerPointer:
5455 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5456 case CXCursor_ObjCRequiresSuper:
5457 return cxstring::createRef("attribute(objc_requires_super)");
5458 case CXCursor_ObjCRootClass:
5459 return cxstring::createRef("attribute(objc_root_class)");
5460 case CXCursor_ObjCSubclassingRestricted:
5461 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5462 case CXCursor_ObjCExplicitProtocolImpl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005463 return cxstring::createRef(
5464 "attribute(objc_protocol_requires_explicit_implementation)");
Michael Wud092d0b2018-08-03 05:03:22 +00005465 case CXCursor_ObjCDesignatedInitializer:
5466 return cxstring::createRef("attribute(objc_designated_initializer)");
5467 case CXCursor_ObjCRuntimeVisible:
5468 return cxstring::createRef("attribute(objc_runtime_visible)");
5469 case CXCursor_ObjCBoxable:
5470 return cxstring::createRef("attribute(objc_boxable)");
Michael Wu58d837d2018-08-03 05:55:40 +00005471 case CXCursor_FlagEnum:
5472 return cxstring::createRef("attribute(flag_enum)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005474 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005476 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005478 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005480 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005482 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005484 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005486 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005488 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005490 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005492 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005493 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005494 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005496 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005498 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005499 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005500 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005501 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005502 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005504 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005506 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005508 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00005509 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005510 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005512 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005513 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005514 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005516 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005518 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005520 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005521 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00005522 return cxstring::createRef("OMPParallelDirective");
5523 case CXCursor_OMPSimdDirective:
5524 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00005525 case CXCursor_OMPForDirective:
5526 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00005527 case CXCursor_OMPForSimdDirective:
5528 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00005529 case CXCursor_OMPSectionsDirective:
5530 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00005531 case CXCursor_OMPSectionDirective:
5532 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00005533 case CXCursor_OMPSingleDirective:
5534 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00005535 case CXCursor_OMPMasterDirective:
5536 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00005537 case CXCursor_OMPCriticalDirective:
5538 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00005539 case CXCursor_OMPParallelForDirective:
5540 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00005541 case CXCursor_OMPParallelForSimdDirective:
5542 return cxstring::createRef("OMPParallelForSimdDirective");
cchen47d60942019-12-05 13:43:48 -05005543 case CXCursor_OMPParallelMasterDirective:
5544 return cxstring::createRef("OMPParallelMasterDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00005545 case CXCursor_OMPParallelSectionsDirective:
5546 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00005547 case CXCursor_OMPTaskDirective:
5548 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00005549 case CXCursor_OMPTaskyieldDirective:
5550 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00005551 case CXCursor_OMPBarrierDirective:
5552 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00005553 case CXCursor_OMPTaskwaitDirective:
5554 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00005555 case CXCursor_OMPTaskgroupDirective:
5556 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00005557 case CXCursor_OMPFlushDirective:
5558 return cxstring::createRef("OMPFlushDirective");
Alexey Bataevc112e942020-02-28 09:52:15 -05005559 case CXCursor_OMPDepobjDirective:
5560 return cxstring::createRef("OMPDepobjDirective");
Alexey Bataevfcba7c32020-03-20 07:03:01 -04005561 case CXCursor_OMPScanDirective:
5562 return cxstring::createRef("OMPScanDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00005563 case CXCursor_OMPOrderedDirective:
5564 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00005565 case CXCursor_OMPAtomicDirective:
5566 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00005567 case CXCursor_OMPTargetDirective:
5568 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00005569 case CXCursor_OMPTargetDataDirective:
5570 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00005571 case CXCursor_OMPTargetEnterDataDirective:
5572 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00005573 case CXCursor_OMPTargetExitDataDirective:
5574 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00005575 case CXCursor_OMPTargetParallelDirective:
5576 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00005577 case CXCursor_OMPTargetParallelForDirective:
5578 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00005579 case CXCursor_OMPTargetUpdateDirective:
5580 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00005581 case CXCursor_OMPTeamsDirective:
5582 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00005583 case CXCursor_OMPCancellationPointDirective:
5584 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00005585 case CXCursor_OMPCancelDirective:
5586 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00005587 case CXCursor_OMPTaskLoopDirective:
5588 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005589 case CXCursor_OMPTaskLoopSimdDirective:
5590 return cxstring::createRef("OMPTaskLoopSimdDirective");
Alexey Bataev60e51c42019-10-10 20:13:02 +00005591 case CXCursor_OMPMasterTaskLoopDirective:
5592 return cxstring::createRef("OMPMasterTaskLoopDirective");
Alexey Bataevb8552ab2019-10-18 16:47:35 +00005593 case CXCursor_OMPMasterTaskLoopSimdDirective:
5594 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
Alexey Bataev5bbcead2019-10-14 17:17:41 +00005595 case CXCursor_OMPParallelMasterTaskLoopDirective:
5596 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
Alexey Bataev14a388f2019-10-25 10:27:13 -04005597 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5598 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00005599 case CXCursor_OMPDistributeDirective:
5600 return cxstring::createRef("OMPDistributeDirective");
Carlo Bertolli9925f152016-06-27 14:55:37 +00005601 case CXCursor_OMPDistributeParallelForDirective:
5602 return cxstring::createRef("OMPDistributeParallelForDirective");
Kelvin Li4a39add2016-07-05 05:00:15 +00005603 case CXCursor_OMPDistributeParallelForSimdDirective:
5604 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
Kelvin Li787f3fc2016-07-06 04:45:38 +00005605 case CXCursor_OMPDistributeSimdDirective:
5606 return cxstring::createRef("OMPDistributeSimdDirective");
Kelvin Lia579b912016-07-14 02:54:56 +00005607 case CXCursor_OMPTargetParallelForSimdDirective:
5608 return cxstring::createRef("OMPTargetParallelForSimdDirective");
Kelvin Li986330c2016-07-20 22:57:10 +00005609 case CXCursor_OMPTargetSimdDirective:
5610 return cxstring::createRef("OMPTargetSimdDirective");
Kelvin Li02532872016-08-05 14:37:37 +00005611 case CXCursor_OMPTeamsDistributeDirective:
5612 return cxstring::createRef("OMPTeamsDistributeDirective");
Kelvin Li4e325f72016-10-25 12:50:55 +00005613 case CXCursor_OMPTeamsDistributeSimdDirective:
5614 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
Kelvin Li579e41c2016-11-30 23:51:03 +00005615 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5616 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
Kelvin Li7ade93f2016-12-09 03:24:30 +00005617 case CXCursor_OMPTeamsDistributeParallelForDirective:
5618 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
Kelvin Libf594a52016-12-17 05:48:59 +00005619 case CXCursor_OMPTargetTeamsDirective:
5620 return cxstring::createRef("OMPTargetTeamsDirective");
Kelvin Li83c451e2016-12-25 04:52:54 +00005621 case CXCursor_OMPTargetTeamsDistributeDirective:
5622 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
Kelvin Li80e8f562016-12-29 22:16:30 +00005623 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5624 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
Kelvin Li1851df52017-01-03 05:23:48 +00005625 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5626 return cxstring::createRef(
5627 "OMPTargetTeamsDistributeParallelForSimdDirective");
Kelvin Lida681182017-01-10 18:08:18 +00005628 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5629 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00005630 case CXCursor_OverloadCandidate:
Michael Kruse7520cf02020-03-25 09:26:14 -05005631 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00005632 case CXCursor_TypeAliasTemplateDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005633 return cxstring::createRef("TypeAliasTemplateDecl");
Olivier Goffart81978012016-06-09 16:15:55 +00005634 case CXCursor_StaticAssert:
Michael Kruse7520cf02020-03-25 09:26:14 -05005635 return cxstring::createRef("StaticAssert");
Olivier Goffartd211c642016-11-04 06:29:27 +00005636 case CXCursor_FriendDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005637 return cxstring::createRef("FriendDecl");
Sven van Haastregtdc2c9302019-02-11 11:00:56 +00005638 case CXCursor_ConvergentAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005639 return cxstring::createRef("attribute(convergent)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005640 case CXCursor_WarnUnusedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005641 return cxstring::createRef("attribute(warn_unused)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005642 case CXCursor_WarnUnusedResultAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005643 return cxstring::createRef("attribute(warn_unused_result)");
Emilio Cobos Alvarezcd741272019-03-13 16:16:54 +00005644 case CXCursor_AlignedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005645 return cxstring::createRef("attribute(aligned)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 }
5647
5648 llvm_unreachable("Unhandled CXCursorKind");
5649}
5650
5651struct GetCursorData {
5652 SourceLocation TokenBeginLoc;
5653 bool PointsAtMacroArgExpansion;
5654 bool VisitedObjCPropertyImplDecl;
5655 SourceLocation VisitedDeclaratorDeclStartLoc;
5656 CXCursor &BestCursor;
5657
Michael Kruse7520cf02020-03-25 09:26:14 -05005658 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5659 CXCursor &outputCursor)
5660 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005661 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5662 VisitedObjCPropertyImplDecl = false;
5663 }
5664};
5665
Michael Kruse7520cf02020-03-25 09:26:14 -05005666static enum CXChildVisitResult
5667GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005668 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5669 CXCursor *BestCursor = &Data->BestCursor;
5670
5671 // If we point inside a macro argument we should provide info of what the
5672 // token is so use the actual cursor, don't replace it with a macro expansion
5673 // cursor.
5674 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5675 return CXChildVisit_Recurse;
Michael Kruse7520cf02020-03-25 09:26:14 -05005676
Guy Benyei11169dd2012-12-18 14:30:41 +00005677 if (clang_isDeclaration(cursor.kind)) {
5678 // Avoid having the implicit methods override the property decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05005679 if (const ObjCMethodDecl *MD =
5680 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 if (MD->isImplicit())
5682 return CXChildVisit_Break;
5683
Michael Kruse7520cf02020-03-25 09:26:14 -05005684 } else if (const ObjCInterfaceDecl *ID =
5685 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005686 // Check that when we have multiple @class references in the same line,
5687 // that later ones do not override the previous ones.
5688 // If we have:
5689 // @class Foo, Bar;
5690 // source ranges for both start at '@', so 'Bar' will end up overriding
5691 // 'Foo' even though the cursor location was at 'Foo'.
5692 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5693 BestCursor->kind == CXCursor_ObjCClassRef)
Michael Kruse7520cf02020-03-25 09:26:14 -05005694 if (const ObjCInterfaceDecl *PrevID =
5695 dyn_cast_or_null<ObjCInterfaceDecl>(
5696 getCursorDecl(*BestCursor))) {
5697 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5698 !ID->isThisDeclarationADefinition())
5699 return CXChildVisit_Break;
Guy Benyei11169dd2012-12-18 14:30:41 +00005700 }
5701
Michael Kruse7520cf02020-03-25 09:26:14 -05005702 } else if (const DeclaratorDecl *DD =
5703 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005704 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5705 // Check that when we have multiple declarators in the same line,
5706 // that later ones do not override the previous ones.
5707 // If we have:
5708 // int Foo, Bar;
5709 // source ranges for both start at 'int', so 'Bar' will end up overriding
5710 // 'Foo' even though the cursor location was at 'Foo'.
5711 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5712 return CXChildVisit_Break;
5713 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5714
Michael Kruse7520cf02020-03-25 09:26:14 -05005715 } else if (const ObjCPropertyImplDecl *PropImp =
5716 dyn_cast_or_null<ObjCPropertyImplDecl>(
5717 getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005718 (void)PropImp;
5719 // Check that when we have multiple @synthesize in the same line,
5720 // that later ones do not override the previous ones.
5721 // If we have:
5722 // @synthesize Foo, Bar;
5723 // source ranges for both start at '@', so 'Bar' will end up overriding
5724 // 'Foo' even though the cursor location was at 'Foo'.
5725 if (Data->VisitedObjCPropertyImplDecl)
5726 return CXChildVisit_Break;
5727 Data->VisitedObjCPropertyImplDecl = true;
5728 }
5729 }
5730
5731 if (clang_isExpression(cursor.kind) &&
5732 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005733 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 // Avoid having the cursor of an expression replace the declaration cursor
5735 // when the expression source range overlaps the declaration range.
5736 // This can happen for C++ constructor expressions whose range generally
5737 // include the variable declaration, e.g.:
Michael Kruse7520cf02020-03-25 09:26:14 -05005738 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5739 // cursor.
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5741 D->getLocation() == Data->TokenBeginLoc)
5742 return CXChildVisit_Break;
5743 }
5744 }
5745
Michael Kruse7520cf02020-03-25 09:26:14 -05005746 // If our current best cursor is the construction of a temporary object,
5747 // don't replace that cursor with a type reference, because we want
Guy Benyei11169dd2012-12-18 14:30:41 +00005748 // clang_getCursor() to point at the constructor.
5749 if (clang_isExpression(BestCursor->kind) &&
5750 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5751 cursor.kind == CXCursor_TypeRef) {
5752 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5753 // as having the actual point on the type reference.
5754 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5755 return CXChildVisit_Recurse;
5756 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005757
5758 // If we already have an Objective-C superclass reference, don't
5759 // update it further.
5760 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5761 return CXChildVisit_Break;
5762
Guy Benyei11169dd2012-12-18 14:30:41 +00005763 *BestCursor = cursor;
5764 return CXChildVisit_Recurse;
5765}
5766
5767CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005768 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005769 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005771 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005772
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005773 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5775
5776 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5777 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5778
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005779 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 CXFile SearchFile;
5781 unsigned SearchLine, SearchColumn;
5782 CXFile ResultFile;
5783 unsigned ResultLine, ResultColumn;
5784 CXString SearchFileName, ResultFileName, KindSpelling, USR;
Michael Kruse7520cf02020-03-25 09:26:14 -05005785 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
Guy Benyei11169dd2012-12-18 14:30:41 +00005786 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005787
5788 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5789 nullptr);
Michael Kruse7520cf02020-03-25 09:26:14 -05005790 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5791 nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005792 SearchFileName = clang_getFileName(SearchFile);
5793 ResultFileName = clang_getFileName(ResultFile);
5794 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5795 USR = clang_getCursorUSR(Result);
Michael Kruse7520cf02020-03-25 09:26:14 -05005796 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5797 SearchLine, SearchColumn,
5798 clang_getCString(KindSpelling))
5799 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5800 ResultLine, ResultColumn, clang_getCString(USR),
5801 IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005802 clang_disposeString(SearchFileName);
5803 clang_disposeString(ResultFileName);
5804 clang_disposeString(KindSpelling);
5805 clang_disposeString(USR);
Michael Kruse7520cf02020-03-25 09:26:14 -05005806
Guy Benyei11169dd2012-12-18 14:30:41 +00005807 CXCursor Definition = clang_getCursorDefinition(Result);
5808 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5809 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
Michael Kruse7520cf02020-03-25 09:26:14 -05005810 CXString DefinitionKindSpelling =
5811 clang_getCursorKindSpelling(Definition.kind);
Guy Benyei11169dd2012-12-18 14:30:41 +00005812 CXFile DefinitionFile;
5813 unsigned DefinitionLine, DefinitionColumn;
Michael Kruse7520cf02020-03-25 09:26:14 -05005814 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5815 &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005816 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005817 *Log << llvm::format(" -> %s(%s:%d:%d)",
Michael Kruse7520cf02020-03-25 09:26:14 -05005818 clang_getCString(DefinitionKindSpelling),
5819 clang_getCString(DefinitionFileName), DefinitionLine,
5820 DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005821 clang_disposeString(DefinitionFileName);
5822 clang_disposeString(DefinitionKindSpelling);
5823 }
5824 }
5825
5826 return Result;
5827}
5828
5829CXCursor clang_getNullCursor(void) {
5830 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5831}
5832
5833unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005834 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5835 // can't set consistently. For example, when visiting a DeclStmt we will set
5836 // it but we don't set it on the result of clang_getCursorDefinition for
5837 // a reference of the same declaration.
5838 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5839 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5840 // to provide that kind of info.
5841 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005842 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005843 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005844 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005845
Guy Benyei11169dd2012-12-18 14:30:41 +00005846 return X == Y;
5847}
5848
5849unsigned clang_hashCursor(CXCursor C) {
5850 unsigned Index = 0;
5851 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5852 Index = 1;
Michael Kruse7520cf02020-03-25 09:26:14 -05005853
5854 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5855 std::make_pair(C.kind, C.data[Index]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005856}
5857
5858unsigned clang_isInvalid(enum CXCursorKind K) {
5859 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5860}
5861
5862unsigned clang_isDeclaration(enum CXCursorKind K) {
5863 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005864 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5865}
5866
Ivan Donchevskii08ff9102018-01-04 10:59:50 +00005867unsigned clang_isInvalidDeclaration(CXCursor C) {
5868 if (clang_isDeclaration(C.kind)) {
5869 if (const Decl *D = getCursorDecl(C))
5870 return D->isInvalidDecl();
5871 }
5872
5873 return 0;
5874}
5875
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005876unsigned clang_isReference(enum CXCursorKind K) {
5877 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5878}
Guy Benyei11169dd2012-12-18 14:30:41 +00005879
5880unsigned clang_isExpression(enum CXCursorKind K) {
5881 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5882}
5883
5884unsigned clang_isStatement(enum CXCursorKind K) {
5885 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5886}
5887
5888unsigned clang_isAttribute(enum CXCursorKind K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005889 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005890}
5891
5892unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5893 return K == CXCursor_TranslationUnit;
5894}
5895
5896unsigned clang_isPreprocessing(enum CXCursorKind K) {
5897 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5898}
Michael Kruse7520cf02020-03-25 09:26:14 -05005899
Guy Benyei11169dd2012-12-18 14:30:41 +00005900unsigned clang_isUnexposed(enum CXCursorKind K) {
5901 switch (K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005902 case CXCursor_UnexposedDecl:
5903 case CXCursor_UnexposedExpr:
5904 case CXCursor_UnexposedStmt:
5905 case CXCursor_UnexposedAttr:
5906 return true;
5907 default:
5908 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005909 }
5910}
5911
Michael Kruse7520cf02020-03-25 09:26:14 -05005912CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005913
5914CXSourceLocation clang_getCursorLocation(CXCursor C) {
5915 if (clang_isReference(C.kind)) {
5916 switch (C.kind) {
5917 case CXCursor_ObjCSuperClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005918 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5919 getCursorObjCSuperClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005920 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5921 }
5922
5923 case CXCursor_ObjCProtocolRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005924 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5925 getCursorObjCProtocolRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005926 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5927 }
5928
5929 case CXCursor_ObjCClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005930 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5931 getCursorObjCClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005932 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5933 }
5934
5935 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005936 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005937 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5938 }
5939
5940 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005941 std::pair<const TemplateDecl *, SourceLocation> P =
5942 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005943 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5944 }
5945
5946 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005947 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005948 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5949 }
5950
5951 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005952 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005953 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5954 }
5955
5956 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005957 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005958 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5959 }
5960
5961 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005962 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005963 if (!BaseSpec)
5964 return clang_getNullLocation();
Michael Kruse7520cf02020-03-25 09:26:14 -05005965
Guy Benyei11169dd2012-12-18 14:30:41 +00005966 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
Michael Kruse7520cf02020-03-25 09:26:14 -05005967 return cxloc::translateSourceLocation(
5968 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005969
Guy Benyei11169dd2012-12-18 14:30:41 +00005970 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005971 BaseSpec->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 }
5973
5974 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005975 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5977 }
5978
5979 case CXCursor_OverloadedDeclRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005980 return cxloc::translateSourceLocation(
5981 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
Guy Benyei11169dd2012-12-18 14:30:41 +00005982
5983 default:
5984 // FIXME: Need a way to enumerate all non-reference cases.
5985 llvm_unreachable("Missed a reference kind");
5986 }
5987 }
5988
5989 if (clang_isExpression(C.kind))
Michael Kruse7520cf02020-03-25 09:26:14 -05005990 return cxloc::translateSourceLocation(
5991 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
Guy Benyei11169dd2012-12-18 14:30:41 +00005992
5993 if (clang_isStatement(C.kind))
5994 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005995 getCursorStmt(C)->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005996
5997 if (C.kind == CXCursor_PreprocessingDirective) {
5998 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
5999 return cxloc::translateSourceLocation(getCursorContext(C), L);
6000 }
6001
6002 if (C.kind == CXCursor_MacroExpansion) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006003 SourceLocation L =
6004 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00006005 return cxloc::translateSourceLocation(getCursorContext(C), L);
6006 }
6007
6008 if (C.kind == CXCursor_MacroDefinition) {
6009 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
6010 return cxloc::translateSourceLocation(getCursorContext(C), L);
6011 }
6012
6013 if (C.kind == CXCursor_InclusionDirective) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006014 SourceLocation L =
6015 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 return cxloc::translateSourceLocation(getCursorContext(C), L);
6017 }
6018
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00006019 if (clang_isAttribute(C.kind)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006020 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00006021 return cxloc::translateSourceLocation(getCursorContext(C), L);
6022 }
6023
Guy Benyei11169dd2012-12-18 14:30:41 +00006024 if (!clang_isDeclaration(C.kind))
6025 return clang_getNullLocation();
6026
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006027 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006028 if (!D)
6029 return clang_getNullLocation();
6030
6031 SourceLocation Loc = D->getLocation();
6032 // FIXME: Multiple variables declared in a single declaration
6033 // currently lack the information needed to correctly determine their
6034 // ranges when accounting for the type-specifier. We use context
6035 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6036 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006037 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006038 if (!cxcursor::isFirstInDeclGroup(C))
6039 Loc = VD->getLocation();
6040 }
6041
6042 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006043 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006044 Loc = MD->getSelectorStartLoc();
6045
6046 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
6047}
6048
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00006049} // end extern "C"
6050
Guy Benyei11169dd2012-12-18 14:30:41 +00006051CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6052 assert(TU);
6053
6054 // Guard against an invalid SourceLocation, or we may assert in one
6055 // of the following calls.
6056 if (SLoc.isInvalid())
6057 return clang_getNullCursor();
6058
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006059 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006060
6061 // Translate the given source location to make it point at the beginning of
6062 // the token under the cursor.
6063 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6064 CXXUnit->getASTContext().getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05006065
Guy Benyei11169dd2012-12-18 14:30:41 +00006066 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6067 if (SLoc.isValid()) {
6068 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6069 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Michael Kruse7520cf02020-03-25 09:26:14 -05006070 /*VisitPreprocessorLast=*/true,
Guy Benyei11169dd2012-12-18 14:30:41 +00006071 /*VisitIncludedEntities=*/false,
6072 SourceLocation(SLoc));
6073 CursorVis.visitFileRegion();
6074 }
6075
6076 return Result;
6077}
6078
6079static SourceRange getRawCursorExtent(CXCursor C) {
6080 if (clang_isReference(C.kind)) {
6081 switch (C.kind) {
6082 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05006083 return getCursorObjCSuperClassRef(C).second;
Guy Benyei11169dd2012-12-18 14:30:41 +00006084
6085 case CXCursor_ObjCProtocolRef:
6086 return getCursorObjCProtocolRef(C).second;
6087
6088 case CXCursor_ObjCClassRef:
6089 return getCursorObjCClassRef(C).second;
6090
6091 case CXCursor_TypeRef:
6092 return getCursorTypeRef(C).second;
6093
6094 case CXCursor_TemplateRef:
6095 return getCursorTemplateRef(C).second;
6096
6097 case CXCursor_NamespaceRef:
6098 return getCursorNamespaceRef(C).second;
6099
6100 case CXCursor_MemberRef:
6101 return getCursorMemberRef(C).second;
6102
6103 case CXCursor_CXXBaseSpecifier:
6104 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6105
6106 case CXCursor_LabelRef:
6107 return getCursorLabelRef(C).second;
6108
6109 case CXCursor_OverloadedDeclRef:
6110 return getCursorOverloadedDeclRef(C).second;
6111
6112 case CXCursor_VariableRef:
6113 return getCursorVariableRef(C).second;
Michael Kruse7520cf02020-03-25 09:26:14 -05006114
Guy Benyei11169dd2012-12-18 14:30:41 +00006115 default:
6116 // FIXME: Need a way to enumerate all non-reference cases.
6117 llvm_unreachable("Missed a reference kind");
6118 }
6119 }
6120
6121 if (clang_isExpression(C.kind))
6122 return getCursorExpr(C)->getSourceRange();
6123
6124 if (clang_isStatement(C.kind))
6125 return getCursorStmt(C)->getSourceRange();
6126
6127 if (clang_isAttribute(C.kind))
6128 return getCursorAttr(C)->getRange();
6129
6130 if (C.kind == CXCursor_PreprocessingDirective)
6131 return cxcursor::getCursorPreprocessingDirective(C);
6132
6133 if (C.kind == CXCursor_MacroExpansion) {
6134 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006135 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006136 return TU->mapRangeFromPreamble(Range);
6137 }
6138
6139 if (C.kind == CXCursor_MacroDefinition) {
6140 ASTUnit *TU = getCursorASTUnit(C);
6141 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6142 return TU->mapRangeFromPreamble(Range);
6143 }
6144
6145 if (C.kind == CXCursor_InclusionDirective) {
6146 ASTUnit *TU = getCursorASTUnit(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05006147 SourceRange Range =
6148 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 return TU->mapRangeFromPreamble(Range);
6150 }
6151
6152 if (C.kind == CXCursor_TranslationUnit) {
6153 ASTUnit *TU = getCursorASTUnit(C);
6154 FileID MainID = TU->getSourceManager().getMainFileID();
6155 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6156 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6157 return SourceRange(Start, End);
6158 }
6159
6160 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006161 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006162 if (!D)
6163 return SourceRange();
6164
6165 SourceRange R = D->getSourceRange();
6166 // FIXME: Multiple variables declared in a single declaration
6167 // currently lack the information needed to correctly determine their
6168 // ranges when accounting for the type-specifier. We use context
6169 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6170 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006171 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006172 if (!cxcursor::isFirstInDeclGroup(C))
6173 R.setBegin(VD->getLocation());
6174 }
6175 return R;
6176 }
6177 return SourceRange();
6178}
6179
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006180/// Retrieves the "raw" cursor extent, which is then extended to include
Guy Benyei11169dd2012-12-18 14:30:41 +00006181/// the decl-specifier-seq for declarations.
6182static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6183 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006184 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006185 if (!D)
6186 return SourceRange();
6187
6188 SourceRange R = D->getSourceRange();
6189
6190 // Adjust the start of the location for declarations preceded by
6191 // declaration specifiers.
6192 SourceLocation StartLoc;
6193 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6194 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006195 StartLoc = TI->getTypeLoc().getBeginLoc();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006196 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006197 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006198 StartLoc = TI->getTypeLoc().getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00006199 }
6200
6201 if (StartLoc.isValid() && R.getBegin().isValid() &&
6202 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6203 R.setBegin(StartLoc);
6204
6205 // FIXME: Multiple variables declared in a single declaration
6206 // currently lack the information needed to correctly determine their
6207 // ranges when accounting for the type-specifier. We use context
6208 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6209 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006210 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006211 if (!cxcursor::isFirstInDeclGroup(C))
6212 R.setBegin(VD->getLocation());
6213 }
6214
Michael Kruse7520cf02020-03-25 09:26:14 -05006215 return R;
Guy Benyei11169dd2012-12-18 14:30:41 +00006216 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006217
Guy Benyei11169dd2012-12-18 14:30:41 +00006218 return getRawCursorExtent(C);
6219}
6220
Guy Benyei11169dd2012-12-18 14:30:41 +00006221CXSourceRange clang_getCursorExtent(CXCursor C) {
6222 SourceRange R = getRawCursorExtent(C);
6223 if (R.isInvalid())
6224 return clang_getNullRange();
6225
6226 return cxloc::translateSourceRange(getCursorContext(C), R);
6227}
6228
6229CXCursor clang_getCursorReferenced(CXCursor C) {
6230 if (clang_isInvalid(C.kind))
6231 return clang_getNullCursor();
6232
6233 CXTranslationUnit tu = getCursorTU(C);
6234 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006235 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006236 if (!D)
6237 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006238 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006239 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006240 if (const ObjCPropertyImplDecl *PropImpl =
6241 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006242 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6243 return MakeCXCursor(Property, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006244
Guy Benyei11169dd2012-12-18 14:30:41 +00006245 return C;
6246 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006247
Guy Benyei11169dd2012-12-18 14:30:41 +00006248 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006249 const Expr *E = getCursorExpr(C);
6250 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00006251 if (D) {
6252 CXCursor declCursor = MakeCXCursor(D, tu);
6253 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6254 declCursor);
6255 return declCursor;
6256 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006257
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006258 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00006259 return MakeCursorOverloadedDeclRef(Ovl, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006260
Guy Benyei11169dd2012-12-18 14:30:41 +00006261 return clang_getNullCursor();
6262 }
6263
6264 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006265 const Stmt *S = getCursorStmt(C);
6266 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00006267 if (LabelDecl *label = Goto->getLabel())
6268 if (LabelStmt *labelS = label->getStmt())
Michael Kruse7520cf02020-03-25 09:26:14 -05006269 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006270
6271 return clang_getNullCursor();
6272 }
Richard Smith66a81862015-05-04 02:25:31 +00006273
Guy Benyei11169dd2012-12-18 14:30:41 +00006274 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00006275 if (const MacroDefinitionRecord *Def =
6276 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006277 return MakeMacroDefinitionCursor(Def, tu);
6278 }
6279
6280 if (!clang_isReference(C.kind))
6281 return clang_getNullCursor();
6282
6283 switch (C.kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006284 case CXCursor_ObjCSuperClassRef:
6285 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006286
Michael Kruse7520cf02020-03-25 09:26:14 -05006287 case CXCursor_ObjCProtocolRef: {
6288 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6289 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6290 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006291
Michael Kruse7520cf02020-03-25 09:26:14 -05006292 return MakeCXCursor(Prot, tu);
6293 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006294
Michael Kruse7520cf02020-03-25 09:26:14 -05006295 case CXCursor_ObjCClassRef: {
6296 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6297 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6298 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006299
Michael Kruse7520cf02020-03-25 09:26:14 -05006300 return MakeCXCursor(Class, tu);
6301 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006302
Michael Kruse7520cf02020-03-25 09:26:14 -05006303 case CXCursor_TypeRef:
6304 return MakeCXCursor(getCursorTypeRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006305
Michael Kruse7520cf02020-03-25 09:26:14 -05006306 case CXCursor_TemplateRef:
6307 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006308
Michael Kruse7520cf02020-03-25 09:26:14 -05006309 case CXCursor_NamespaceRef:
6310 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006311
Michael Kruse7520cf02020-03-25 09:26:14 -05006312 case CXCursor_MemberRef:
6313 return MakeCXCursor(getCursorMemberRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006314
Michael Kruse7520cf02020-03-25 09:26:14 -05006315 case CXCursor_CXXBaseSpecifier: {
6316 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6317 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6318 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006319
Michael Kruse7520cf02020-03-25 09:26:14 -05006320 case CXCursor_LabelRef:
6321 // FIXME: We end up faking the "parent" declaration here because we
6322 // don't want to make CXCursor larger.
6323 return MakeCXCursor(
6324 getCursorLabelRef(C).first,
6325 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006326
Michael Kruse7520cf02020-03-25 09:26:14 -05006327 case CXCursor_OverloadedDeclRef:
6328 return C;
Guy Benyei11169dd2012-12-18 14:30:41 +00006329
Michael Kruse7520cf02020-03-25 09:26:14 -05006330 case CXCursor_VariableRef:
6331 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6332
6333 default:
6334 // We would prefer to enumerate all non-reference cursor kinds here.
6335 llvm_unreachable("Unhandled reference cursor kind");
Guy Benyei11169dd2012-12-18 14:30:41 +00006336 }
6337}
6338
6339CXCursor clang_getCursorDefinition(CXCursor C) {
6340 if (clang_isInvalid(C.kind))
6341 return clang_getNullCursor();
6342
6343 CXTranslationUnit TU = getCursorTU(C);
6344
6345 bool WasReference = false;
6346 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6347 C = clang_getCursorReferenced(C);
6348 WasReference = true;
6349 }
6350
6351 if (C.kind == CXCursor_MacroExpansion)
6352 return clang_getCursorReferenced(C);
6353
6354 if (!clang_isDeclaration(C.kind))
6355 return clang_getNullCursor();
6356
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006357 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006358 if (!D)
6359 return clang_getNullCursor();
6360
6361 switch (D->getKind()) {
6362 // Declaration kinds that don't really separate the notions of
6363 // declaration and definition.
6364 case Decl::Namespace:
6365 case Decl::Typedef:
6366 case Decl::TypeAlias:
6367 case Decl::TypeAliasTemplate:
6368 case Decl::TemplateTypeParm:
6369 case Decl::EnumConstant:
6370 case Decl::Field:
Richard Smithbdb84f32016-07-22 23:36:59 +00006371 case Decl::Binding:
John McCall5e77d762013-04-16 07:28:30 +00006372 case Decl::MSProperty:
Richard Smithbab6df82020-04-11 22:15:29 -07006373 case Decl::MSGuid:
Guy Benyei11169dd2012-12-18 14:30:41 +00006374 case Decl::IndirectField:
6375 case Decl::ObjCIvar:
6376 case Decl::ObjCAtDefsField:
6377 case Decl::ImplicitParam:
6378 case Decl::ParmVar:
6379 case Decl::NonTypeTemplateParm:
6380 case Decl::TemplateTemplateParm:
6381 case Decl::ObjCCategoryImpl:
6382 case Decl::ObjCImplementation:
6383 case Decl::AccessSpec:
6384 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006385 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006386 case Decl::ObjCPropertyImpl:
6387 case Decl::FileScopeAsm:
6388 case Decl::StaticAssert:
6389 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006390 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006391 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006392 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006393 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006394 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006395 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006396 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006397 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006398 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006399 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006400 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006401 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006402 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006403 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006404 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006405 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006406 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006407 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006408 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006409 return C;
6410
6411 // Declaration kinds that don't make any sense here, but are
6412 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006413 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006415 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006416 break;
6417
6418 // Declaration kinds for which the definition is not resolvable.
6419 case Decl::UnresolvedUsingTypename:
6420 case Decl::UnresolvedUsingValue:
6421 break;
6422
6423 case Decl::UsingDirective:
6424 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6425 TU);
6426
6427 case Decl::NamespaceAlias:
6428 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6429
6430 case Decl::Enum:
6431 case Decl::Record:
6432 case Decl::CXXRecord:
6433 case Decl::ClassTemplateSpecialization:
6434 case Decl::ClassTemplatePartialSpecialization:
6435 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6436 return MakeCXCursor(Def, TU);
6437 return clang_getNullCursor();
6438
6439 case Decl::Function:
6440 case Decl::CXXMethod:
6441 case Decl::CXXConstructor:
6442 case Decl::CXXDestructor:
6443 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006444 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006445 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006446 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006447 return clang_getNullCursor();
6448 }
6449
Larisse Voufo39a1e502013-08-06 01:03:05 +00006450 case Decl::Var:
6451 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006452 case Decl::VarTemplatePartialSpecialization:
6453 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006455 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006456 return MakeCXCursor(Def, TU);
6457 return clang_getNullCursor();
6458 }
6459
6460 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006461 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6463 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6464 return clang_getNullCursor();
6465 }
6466
6467 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006468 if (RecordDecl *Def =
6469 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006470 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6471 TU);
6472 return clang_getNullCursor();
6473 }
6474
Larisse Voufo39a1e502013-08-06 01:03:05 +00006475 case Decl::VarTemplate: {
6476 if (VarDecl *Def =
6477 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6478 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6479 return clang_getNullCursor();
6480 }
6481
Guy Benyei11169dd2012-12-18 14:30:41 +00006482 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006483 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6484 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006485
6486 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006487 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006488 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006489 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006490
6491 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006492 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006493 if (Method->isThisDeclarationADefinition())
6494 return C;
6495
6496 // Dig out the method definition in the associated
6497 // @implementation, if we have it.
6498 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006499 if (const ObjCInterfaceDecl *Class =
6500 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006501 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006502 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6503 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006504 if (Def->isThisDeclarationADefinition())
6505 return MakeCXCursor(Def, TU);
6506
6507 return clang_getNullCursor();
6508 }
6509
6510 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006511 if (ObjCCategoryImplDecl *Impl =
6512 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006513 return MakeCXCursor(Impl, TU);
6514 return clang_getNullCursor();
6515
6516 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006517 if (const ObjCProtocolDecl *Def =
6518 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006519 return MakeCXCursor(Def, TU);
6520 return clang_getNullCursor();
6521
6522 case Decl::ObjCInterface: {
6523 // There are two notions of a "definition" for an Objective-C
6524 // class: the interface and its implementation. When we resolved a
6525 // reference to an Objective-C class, produce the @interface as
6526 // the definition; when we were provided with the interface,
6527 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006528 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006529 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006530 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006531 return MakeCXCursor(Def, TU);
6532 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6533 return MakeCXCursor(Impl, TU);
6534 return clang_getNullCursor();
6535 }
6536
6537 case Decl::ObjCProperty:
6538 // FIXME: We don't really know where to find the
6539 // ObjCPropertyImplDecls that implement this property.
6540 return clang_getNullCursor();
6541
6542 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006543 if (const ObjCInterfaceDecl *Class =
6544 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006545 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006546 return MakeCXCursor(Def, TU);
6547
6548 return clang_getNullCursor();
6549
6550 case Decl::Friend:
6551 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6552 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6553 return clang_getNullCursor();
6554
6555 case Decl::FriendTemplate:
6556 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6557 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6558 return clang_getNullCursor();
6559 }
6560
6561 return clang_getNullCursor();
6562}
6563
6564unsigned clang_isCursorDefinition(CXCursor C) {
6565 if (!clang_isDeclaration(C.kind))
6566 return 0;
6567
6568 return clang_getCursorDefinition(C) == C;
6569}
6570
6571CXCursor clang_getCanonicalCursor(CXCursor C) {
6572 if (!clang_isDeclaration(C.kind))
6573 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006574
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006575 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006576 if (const ObjCCategoryImplDecl *CatImplD =
6577 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006578 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6579 return MakeCXCursor(CatD, getCursorTU(C));
6580
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006581 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6582 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006583 return MakeCXCursor(IFD, getCursorTU(C));
6584
6585 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6586 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006587
Guy Benyei11169dd2012-12-18 14:30:41 +00006588 return C;
6589}
6590
6591int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6592 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6593}
Michael Kruse7520cf02020-03-25 09:26:14 -05006594
Guy Benyei11169dd2012-12-18 14:30:41 +00006595unsigned clang_getNumOverloadedDecls(CXCursor C) {
6596 if (C.kind != CXCursor_OverloadedDeclRef)
6597 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006598
Guy Benyei11169dd2012-12-18 14:30:41 +00006599 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006600 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006601 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006602
6603 if (OverloadedTemplateStorage *S =
6604 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006605 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006606
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006607 const Decl *D = Storage.get<const Decl *>();
6608 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006609 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006610
Guy Benyei11169dd2012-12-18 14:30:41 +00006611 return 0;
6612}
6613
6614CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6615 if (cursor.kind != CXCursor_OverloadedDeclRef)
6616 return clang_getNullCursor();
6617
6618 if (index >= clang_getNumOverloadedDecls(cursor))
6619 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006620
Guy Benyei11169dd2012-12-18 14:30:41 +00006621 CXTranslationUnit TU = getCursorTU(cursor);
6622 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006623 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006624 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006625
6626 if (OverloadedTemplateStorage *S =
6627 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006628 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006629
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006630 const Decl *D = Storage.get<const Decl *>();
6631 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006632 // FIXME: This is, unfortunately, linear time.
6633 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6634 std::advance(Pos, index);
6635 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6636 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006637
Guy Benyei11169dd2012-12-18 14:30:41 +00006638 return clang_getNullCursor();
6639}
Michael Kruse7520cf02020-03-25 09:26:14 -05006640
6641void clang_getDefinitionSpellingAndExtent(
6642 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6643 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006644 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006645 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006646 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6647
6648 SourceManager &SM = FD->getASTContext().getSourceManager();
6649 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6650 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6651 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6652 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6653 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6654 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6655}
6656
Guy Benyei11169dd2012-12-18 14:30:41 +00006657CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6658 unsigned PieceIndex) {
6659 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006660
Guy Benyei11169dd2012-12-18 14:30:41 +00006661 switch (C.kind) {
6662 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006663 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006664 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6665 E->getQualifierLoc().getSourceRange());
6666 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006667
Guy Benyei11169dd2012-12-18 14:30:41 +00006668 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006669 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6670 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6671 Pieces =
6672 buildPieces(NameFlags, false, E->getNameInfo(),
6673 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6674 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006675 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006676
Guy Benyei11169dd2012-12-18 14:30:41 +00006677 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006678 if (const CXXOperatorCallExpr *OCE =
6679 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006680 const Expr *Callee = OCE->getCallee();
6681 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006682 Callee = ICE->getSubExpr();
6683
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006684 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006685 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6686 DRE->getQualifierLoc().getSourceRange());
6687 }
6688 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006689
Guy Benyei11169dd2012-12-18 14:30:41 +00006690 default:
6691 break;
6692 }
6693
6694 if (Pieces.empty()) {
6695 if (PieceIndex == 0)
6696 return clang_getCursorExtent(C);
6697 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006698 SourceRange R = Pieces[PieceIndex];
6699 if (R.isValid())
6700 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006701 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006702
Guy Benyei11169dd2012-12-18 14:30:41 +00006703 return clang_getNullRange();
6704}
6705
6706void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006707 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6708 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006709}
6710
Michael Kruse7520cf02020-03-25 09:26:14 -05006711void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006712 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006713 llvm::llvm_execute_on_thread(fn, user_data,
6714 stack_size == 0
6715 ? clang::DesiredStackSize
6716 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006717}
6718
Guy Benyei11169dd2012-12-18 14:30:41 +00006719//===----------------------------------------------------------------------===//
6720// Token-based Operations.
6721//===----------------------------------------------------------------------===//
6722
6723/* CXToken layout:
6724 * int_data[0]: a CXTokenKind
6725 * int_data[1]: starting token location
6726 * int_data[2]: token length
6727 * int_data[3]: reserved
6728 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6729 * otherwise unused.
6730 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006731CXTokenKind clang_getTokenKind(CXToken CXTok) {
6732 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6733}
6734
6735CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6736 switch (clang_getTokenKind(CXTok)) {
6737 case CXToken_Identifier:
6738 case CXToken_Keyword:
6739 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006740 return cxstring::createRef(
6741 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006742
6743 case CXToken_Literal: {
6744 // We have stashed the starting pointer in the ptr_data field. Use it.
6745 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006746 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006747 }
6748
6749 case CXToken_Punctuation:
6750 case CXToken_Comment:
6751 break;
6752 }
6753
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006754 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006755 LOG_BAD_TU(TU);
6756 return cxstring::createEmpty();
6757 }
6758
Guy Benyei11169dd2012-12-18 14:30:41 +00006759 // We have to find the starting buffer pointer the hard way, by
6760 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006761 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006762 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006763 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006764
6765 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006766 std::pair<FileID, unsigned> LocInfo =
6767 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006768 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006769 StringRef Buffer =
6770 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006771 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006772 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006773
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006774 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006775}
6776
6777CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006778 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006779 LOG_BAD_TU(TU);
6780 return clang_getNullLocation();
6781 }
6782
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006783 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006784 if (!CXXUnit)
6785 return clang_getNullLocation();
6786
Michael Kruse7520cf02020-03-25 09:26:14 -05006787 return cxloc::translateSourceLocation(
6788 CXXUnit->getASTContext(),
6789 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006790}
6791
6792CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006793 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006794 LOG_BAD_TU(TU);
6795 return clang_getNullRange();
6796 }
6797
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006798 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006799 if (!CXXUnit)
6800 return clang_getNullRange();
6801
Michael Kruse7520cf02020-03-25 09:26:14 -05006802 return cxloc::translateSourceRange(
6803 CXXUnit->getASTContext(),
6804 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006805}
6806
6807static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6808 SmallVectorImpl<CXToken> &CXTokens) {
6809 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006810 std::pair<FileID, unsigned> BeginLocInfo =
6811 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6812 std::pair<FileID, unsigned> EndLocInfo =
6813 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006814
6815 // Cannot tokenize across files.
6816 if (BeginLocInfo.first != EndLocInfo.first)
6817 return;
6818
6819 // Create a lexer
6820 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006821 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006822 if (Invalid)
6823 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006824
Guy Benyei11169dd2012-12-18 14:30:41 +00006825 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006826 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6827 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006828 Lex.SetCommentRetentionState(true);
6829
6830 // Lex tokens until we hit the end of the range.
6831 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6832 Token Tok;
6833 bool previousWasAt = false;
6834 do {
6835 // Lex the next token
6836 Lex.LexFromRawLexer(Tok);
6837 if (Tok.is(tok::eof))
6838 break;
6839
6840 // Initialize the CXToken.
6841 CXToken CXTok;
6842
6843 // - Common fields
6844 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6845 CXTok.int_data[2] = Tok.getLength();
6846 CXTok.int_data[3] = 0;
6847
6848 // - Kind-specific fields
6849 if (Tok.isLiteral()) {
6850 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006851 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006852 } else if (Tok.is(tok::raw_identifier)) {
6853 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006854 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006855
6856 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6857 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006858 } else {
6859 CXTok.int_data[0] =
6860 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006861 }
6862 CXTok.ptr_data = II;
6863 } else if (Tok.is(tok::comment)) {
6864 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006865 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006866 } else {
6867 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006868 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006869 }
6870 CXTokens.push_back(CXTok);
6871 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006872 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006873}
6874
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006875CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006876 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006877
6878 if (isNotUsableTU(TU)) {
6879 LOG_BAD_TU(TU);
6880 return NULL;
6881 }
6882
6883 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6884 if (!CXXUnit)
6885 return NULL;
6886
6887 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6888 if (Begin.isInvalid())
6889 return NULL;
6890 SourceManager &SM = CXXUnit->getSourceManager();
6891 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006892 DecomposedEnd.second +=
6893 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006894
Michael Kruse7520cf02020-03-25 09:26:14 -05006895 SourceLocation End =
6896 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006897
6898 SmallVector<CXToken, 32> CXTokens;
6899 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6900
6901 if (CXTokens.empty())
6902 return NULL;
6903
6904 CXTokens.resize(1);
6905 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6906
6907 memmove(Token, CXTokens.data(), sizeof(CXToken));
6908 return Token;
6909}
6910
Michael Kruse7520cf02020-03-25 09:26:14 -05006911void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6912 unsigned *NumTokens) {
6913 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006914
Guy Benyei11169dd2012-12-18 14:30:41 +00006915 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006916 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006917 if (NumTokens)
6918 *NumTokens = 0;
6919
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006920 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006921 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006922 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006923 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006924
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006925 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006926 if (!CXXUnit || !Tokens || !NumTokens)
6927 return;
6928
6929 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006930
Guy Benyei11169dd2012-12-18 14:30:41 +00006931 SourceRange R = cxloc::translateCXSourceRange(Range);
6932 if (R.isInvalid())
6933 return;
6934
6935 SmallVector<CXToken, 32> CXTokens;
6936 getTokens(CXXUnit, R, CXTokens);
6937
6938 if (CXTokens.empty())
6939 return;
6940
Serge Pavlov52525732018-02-21 02:02:39 +00006941 *Tokens = static_cast<CXToken *>(
6942 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006943 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6944 *NumTokens = CXTokens.size();
6945}
6946
Michael Kruse7520cf02020-03-25 09:26:14 -05006947void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6948 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006949 free(Tokens);
6950}
6951
Guy Benyei11169dd2012-12-18 14:30:41 +00006952//===----------------------------------------------------------------------===//
6953// Token annotation APIs.
6954//===----------------------------------------------------------------------===//
6955
Guy Benyei11169dd2012-12-18 14:30:41 +00006956static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6957 CXCursor parent,
6958 CXClientData client_data);
6959static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6960 CXClientData client_data);
6961
6962namespace {
6963class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006964 CXToken *Tokens;
6965 CXCursor *Cursors;
6966 unsigned NumTokens;
6967 unsigned TokIdx;
6968 unsigned PreprocessingTokIdx;
6969 CursorVisitor AnnotateVis;
6970 SourceManager &SrcMgr;
6971 bool HasContextSensitiveKeywords;
6972
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006973 struct PostChildrenAction {
6974 CXCursor cursor;
6975 enum Action { Invalid, Ignore, Postpone } action;
6976 };
6977 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6978
Guy Benyei11169dd2012-12-18 14:30:41 +00006979 struct PostChildrenInfo {
6980 CXCursor Cursor;
6981 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006982 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006983 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006984 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006985 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006986 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006987
6988 CXToken &getTok(unsigned Idx) {
6989 assert(Idx < NumTokens);
6990 return Tokens[Idx];
6991 }
6992 const CXToken &getTok(unsigned Idx) const {
6993 assert(Idx < NumTokens);
6994 return Tokens[Idx];
6995 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006996 bool MoreTokens() const { return TokIdx < NumTokens; }
6997 unsigned NextToken() const { return TokIdx; }
6998 void AdvanceToken() { ++TokIdx; }
6999 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007000 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007001 }
7002 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007003 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007004 }
7005 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007006 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007007 }
7008
7009 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007010 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00007011 SourceRange);
7012
7013public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007014 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007015 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05007016 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
7017 PreprocessingTokIdx(0),
7018 AnnotateVis(TU, AnnotateTokensVisitor, this,
7019 /*VisitPreprocessorLast=*/true,
7020 /*VisitIncludedEntities=*/false, RegionOfInterest,
7021 /*VisitDeclsOnly=*/false,
7022 AnnotateTokensPostChildrenVisitor),
7023 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
7024 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007025
7026 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
7027 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007028 bool IsIgnoredChildCursor(CXCursor cursor) const;
7029 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
7030
Guy Benyei11169dd2012-12-18 14:30:41 +00007031 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007032 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
7033 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
7034
Guy Benyei11169dd2012-12-18 14:30:41 +00007035 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05007036
7037 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00007038 /// context-sensitive keywords.
7039 bool hasContextSensitiveKeywords() const {
7040 return HasContextSensitiveKeywords;
7041 }
7042
Michael Kruse7520cf02020-03-25 09:26:14 -05007043 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00007044};
Michael Kruse7520cf02020-03-25 09:26:14 -05007045} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00007046
7047void AnnotateTokensWorker::AnnotateTokens() {
7048 // Walk the AST within the region of interest, annotating tokens
7049 // along the way.
7050 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007051}
Guy Benyei11169dd2012-12-18 14:30:41 +00007052
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007053bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7054 if (PostChildrenInfos.empty())
7055 return false;
7056
7057 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7058 if (ChildAction.cursor == cursor &&
7059 ChildAction.action == PostChildrenAction::Ignore) {
7060 return true;
7061 }
7062 }
7063
7064 return false;
7065}
7066
7067const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7068 if (!clang_isExpression(Cursor.kind))
7069 return nullptr;
7070
7071 const Expr *E = getCursorExpr(Cursor);
7072 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7073 const OverloadedOperatorKind Kind = OCE->getOperator();
7074 if (Kind == OO_Call || Kind == OO_Subscript)
7075 return OCE;
7076 }
7077
7078 return nullptr;
7079}
7080
7081AnnotateTokensWorker::PostChildrenActions
7082AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7083 PostChildrenActions actions;
7084
7085 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7086 // visited before the arguments to the operator call. For the Call and
7087 // Subscript operator the range of this DeclRefExpr includes the whole call
7088 // expression, so that all tokens in that range would be mapped to the
7089 // operator function, including the tokens of the arguments. To avoid that,
7090 // ensure to visit this DeclRefExpr as last node.
7091 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7092 const Expr *Callee = OCE->getCallee();
7093 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7094 const Expr *SubExpr = ICE->getSubExpr();
7095 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007096 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007097 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7098
7099 // Visit the DeclRefExpr as last.
7100 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7101 actions.push_back({cxChild, PostChildrenAction::Postpone});
7102
7103 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7104 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7105 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7106 actions.push_back({cxChild, PostChildrenAction::Ignore});
7107 }
7108 }
7109 }
7110
7111 return actions;
7112}
7113
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007114static inline void updateCursorAnnotation(CXCursor &Cursor,
7115 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007116 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007117 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007118 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007119}
7120
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007121/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007122//// between the cursor location and the source range is the same as
7123/// \arg compResult.
7124///
7125/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7126/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007127void AnnotateTokensWorker::annotateAndAdvanceTokens(
7128 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007129 while (MoreTokens()) {
7130 const unsigned I = NextToken();
7131 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007132 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7133 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007134
7135 SourceLocation TokLoc = GetTokenLoc(I);
7136 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007137 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007138 AdvanceToken();
7139 continue;
7140 }
7141 break;
7142 }
7143}
7144
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007145/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007146/// \returns true if it advanced beyond all macro tokens, false otherwise.
7147bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007148 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007149 assert(MoreTokens());
7150 assert(isFunctionMacroToken(NextToken()) &&
7151 "Should be called only for macro arg tokens");
7152
7153 // This works differently than annotateAndAdvanceTokens; because expanded
7154 // macro arguments can have arbitrary translation-unit source order, we do not
7155 // advance the token index one by one until a token fails the range test.
7156 // We only advance once past all of the macro arg tokens if all of them
7157 // pass the range test. If one of them fails we keep the token index pointing
7158 // at the start of the macro arg tokens so that the failing token will be
7159 // annotated by a subsequent annotation try.
7160
7161 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007162
Guy Benyei11169dd2012-12-18 14:30:41 +00007163 unsigned I = NextToken();
7164 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7165 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7166 if (TokLoc.isFileID())
7167 continue; // not macro arg token, it's parens or comma.
7168 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7169 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7170 Cursors[I] = updateC;
7171 } else
7172 atLeastOneCompFail = true;
7173 }
7174
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007175 if (atLeastOneCompFail)
7176 return false;
7177
7178 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7179 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007180}
7181
Michael Kruse7520cf02020-03-25 09:26:14 -05007182enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7183 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007184 SourceRange cursorRange = getRawCursorExtent(cursor);
7185 if (cursorRange.isInvalid())
7186 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007187
7188 if (IsIgnoredChildCursor(cursor))
7189 return CXChildVisit_Continue;
7190
Guy Benyei11169dd2012-12-18 14:30:41 +00007191 if (!HasContextSensitiveKeywords) {
7192 // Objective-C properties can have context-sensitive keywords.
7193 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007194 if (const ObjCPropertyDecl *Property =
7195 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7196 HasContextSensitiveKeywords =
7197 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007198 }
7199 // Objective-C methods can have context-sensitive keywords.
7200 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7201 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007202 if (const ObjCMethodDecl *Method =
7203 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007204 if (Method->getObjCDeclQualifier())
7205 HasContextSensitiveKeywords = true;
7206 else {
David Majnemer59f77922016-06-24 04:05:48 +00007207 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007208 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007209 HasContextSensitiveKeywords = true;
7210 break;
7211 }
7212 }
7213 }
7214 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007215 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007216 // C++ methods can have context-sensitive keywords.
7217 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007218 if (const CXXMethodDecl *Method =
7219 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007220 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7221 HasContextSensitiveKeywords = true;
7222 }
7223 }
7224 // C++ classes can have context-sensitive keywords.
7225 else if (cursor.kind == CXCursor_StructDecl ||
7226 cursor.kind == CXCursor_ClassDecl ||
7227 cursor.kind == CXCursor_ClassTemplate ||
7228 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007229 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007230 if (D->hasAttr<FinalAttr>())
7231 HasContextSensitiveKeywords = true;
7232 }
7233 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007234
7235 // Don't override a property annotation with its getter/setter method.
7236 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7237 parent.kind == CXCursor_ObjCPropertyDecl)
7238 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007239
7240 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007241 // Items in the preprocessing record are kept separate from items in
7242 // declarations, so we keep a separate token index.
7243 unsigned SavedTokIdx = TokIdx;
7244 TokIdx = PreprocessingTokIdx;
7245
7246 // Skip tokens up until we catch up to the beginning of the preprocessing
7247 // entry.
7248 while (MoreTokens()) {
7249 const unsigned I = NextToken();
7250 SourceLocation TokLoc = GetTokenLoc(I);
7251 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7252 case RangeBefore:
7253 AdvanceToken();
7254 continue;
7255 case RangeAfter:
7256 case RangeOverlap:
7257 break;
7258 }
7259 break;
7260 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007261
Guy Benyei11169dd2012-12-18 14:30:41 +00007262 // Look at all of the tokens within this range.
7263 while (MoreTokens()) {
7264 const unsigned I = NextToken();
7265 SourceLocation TokLoc = GetTokenLoc(I);
7266 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7267 case RangeBefore:
7268 llvm_unreachable("Infeasible");
7269 case RangeAfter:
7270 break;
7271 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007272 // For macro expansions, just note where the beginning of the macro
7273 // expansion occurs.
7274 if (cursor.kind == CXCursor_MacroExpansion) {
7275 if (TokLoc == cursorRange.getBegin())
7276 Cursors[I] = cursor;
7277 AdvanceToken();
7278 break;
7279 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007280 // We may have already annotated macro names inside macro definitions.
7281 if (Cursors[I].kind != CXCursor_MacroExpansion)
7282 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007283 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007284 continue;
7285 }
7286 break;
7287 }
7288
7289 // Save the preprocessing token index; restore the non-preprocessing
7290 // token index.
7291 PreprocessingTokIdx = TokIdx;
7292 TokIdx = SavedTokIdx;
7293 return CXChildVisit_Recurse;
7294 }
7295
7296 if (cursorRange.isInvalid())
7297 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007298
7299 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007300 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007301 const enum CXCursorKind K = clang_getCursorKind(parent);
7302 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007303 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7304 // Attributes are annotated out-of-order, skip tokens until we reach it.
7305 clang_isAttribute(cursor.kind))
7306 ? clang_getNullCursor()
7307 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007308
7309 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7310
7311 // Avoid having the cursor of an expression "overwrite" the annotation of the
7312 // variable declaration that it belongs to.
7313 // This can happen for C++ constructor expressions whose range generally
7314 // include the variable declaration, e.g.:
7315 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007316 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007317 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007318 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007319 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007320 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7321 E->getBeginLoc() == D->getLocation() &&
7322 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007323 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007324 AdvanceToken();
7325 }
7326 }
7327 }
7328
7329 // Before recursing into the children keep some state that we are going
7330 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7331 // extra work after the child nodes are visited.
7332 // Note that we don't call VisitChildren here to avoid traversing statements
7333 // code-recursively which can blow the stack.
7334
7335 PostChildrenInfo Info;
7336 Info.Cursor = cursor;
7337 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007338 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007339 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007340 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007341 PostChildrenInfos.push_back(Info);
7342
7343 return CXChildVisit_Recurse;
7344}
7345
7346bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7347 if (PostChildrenInfos.empty())
7348 return false;
7349 const PostChildrenInfo &Info = PostChildrenInfos.back();
7350 if (!clang_equalCursors(Info.Cursor, cursor))
7351 return false;
7352
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007353 HandlePostPonedChildCursors(Info);
7354
Guy Benyei11169dd2012-12-18 14:30:41 +00007355 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7356 const unsigned AfterChildren = NextToken();
7357 SourceRange cursorRange = Info.CursorRange;
7358
7359 // Scan the tokens that are at the end of the cursor, but are not captured
7360 // but the child cursors.
7361 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7362
7363 // Scan the tokens that are at the beginning of the cursor, but are not
7364 // capture by the child cursors.
7365 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7366 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7367 break;
7368
7369 Cursors[I] = cursor;
7370 }
7371
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007372 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7373 // encountered the attribute cursor.
7374 if (clang_isAttribute(cursor.kind))
7375 TokIdx = Info.BeforeReachingCursorIdx;
7376
Guy Benyei11169dd2012-12-18 14:30:41 +00007377 PostChildrenInfos.pop_back();
7378 return false;
7379}
7380
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007381void AnnotateTokensWorker::HandlePostPonedChildCursors(
7382 const PostChildrenInfo &Info) {
7383 for (const auto &ChildAction : Info.ChildActions) {
7384 if (ChildAction.action == PostChildrenAction::Postpone) {
7385 HandlePostPonedChildCursor(ChildAction.cursor,
7386 Info.BeforeChildrenTokenIdx);
7387 }
7388 }
7389}
7390
7391void AnnotateTokensWorker::HandlePostPonedChildCursor(
7392 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007393 unsigned I = StartTokenIndex;
7394
7395 // The bracket tokens of a Call or Subscript operator are mapped to
7396 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7397 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7398 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007399 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7400 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007401 if (clang_Range_isNull(CXRefNameRange))
7402 break; // All ranges handled.
7403
7404 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7405 while (I < NumTokens) {
7406 const SourceLocation TokenLocation = GetTokenLoc(I);
7407 if (!TokenLocation.isValid())
7408 break;
7409
7410 // Adapt the end range, because LocationCompare() reports
7411 // RangeOverlap even for the not-inclusive end location.
7412 const SourceLocation fixedEnd =
7413 RefNameRange.getEnd().getLocWithOffset(-1);
7414 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7415
7416 const RangeComparisonResult ComparisonResult =
7417 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7418
7419 if (ComparisonResult == RangeOverlap) {
7420 Cursors[I++] = Cursor;
7421 } else if (ComparisonResult == RangeBefore) {
7422 ++I; // Not relevant token, check next one.
7423 } else if (ComparisonResult == RangeAfter) {
7424 break; // All tokens updated for current range, check next.
7425 }
7426 }
7427 }
7428}
7429
Guy Benyei11169dd2012-12-18 14:30:41 +00007430static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7431 CXCursor parent,
7432 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007433 return static_cast<AnnotateTokensWorker *>(client_data)
7434 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007435}
7436
7437static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7438 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007439 return static_cast<AnnotateTokensWorker *>(client_data)
7440 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007441}
7442
7443namespace {
7444
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007445/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007446/// and mark tokens that are macro arguments. This info is used by the
7447/// AnnotateTokensWorker.
7448class MarkMacroArgTokensVisitor {
7449 SourceManager &SM;
7450 CXToken *Tokens;
7451 unsigned NumTokens;
7452 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007453
Guy Benyei11169dd2012-12-18 14:30:41 +00007454public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007455 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7456 unsigned numTokens)
7457 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007458
7459 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7460 if (cursor.kind != CXCursor_MacroExpansion)
7461 return CXChildVisit_Continue;
7462
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007463 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007464 if (macroRange.getBegin() == macroRange.getEnd())
7465 return CXChildVisit_Continue; // it's not a function macro.
7466
7467 for (; CurIdx < NumTokens; ++CurIdx) {
7468 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7469 macroRange.getBegin()))
7470 break;
7471 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007472
Guy Benyei11169dd2012-12-18 14:30:41 +00007473 if (CurIdx == NumTokens)
7474 return CXChildVisit_Break;
7475
7476 for (; CurIdx < NumTokens; ++CurIdx) {
7477 SourceLocation tokLoc = getTokenLoc(CurIdx);
7478 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7479 break;
7480
7481 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7482 }
7483
7484 if (CurIdx == NumTokens)
7485 return CXChildVisit_Break;
7486
7487 return CXChildVisit_Continue;
7488 }
7489
7490private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007491 CXToken &getTok(unsigned Idx) {
7492 assert(Idx < NumTokens);
7493 return Tokens[Idx];
7494 }
7495 const CXToken &getTok(unsigned Idx) const {
7496 assert(Idx < NumTokens);
7497 return Tokens[Idx];
7498 }
7499
Guy Benyei11169dd2012-12-18 14:30:41 +00007500 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007501 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007502 }
7503
7504 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7505 // The third field is reserved and currently not used. Use it here
7506 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007507 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007508 }
7509};
7510
7511} // end anonymous namespace
7512
7513static CXChildVisitResult
7514MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7515 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007516 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7517 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007518}
7519
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007520/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007521/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007522static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7523 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007524 if (NextIdx >= NumTokens)
7525 return true;
7526
7527 ++NextIdx;
7528 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007529 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007530}
7531
Guy Benyei11169dd2012-12-18 14:30:41 +00007532static void annotatePreprocessorTokens(CXTranslationUnit TU,
7533 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007534 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007535 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007536 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007537
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007538 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007539 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007540 std::pair<FileID, unsigned> BeginLocInfo =
7541 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7542 std::pair<FileID, unsigned> EndLocInfo =
7543 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007544
7545 if (BeginLocInfo.first != EndLocInfo.first)
7546 return;
7547
7548 StringRef Buffer;
7549 bool Invalid = false;
7550 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7551 if (Buffer.empty() || Invalid)
7552 return;
7553
7554 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007555 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7556 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007557 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007558
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007559 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007560 // Lex tokens in raw mode until we hit the end of the range, to avoid
7561 // entering #includes or expanding macros.
7562 while (true) {
7563 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007564 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7565 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007566 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007567 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007568 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7569
Guy Benyei11169dd2012-12-18 14:30:41 +00007570 reprocess:
7571 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007572 // We have found a preprocessing directive. Annotate the tokens
7573 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007574 //
7575 // FIXME: Some simple tests here could identify macro definitions and
7576 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007577
7578 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007579 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7580 break;
7581
Craig Topper69186e72014-06-08 08:38:04 +00007582 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007583 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007584 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7585 break;
7586
7587 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007588 IdentifierInfo &II =
7589 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007590 SourceLocation MappedTokLoc =
7591 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7592 MI = getMacroInfo(II, MappedTokLoc, TU);
7593 }
7594 }
7595
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007596 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007597 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007598 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7599 finished = true;
7600 break;
7601 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007602 // If we are in a macro definition, check if the token was ever a
7603 // macro name and annotate it if that's the case.
7604 if (MI) {
7605 SourceLocation SaveLoc = Tok.getLocation();
7606 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007607 MacroDefinitionRecord *MacroDef =
7608 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007609 Tok.setLocation(SaveLoc);
7610 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007611 Cursors[NextIdx - 1] =
7612 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007613 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007614 } while (!Tok.isAtStartOfLine());
7615
Michael Kruse7520cf02020-03-25 09:26:14 -05007616 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007617 assert(TokIdx <= LastIdx);
7618 SourceLocation EndLoc =
7619 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7620 CXCursor Cursor =
7621 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7622
7623 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007624 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007625
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007626 if (finished)
7627 break;
7628 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007629 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007630 }
7631}
7632
7633// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007634static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7635 CXToken *Tokens, unsigned NumTokens,
7636 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007637 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007638 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7639 setThreadBackgroundPriority();
7640
7641 // Determine the region of interest, which contains all of the tokens.
7642 SourceRange RegionOfInterest;
7643 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007644 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7645 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7646 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007647
Guy Benyei11169dd2012-12-18 14:30:41 +00007648 // Relex the tokens within the source range to look for preprocessing
7649 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007650 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007651
7652 // If begin location points inside a macro argument, set it to the expansion
7653 // location so we can have the full context when annotating semantically.
7654 {
7655 SourceManager &SM = CXXUnit->getSourceManager();
7656 SourceLocation Loc =
7657 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7658 if (Loc.isMacroID())
7659 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7660 }
7661
Guy Benyei11169dd2012-12-18 14:30:41 +00007662 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7663 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007664 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7665 NumTokens);
7666 CursorVisitor MacroArgMarker(
7667 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7668 /*VisitPreprocessorLast=*/true,
7669 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007670 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7671 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007672
Guy Benyei11169dd2012-12-18 14:30:41 +00007673 // Annotate all of the source locations in the region of interest that map to
7674 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007675 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007676
Guy Benyei11169dd2012-12-18 14:30:41 +00007677 // FIXME: We use a ridiculous stack size here because the data-recursion
7678 // algorithm uses a large stack frame than the non-data recursive version,
7679 // and AnnotationTokensWorker currently transforms the data-recursion
7680 // algorithm back into a traditional recursion by explicitly calling
7681 // VisitChildren(). We will need to remove this explicit recursive call.
7682 W.AnnotateTokens();
7683
7684 // If we ran into any entities that involve context-sensitive keywords,
7685 // take another pass through the tokens to mark them as such.
7686 if (W.hasContextSensitiveKeywords()) {
7687 for (unsigned I = 0; I != NumTokens; ++I) {
7688 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7689 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007690
Guy Benyei11169dd2012-12-18 14:30:41 +00007691 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7692 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007693 if (const ObjCPropertyDecl *Property =
7694 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007695 if (Property->getPropertyAttributesAsWritten() != 0 &&
7696 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007697 .Case("readonly", true)
7698 .Case("assign", true)
7699 .Case("unsafe_unretained", true)
7700 .Case("readwrite", true)
7701 .Case("retain", true)
7702 .Case("copy", true)
7703 .Case("nonatomic", true)
7704 .Case("atomic", true)
7705 .Case("getter", true)
7706 .Case("setter", true)
7707 .Case("strong", true)
7708 .Case("weak", true)
7709 .Case("class", true)
7710 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007711 Tokens[I].int_data[0] = CXToken_Keyword;
7712 }
7713 continue;
7714 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007715
Guy Benyei11169dd2012-12-18 14:30:41 +00007716 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7717 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7718 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7719 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007720 .Case("in", true)
7721 .Case("out", true)
7722 .Case("inout", true)
7723 .Case("oneway", true)
7724 .Case("bycopy", true)
7725 .Case("byref", true)
7726 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007727 Tokens[I].int_data[0] = CXToken_Keyword;
7728 continue;
7729 }
7730
7731 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7732 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7733 Tokens[I].int_data[0] = CXToken_Keyword;
7734 continue;
7735 }
7736 }
7737 }
7738}
7739
Michael Kruse7520cf02020-03-25 09:26:14 -05007740void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7741 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007742 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007743 LOG_BAD_TU(TU);
7744 return;
7745 }
7746 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007747 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007748 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007749 }
7750
7751 LOG_FUNC_SECTION {
7752 *Log << TU << ' ';
7753 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007754 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007755 *Log << clang_getRange(bloc, eloc);
7756 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007757
7758 // Any token we don't specifically annotate will have a NULL cursor.
7759 CXCursor C = clang_getNullCursor();
7760 for (unsigned I = 0; I != NumTokens; ++I)
7761 Cursors[I] = C;
7762
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007763 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007764 if (!CXXUnit)
7765 return;
7766
7767 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007768
7769 auto AnnotateTokensImpl = [=]() {
7770 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7771 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007772 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007773 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007774 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7775 }
7776}
7777
Guy Benyei11169dd2012-12-18 14:30:41 +00007778//===----------------------------------------------------------------------===//
7779// Operations for querying linkage of a cursor.
7780//===----------------------------------------------------------------------===//
7781
Guy Benyei11169dd2012-12-18 14:30:41 +00007782CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7783 if (!clang_isDeclaration(cursor.kind))
7784 return CXLinkage_Invalid;
7785
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007786 const Decl *D = cxcursor::getCursorDecl(cursor);
7787 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007788 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007789 case NoLinkage:
7790 case VisibleNoLinkage:
7791 return CXLinkage_NoLinkage;
7792 case ModuleInternalLinkage:
7793 case InternalLinkage:
7794 return CXLinkage_Internal;
7795 case UniqueExternalLinkage:
7796 return CXLinkage_UniqueExternal;
7797 case ModuleLinkage:
7798 case ExternalLinkage:
7799 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007800 };
7801
7802 return CXLinkage_Invalid;
7803}
Guy Benyei11169dd2012-12-18 14:30:41 +00007804
7805//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007806// Operations for querying visibility of a cursor.
7807//===----------------------------------------------------------------------===//
7808
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007809CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7810 if (!clang_isDeclaration(cursor.kind))
7811 return CXVisibility_Invalid;
7812
7813 const Decl *D = cxcursor::getCursorDecl(cursor);
7814 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7815 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007816 case HiddenVisibility:
7817 return CXVisibility_Hidden;
7818 case ProtectedVisibility:
7819 return CXVisibility_Protected;
7820 case DefaultVisibility:
7821 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007822 };
7823
7824 return CXVisibility_Invalid;
7825}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007826
7827//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007828// Operations for querying language of a cursor.
7829//===----------------------------------------------------------------------===//
7830
7831static CXLanguageKind getDeclLanguage(const Decl *D) {
7832 if (!D)
7833 return CXLanguage_C;
7834
7835 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007836 default:
7837 break;
7838 case Decl::ImplicitParam:
7839 case Decl::ObjCAtDefsField:
7840 case Decl::ObjCCategory:
7841 case Decl::ObjCCategoryImpl:
7842 case Decl::ObjCCompatibleAlias:
7843 case Decl::ObjCImplementation:
7844 case Decl::ObjCInterface:
7845 case Decl::ObjCIvar:
7846 case Decl::ObjCMethod:
7847 case Decl::ObjCProperty:
7848 case Decl::ObjCPropertyImpl:
7849 case Decl::ObjCProtocol:
7850 case Decl::ObjCTypeParam:
7851 return CXLanguage_ObjC;
7852 case Decl::CXXConstructor:
7853 case Decl::CXXConversion:
7854 case Decl::CXXDestructor:
7855 case Decl::CXXMethod:
7856 case Decl::CXXRecord:
7857 case Decl::ClassTemplate:
7858 case Decl::ClassTemplatePartialSpecialization:
7859 case Decl::ClassTemplateSpecialization:
7860 case Decl::Friend:
7861 case Decl::FriendTemplate:
7862 case Decl::FunctionTemplate:
7863 case Decl::LinkageSpec:
7864 case Decl::Namespace:
7865 case Decl::NamespaceAlias:
7866 case Decl::NonTypeTemplateParm:
7867 case Decl::StaticAssert:
7868 case Decl::TemplateTemplateParm:
7869 case Decl::TemplateTypeParm:
7870 case Decl::UnresolvedUsingTypename:
7871 case Decl::UnresolvedUsingValue:
7872 case Decl::Using:
7873 case Decl::UsingDirective:
7874 case Decl::UsingShadow:
7875 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007876 }
7877
7878 return CXLanguage_C;
7879}
7880
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007881static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7882 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007883 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007884
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007885 switch (D->getAvailability()) {
7886 case AR_Available:
7887 case AR_NotYetIntroduced:
7888 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007889 return getCursorAvailabilityForDecl(
7890 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007891 return CXAvailability_Available;
7892
7893 case AR_Deprecated:
7894 return CXAvailability_Deprecated;
7895
7896 case AR_Unavailable:
7897 return CXAvailability_NotAvailable;
7898 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007899
7900 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007901}
7902
Guy Benyei11169dd2012-12-18 14:30:41 +00007903enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7904 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007905 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7906 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007907
7908 return CXAvailability_Available;
7909}
7910
7911static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007912 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007913 if (In.empty())
7914 return Out;
7915
7916 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007917
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007918 Optional<unsigned> Minor = In.getMinor();
7919 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007920 Out.Minor = *Minor;
7921 else
7922 return Out;
7923
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007924 Optional<unsigned> Subminor = In.getSubminor();
7925 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007926 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007927
Guy Benyei11169dd2012-12-18 14:30:41 +00007928 return Out;
7929}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007930
Alex Lorenz1345ea22017-06-12 19:06:30 +00007931static void getCursorPlatformAvailabilityForDecl(
7932 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7933 int *always_unavailable, CXString *unavailable_message,
7934 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007935 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007936 for (auto A : D->attrs()) {
7937 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007938 HadAvailAttr = true;
7939 if (always_deprecated)
7940 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007941 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007942 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007943 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007944 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007945 continue;
7946 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007947
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007948 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007949 HadAvailAttr = true;
7950 if (always_unavailable)
7951 *always_unavailable = 1;
7952 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007953 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007954 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7955 }
7956 continue;
7957 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007958
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007959 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007960 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007961 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007962 }
7963 }
7964
7965 if (!HadAvailAttr)
7966 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7967 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007968 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7969 deprecated_message, always_unavailable, unavailable_message,
7970 AvailabilityAttrs);
7971
7972 if (AvailabilityAttrs.empty())
7973 return;
7974
Michael Kruse7520cf02020-03-25 09:26:14 -05007975 llvm::sort(
7976 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7977 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7978 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007979 ASTContext &Ctx = D->getASTContext();
7980 auto It = std::unique(
7981 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7982 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7983 if (LHS->getPlatform() != RHS->getPlatform())
7984 return false;
7985
7986 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7987 LHS->getDeprecated() == RHS->getDeprecated() &&
7988 LHS->getObsoleted() == RHS->getObsoleted() &&
7989 LHS->getMessage() == RHS->getMessage() &&
7990 LHS->getReplacement() == RHS->getReplacement())
7991 return true;
7992
7993 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
7994 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
7995 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
7996 return false;
7997
7998 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
7999 LHS->setIntroduced(Ctx, RHS->getIntroduced());
8000
8001 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
8002 LHS->setDeprecated(Ctx, RHS->getDeprecated());
8003 if (LHS->getMessage().empty())
8004 LHS->setMessage(Ctx, RHS->getMessage());
8005 if (LHS->getReplacement().empty())
8006 LHS->setReplacement(Ctx, RHS->getReplacement());
8007 }
8008
8009 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
8010 LHS->setObsoleted(Ctx, RHS->getObsoleted());
8011 if (LHS->getMessage().empty())
8012 LHS->setMessage(Ctx, RHS->getMessage());
8013 if (LHS->getReplacement().empty())
8014 LHS->setReplacement(Ctx, RHS->getReplacement());
8015 }
8016
8017 return true;
8018 });
8019 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008020}
8021
Alex Lorenz1345ea22017-06-12 19:06:30 +00008022int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00008023 CXString *deprecated_message,
8024 int *always_unavailable,
8025 CXString *unavailable_message,
8026 CXPlatformAvailability *availability,
8027 int availability_size) {
8028 if (always_deprecated)
8029 *always_deprecated = 0;
8030 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008031 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00008032 if (always_unavailable)
8033 *always_unavailable = 0;
8034 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008035 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008036
Guy Benyei11169dd2012-12-18 14:30:41 +00008037 if (!clang_isDeclaration(cursor.kind))
8038 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008039
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008040 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00008041 if (!D)
8042 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008043
Alex Lorenz1345ea22017-06-12 19:06:30 +00008044 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
8045 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8046 always_unavailable, unavailable_message,
8047 AvailabilityAttrs);
8048 for (const auto &Avail :
8049 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8050 .take_front(availability_size))) {
8051 availability[Avail.index()].Platform =
8052 cxstring::createDup(Avail.value()->getPlatform()->getName());
8053 availability[Avail.index()].Introduced =
8054 convertVersion(Avail.value()->getIntroduced());
8055 availability[Avail.index()].Deprecated =
8056 convertVersion(Avail.value()->getDeprecated());
8057 availability[Avail.index()].Obsoleted =
8058 convertVersion(Avail.value()->getObsoleted());
8059 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8060 availability[Avail.index()].Message =
8061 cxstring::createDup(Avail.value()->getMessage());
8062 }
8063
8064 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008065}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008066
Guy Benyei11169dd2012-12-18 14:30:41 +00008067void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8068 clang_disposeString(availability->Platform);
8069 clang_disposeString(availability->Message);
8070}
8071
8072CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8073 if (clang_isDeclaration(cursor.kind))
8074 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8075
8076 return CXLanguage_Invalid;
8077}
8078
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008079CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8080 const Decl *D = cxcursor::getCursorDecl(cursor);
8081 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8082 switch (VD->getTLSKind()) {
8083 case VarDecl::TLS_None:
8084 return CXTLS_None;
8085 case VarDecl::TLS_Dynamic:
8086 return CXTLS_Dynamic;
8087 case VarDecl::TLS_Static:
8088 return CXTLS_Static;
8089 }
8090 }
8091
8092 return CXTLS_None;
8093}
8094
Michael Kruse7520cf02020-03-25 09:26:14 -05008095/// If the given cursor is the "templated" declaration
8096/// describing a class or function template, return the class or
8097/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008098static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008099 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008100 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008101
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008102 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008103 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8104 return FunTmpl;
8105
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008106 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008107 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8108 return ClassTmpl;
8109
8110 return D;
8111}
8112
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008113enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8114 StorageClass sc = SC_None;
8115 const Decl *D = getCursorDecl(C);
8116 if (D) {
8117 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8118 sc = FD->getStorageClass();
8119 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8120 sc = VD->getStorageClass();
8121 } else {
8122 return CX_SC_Invalid;
8123 }
8124 } else {
8125 return CX_SC_Invalid;
8126 }
8127 switch (sc) {
8128 case SC_None:
8129 return CX_SC_None;
8130 case SC_Extern:
8131 return CX_SC_Extern;
8132 case SC_Static:
8133 return CX_SC_Static;
8134 case SC_PrivateExtern:
8135 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008136 case SC_Auto:
8137 return CX_SC_Auto;
8138 case SC_Register:
8139 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008140 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008141 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008142}
8143
Guy Benyei11169dd2012-12-18 14:30:41 +00008144CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8145 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008146 if (const Decl *D = getCursorDecl(cursor)) {
8147 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008148 if (!DC)
8149 return clang_getNullCursor();
8150
Michael Kruse7520cf02020-03-25 09:26:14 -05008151 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008152 getCursorTU(cursor));
8153 }
8154 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008155
Guy Benyei11169dd2012-12-18 14:30:41 +00008156 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008157 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008158 return MakeCXCursor(D, getCursorTU(cursor));
8159 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008160
Guy Benyei11169dd2012-12-18 14:30:41 +00008161 return clang_getNullCursor();
8162}
8163
8164CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8165 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008166 if (const Decl *D = getCursorDecl(cursor)) {
8167 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008168 if (!DC)
8169 return clang_getNullCursor();
8170
Michael Kruse7520cf02020-03-25 09:26:14 -05008171 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008172 getCursorTU(cursor));
8173 }
8174 }
8175
Michael Kruse7520cf02020-03-25 09:26:14 -05008176 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008177 // statement or expression, so we return nothing.
8178 return clang_getNullCursor();
8179}
8180
8181CXFile clang_getIncludedFile(CXCursor cursor) {
8182 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008183 return nullptr;
8184
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008185 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008186 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008187}
8188
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008189unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8190 if (C.kind != CXCursor_ObjCPropertyDecl)
8191 return CXObjCPropertyAttr_noattr;
8192
8193 unsigned Result = CXObjCPropertyAttr_noattr;
8194 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008195 ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008196
Michael Kruse7520cf02020-03-25 09:26:14 -05008197#define SET_CXOBJCPROP_ATTR(A) \
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008198 if (Attr & ObjCPropertyAttribute::kind_##A) \
Michael Kruse7520cf02020-03-25 09:26:14 -05008199 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008200 SET_CXOBJCPROP_ATTR(readonly);
8201 SET_CXOBJCPROP_ATTR(getter);
8202 SET_CXOBJCPROP_ATTR(assign);
8203 SET_CXOBJCPROP_ATTR(readwrite);
8204 SET_CXOBJCPROP_ATTR(retain);
8205 SET_CXOBJCPROP_ATTR(copy);
8206 SET_CXOBJCPROP_ATTR(nonatomic);
8207 SET_CXOBJCPROP_ATTR(setter);
8208 SET_CXOBJCPROP_ATTR(atomic);
8209 SET_CXOBJCPROP_ATTR(weak);
8210 SET_CXOBJCPROP_ATTR(strong);
8211 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008212 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008213#undef SET_CXOBJCPROP_ATTR
8214
8215 return Result;
8216}
8217
Michael Wu6e88f532018-08-03 05:38:29 +00008218CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8219 if (C.kind != CXCursor_ObjCPropertyDecl)
8220 return cxstring::createNull();
8221
8222 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8223 Selector sel = PD->getGetterName();
8224 if (sel.isNull())
8225 return cxstring::createNull();
8226
8227 return cxstring::createDup(sel.getAsString());
8228}
8229
8230CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8231 if (C.kind != CXCursor_ObjCPropertyDecl)
8232 return cxstring::createNull();
8233
8234 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8235 Selector sel = PD->getSetterName();
8236 if (sel.isNull())
8237 return cxstring::createNull();
8238
8239 return cxstring::createDup(sel.getAsString());
8240}
8241
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008242unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8243 if (!clang_isDeclaration(C.kind))
8244 return CXObjCDeclQualifier_None;
8245
8246 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8247 const Decl *D = getCursorDecl(C);
8248 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8249 QT = MD->getObjCDeclQualifier();
8250 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8251 QT = PD->getObjCDeclQualifier();
8252 if (QT == Decl::OBJC_TQ_None)
8253 return CXObjCDeclQualifier_None;
8254
8255 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008256 if (QT & Decl::OBJC_TQ_In)
8257 Result |= CXObjCDeclQualifier_In;
8258 if (QT & Decl::OBJC_TQ_Inout)
8259 Result |= CXObjCDeclQualifier_Inout;
8260 if (QT & Decl::OBJC_TQ_Out)
8261 Result |= CXObjCDeclQualifier_Out;
8262 if (QT & Decl::OBJC_TQ_Bycopy)
8263 Result |= CXObjCDeclQualifier_Bycopy;
8264 if (QT & Decl::OBJC_TQ_Byref)
8265 Result |= CXObjCDeclQualifier_Byref;
8266 if (QT & Decl::OBJC_TQ_Oneway)
8267 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008268
8269 return Result;
8270}
8271
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008272unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8273 if (!clang_isDeclaration(C.kind))
8274 return 0;
8275
8276 const Decl *D = getCursorDecl(C);
8277 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8278 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8279 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8280 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8281
8282 return 0;
8283}
8284
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008285unsigned clang_Cursor_isVariadic(CXCursor C) {
8286 if (!clang_isDeclaration(C.kind))
8287 return 0;
8288
8289 const Decl *D = getCursorDecl(C);
8290 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8291 return FD->isVariadic();
8292 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8293 return MD->isVariadic();
8294
8295 return 0;
8296}
8297
Michael Kruse7520cf02020-03-25 09:26:14 -05008298unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8299 CXString *definedIn,
8300 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008301 if (!clang_isDeclaration(C.kind))
8302 return 0;
8303
8304 const Decl *D = getCursorDecl(C);
8305
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008306 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008307 if (language)
8308 *language = cxstring::createDup(attr->getLanguage());
8309 if (definedIn)
8310 *definedIn = cxstring::createDup(attr->getDefinedIn());
8311 if (isGenerated)
8312 *isGenerated = attr->getGeneratedDeclaration();
8313 return 1;
8314 }
8315 return 0;
8316}
8317
Guy Benyei11169dd2012-12-18 14:30:41 +00008318CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8319 if (!clang_isDeclaration(C.kind))
8320 return clang_getNullRange();
8321
8322 const Decl *D = getCursorDecl(C);
8323 ASTContext &Context = getCursorContext(C);
8324 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8325 if (!RC)
8326 return clang_getNullRange();
8327
8328 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8329}
8330
8331CXString clang_Cursor_getRawCommentText(CXCursor C) {
8332 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008333 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008334
8335 const Decl *D = getCursorDecl(C);
8336 ASTContext &Context = getCursorContext(C);
8337 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008338 StringRef RawText =
8339 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008340
8341 // Don't duplicate the string because RawText points directly into source
8342 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008343 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008344}
8345
8346CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8347 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008348 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008349
8350 const Decl *D = getCursorDecl(C);
8351 const ASTContext &Context = getCursorContext(C);
8352 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8353
8354 if (RC) {
8355 StringRef BriefText = RC->getBriefText(Context);
8356
8357 // Don't duplicate the string because RawComment ensures that this memory
8358 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008359 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008360 }
8361
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008362 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008363}
8364
Guy Benyei11169dd2012-12-18 14:30:41 +00008365CXModule clang_Cursor_getModule(CXCursor C) {
8366 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008367 if (const ImportDecl *ImportD =
8368 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008369 return ImportD->getImportedModule();
8370 }
8371
Craig Topper69186e72014-06-08 08:38:04 +00008372 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008373}
8374
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008375CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8376 if (isNotUsableTU(TU)) {
8377 LOG_BAD_TU(TU);
8378 return nullptr;
8379 }
8380 if (!File)
8381 return nullptr;
8382 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008383
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008384 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8385 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8386 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008387
Richard Smithfeb54b62014-10-23 02:01:19 +00008388 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008389}
8390
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008391CXFile clang_Module_getASTFile(CXModule CXMod) {
8392 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008393 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008394 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008395 return const_cast<FileEntry *>(Mod->getASTFile());
8396}
8397
Guy Benyei11169dd2012-12-18 14:30:41 +00008398CXModule clang_Module_getParent(CXModule CXMod) {
8399 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008400 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008401 Module *Mod = static_cast<Module *>(CXMod);
Guy Benyei11169dd2012-12-18 14:30:41 +00008402 return Mod->Parent;
8403}
8404
8405CXString clang_Module_getName(CXModule CXMod) {
8406 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008407 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008408 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008409 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008410}
8411
8412CXString clang_Module_getFullName(CXModule CXMod) {
8413 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008414 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008415 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008416 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008417}
8418
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008419int clang_Module_isSystem(CXModule CXMod) {
8420 if (!CXMod)
8421 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008422 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008423 return Mod->IsSystem;
8424}
8425
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008426unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8427 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008428 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008429 LOG_BAD_TU(TU);
8430 return 0;
8431 }
8432 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008433 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008434 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008435 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8436 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8437 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008438}
8439
Michael Kruse7520cf02020-03-25 09:26:14 -05008440CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8441 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008442 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008443 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008444 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008445 }
8446 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008447 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008448 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008449 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008450
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008451 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8452 if (Index < TopHeaders.size())
8453 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008454
Craig Topper69186e72014-06-08 08:38:04 +00008455 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008456}
8457
Guy Benyei11169dd2012-12-18 14:30:41 +00008458//===----------------------------------------------------------------------===//
8459// C++ AST instrospection.
8460//===----------------------------------------------------------------------===//
8461
Jonathan Coe29565352016-04-27 12:48:25 +00008462unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8463 if (!clang_isDeclaration(C.kind))
8464 return 0;
8465
8466 const Decl *D = cxcursor::getCursorDecl(C);
8467 const CXXConstructorDecl *Constructor =
8468 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8469 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8470}
8471
8472unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8473 if (!clang_isDeclaration(C.kind))
8474 return 0;
8475
8476 const Decl *D = cxcursor::getCursorDecl(C);
8477 const CXXConstructorDecl *Constructor =
8478 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8479 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8480}
8481
8482unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8483 if (!clang_isDeclaration(C.kind))
8484 return 0;
8485
8486 const Decl *D = cxcursor::getCursorDecl(C);
8487 const CXXConstructorDecl *Constructor =
8488 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8489 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8490}
8491
8492unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8493 if (!clang_isDeclaration(C.kind))
8494 return 0;
8495
8496 const Decl *D = cxcursor::getCursorDecl(C);
8497 const CXXConstructorDecl *Constructor =
8498 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8499 // Passing 'false' excludes constructors marked 'explicit'.
8500 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8501}
8502
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008503unsigned clang_CXXField_isMutable(CXCursor C) {
8504 if (!clang_isDeclaration(C.kind))
8505 return 0;
8506
8507 if (const auto D = cxcursor::getCursorDecl(C))
8508 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8509 return FD->isMutable() ? 1 : 0;
8510 return 0;
8511}
8512
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008513unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8514 if (!clang_isDeclaration(C.kind))
8515 return 0;
8516
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008517 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008518 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008519 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008520 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8521}
8522
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008523unsigned clang_CXXMethod_isConst(CXCursor C) {
8524 if (!clang_isDeclaration(C.kind))
8525 return 0;
8526
8527 const Decl *D = cxcursor::getCursorDecl(C);
8528 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008529 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008530 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008531}
8532
Jonathan Coe29565352016-04-27 12:48:25 +00008533unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8534 if (!clang_isDeclaration(C.kind))
8535 return 0;
8536
8537 const Decl *D = cxcursor::getCursorDecl(C);
8538 const CXXMethodDecl *Method =
8539 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8540 return (Method && Method->isDefaulted()) ? 1 : 0;
8541}
8542
Guy Benyei11169dd2012-12-18 14:30:41 +00008543unsigned clang_CXXMethod_isStatic(CXCursor C) {
8544 if (!clang_isDeclaration(C.kind))
8545 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008546
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008547 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008548 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008549 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008550 return (Method && Method->isStatic()) ? 1 : 0;
8551}
8552
8553unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8554 if (!clang_isDeclaration(C.kind))
8555 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008556
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008557 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008558 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008559 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008560 return (Method && Method->isVirtual()) ? 1 : 0;
8561}
Guy Benyei11169dd2012-12-18 14:30:41 +00008562
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008563unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8564 if (!clang_isDeclaration(C.kind))
8565 return 0;
8566
8567 const auto *D = cxcursor::getCursorDecl(C);
8568 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8569 if (RD)
8570 RD = RD->getDefinition();
8571 return (RD && RD->isAbstract()) ? 1 : 0;
8572}
8573
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008574unsigned clang_EnumDecl_isScoped(CXCursor C) {
8575 if (!clang_isDeclaration(C.kind))
8576 return 0;
8577
8578 const Decl *D = cxcursor::getCursorDecl(C);
8579 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8580 return (Enum && Enum->isScoped()) ? 1 : 0;
8581}
8582
Guy Benyei11169dd2012-12-18 14:30:41 +00008583//===----------------------------------------------------------------------===//
8584// Attribute introspection.
8585//===----------------------------------------------------------------------===//
8586
Guy Benyei11169dd2012-12-18 14:30:41 +00008587CXType clang_getIBOutletCollectionType(CXCursor C) {
8588 if (C.kind != CXCursor_IBOutletCollectionAttr)
8589 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008590
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008591 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008592 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8593
8594 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008595}
Guy Benyei11169dd2012-12-18 14:30:41 +00008596
8597//===----------------------------------------------------------------------===//
8598// Inspecting memory usage.
8599//===----------------------------------------------------------------------===//
8600
8601typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8602
8603static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008604 enum CXTUResourceUsageKind k,
8605 unsigned long amount) {
8606 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008607 entries.push_back(entry);
8608}
8609
Guy Benyei11169dd2012-12-18 14:30:41 +00008610const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8611 const char *str = "";
8612 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008613 case CXTUResourceUsage_AST:
8614 str = "ASTContext: expressions, declarations, and types";
8615 break;
8616 case CXTUResourceUsage_Identifiers:
8617 str = "ASTContext: identifiers";
8618 break;
8619 case CXTUResourceUsage_Selectors:
8620 str = "ASTContext: selectors";
8621 break;
8622 case CXTUResourceUsage_GlobalCompletionResults:
8623 str = "Code completion: cached global results";
8624 break;
8625 case CXTUResourceUsage_SourceManagerContentCache:
8626 str = "SourceManager: content cache allocator";
8627 break;
8628 case CXTUResourceUsage_AST_SideTables:
8629 str = "ASTContext: side tables";
8630 break;
8631 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8632 str = "SourceManager: malloc'ed memory buffers";
8633 break;
8634 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8635 str = "SourceManager: mmap'ed memory buffers";
8636 break;
8637 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8638 str = "ExternalASTSource: malloc'ed memory buffers";
8639 break;
8640 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8641 str = "ExternalASTSource: mmap'ed memory buffers";
8642 break;
8643 case CXTUResourceUsage_Preprocessor:
8644 str = "Preprocessor: malloc'ed memory";
8645 break;
8646 case CXTUResourceUsage_PreprocessingRecord:
8647 str = "Preprocessor: PreprocessingRecord";
8648 break;
8649 case CXTUResourceUsage_SourceManager_DataStructures:
8650 str = "SourceManager: data structures and tables";
8651 break;
8652 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8653 str = "Preprocessor: header search tables";
8654 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008655 }
8656 return str;
8657}
8658
8659CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008660 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008661 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008662 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008663 return usage;
8664 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008665
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008666 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008667 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008668 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008669
Guy Benyei11169dd2012-12-18 14:30:41 +00008670 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008671 createCXTUResourceUsageEntry(
8672 *entries, CXTUResourceUsage_AST,
8673 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008674
8675 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008676 createCXTUResourceUsageEntry(
8677 *entries, CXTUResourceUsage_Identifiers,
8678 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008679
8680 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008681 createCXTUResourceUsageEntry(
8682 *entries, CXTUResourceUsage_Selectors,
8683 (unsigned long)astContext.Selectors.getTotalMemory());
8684
Guy Benyei11169dd2012-12-18 14:30:41 +00008685 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008686 createCXTUResourceUsageEntry(
8687 *entries, CXTUResourceUsage_AST_SideTables,
8688 (unsigned long)astContext.getSideTableAllocatedMemory());
8689
Guy Benyei11169dd2012-12-18 14:30:41 +00008690 // How much memory is used for caching global code completion results?
8691 unsigned long completionBytes = 0;
8692 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008693 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008694 completionBytes = completionAllocator->getTotalMemory();
8695 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008696 createCXTUResourceUsageEntry(
8697 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8698
Guy Benyei11169dd2012-12-18 14:30:41 +00008699 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008700 createCXTUResourceUsageEntry(
8701 *entries, CXTUResourceUsage_SourceManagerContentCache,
8702 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8703
Guy Benyei11169dd2012-12-18 14:30:41 +00008704 // How much memory is being used by the MemoryBuffer's in SourceManager?
8705 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008706 astUnit->getSourceManager().getMemoryBufferSizes();
8707
Guy Benyei11169dd2012-12-18 14:30:41 +00008708 createCXTUResourceUsageEntry(*entries,
8709 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008710 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008711 createCXTUResourceUsageEntry(*entries,
8712 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008713 (unsigned long)srcBufs.mmap_bytes);
8714 createCXTUResourceUsageEntry(
8715 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8716 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8717
Guy Benyei11169dd2012-12-18 14:30:41 +00008718 // How much memory is being used by the ExternalASTSource?
8719 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8720 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008721 esrc->getMemoryBufferSizes();
8722
8723 createCXTUResourceUsageEntry(
8724 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8725 (unsigned long)sizes.malloc_bytes);
8726 createCXTUResourceUsageEntry(
8727 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8728 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008729 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008730
Guy Benyei11169dd2012-12-18 14:30:41 +00008731 // How much memory is being used by the Preprocessor?
8732 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008733 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008734 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008735
Guy Benyei11169dd2012-12-18 14:30:41 +00008736 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8737 createCXTUResourceUsageEntry(*entries,
8738 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008739 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008740 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008741
Guy Benyei11169dd2012-12-18 14:30:41 +00008742 createCXTUResourceUsageEntry(*entries,
8743 CXTUResourceUsage_Preprocessor_HeaderSearch,
8744 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008745
Michael Kruse7520cf02020-03-25 09:26:14 -05008746 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8747 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008748 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008749 return usage;
8750}
8751
8752void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8753 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008754 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008755}
8756
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008757CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8758 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008759 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008760 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008761
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008762 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008763 LOG_BAD_TU(TU);
8764 return skipped;
8765 }
8766
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008767 if (!file)
8768 return skipped;
8769
8770 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008771 PreprocessingRecord *ppRec =
8772 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008773 if (!ppRec)
8774 return skipped;
8775
8776 ASTContext &Ctx = astUnit->getASTContext();
8777 SourceManager &sm = Ctx.getSourceManager();
8778 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8779 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008780 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008781
8782 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8783 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008784 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8785 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008786 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008787 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8788 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008789 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008790 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8791 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008792 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008793 }
8794
8795 skipped->count = wantedRanges.size();
8796 skipped->ranges = new CXSourceRange[skipped->count];
8797 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8798 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8799
8800 return skipped;
8801}
8802
Cameron Desrochersd8091282016-08-18 15:43:55 +00008803CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8804 CXSourceRangeList *skipped = new CXSourceRangeList;
8805 skipped->count = 0;
8806 skipped->ranges = nullptr;
8807
8808 if (isNotUsableTU(TU)) {
8809 LOG_BAD_TU(TU);
8810 return skipped;
8811 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008812
Cameron Desrochersd8091282016-08-18 15:43:55 +00008813 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008814 PreprocessingRecord *ppRec =
8815 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008816 if (!ppRec)
8817 return skipped;
8818
8819 ASTContext &Ctx = astUnit->getASTContext();
8820
8821 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8822
8823 skipped->count = SkippedRanges.size();
8824 skipped->ranges = new CXSourceRange[skipped->count];
8825 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8826 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8827
8828 return skipped;
8829}
8830
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008831void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8832 if (ranges) {
8833 delete[] ranges->ranges;
8834 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008835 }
8836}
8837
Guy Benyei11169dd2012-12-18 14:30:41 +00008838void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8839 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8840 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008841 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008842 clang_getTUResourceUsageName(Usage.entries[I].kind),
8843 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008844
Guy Benyei11169dd2012-12-18 14:30:41 +00008845 clang_disposeCXTUResourceUsage(Usage);
8846}
8847
8848//===----------------------------------------------------------------------===//
8849// Misc. utility functions.
8850//===----------------------------------------------------------------------===//
8851
Richard Smith0a7b2972018-07-03 21:34:13 +00008852/// Default to using our desired 8 MB stack size on "safety" threads.
8853static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008854
8855namespace clang {
8856
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008857bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008858 unsigned Size) {
8859 if (!Size)
8860 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008861 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008862 return CRC.RunSafelyOnThread(Fn, Size);
8863 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008864}
8865
Michael Kruse7520cf02020-03-25 09:26:14 -05008866unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008867
Michael Kruse7520cf02020-03-25 09:26:14 -05008868void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008869
Michael Kruse7520cf02020-03-25 09:26:14 -05008870} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008871
8872void clang::setThreadBackgroundPriority() {
8873 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8874 return;
8875
Nico Weber18cfd9f2019-04-21 19:18:41 +00008876#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008877 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008878#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008879}
8880
8881void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8882 if (!Unit)
8883 return;
8884
Michael Kruse7520cf02020-03-25 09:26:14 -05008885 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8886 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008887 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008888 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008889 CXString Msg =
8890 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008891 fprintf(stderr, "%s\n", clang_getCString(Msg));
8892 clang_disposeString(Msg);
8893 }
Nico Weber1865df42018-04-27 19:11:14 +00008894#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008895 // On Windows, force a flush, since there may be multiple copies of
8896 // stderr and stdout in the file system, all with different buffers
8897 // but writing to the same device.
8898 fflush(stderr);
8899#endif
8900}
8901
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008902MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8903 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008904 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008905 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008906 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008907 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008908 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008909
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008910 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008911 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008912 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008913 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008914 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8915 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008916 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8917 return Def.getMacroInfo();
8918 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008919 }
8920
Craig Topper69186e72014-06-08 08:38:04 +00008921 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008922}
8923
Richard Smith66a81862015-05-04 02:25:31 +00008924const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008925 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008926 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008927 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008928 const IdentifierInfo *II = MacroDef->getName();
8929 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008930 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008931
8932 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8933}
8934
Richard Smith66a81862015-05-04 02:25:31 +00008935MacroDefinitionRecord *
8936cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8937 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008938 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008939 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008940 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008941 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008942
8943 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008944 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008945 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8946 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008947 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008948
8949 // Check that the token is inside the definition and not its argument list.
8950 SourceManager &SM = Unit->getSourceManager();
8951 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008952 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008953 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00008954 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008955
8956 Preprocessor &PP = Unit->getPreprocessor();
8957 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
8958 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00008959 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008960
Alp Toker2d57cea2014-05-17 04:53:25 +00008961 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008962 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008963 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008964
8965 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00008966 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00008967 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008968
Richard Smith20e883e2015-04-29 23:20:19 +00008969 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00008970 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00008971 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008972
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008973 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008974}
8975
Richard Smith66a81862015-05-04 02:25:31 +00008976MacroDefinitionRecord *
8977cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
8978 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008979 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008980 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008981
8982 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008983 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008984 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008985 Preprocessor &PP = Unit->getPreprocessor();
8986 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00008987 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008988 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
8989 Token Tok;
8990 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00008991 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008992
8993 return checkForMacroInMacroDefinition(MI, Tok, TU);
8994}
8995
Guy Benyei11169dd2012-12-18 14:30:41 +00008996CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008997 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00008998}
8999
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009000Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
9001 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00009002 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009003 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00009004 if (Unit->isMainFileAST())
9005 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009006 return *this;
9007 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00009008 } else {
9009 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009010 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009011 return *this;
9012}
9013
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00009014Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
9015 *this << FE->getName();
9016 return *this;
9017}
9018
9019Logger &cxindex::Logger::operator<<(CXCursor cursor) {
9020 CXString cursorName = clang_getCursorDisplayName(cursor);
9021 *this << cursorName << "@" << clang_getCursorLocation(cursor);
9022 clang_disposeString(cursorName);
9023 return *this;
9024}
9025
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009026Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
9027 CXFile File;
9028 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00009029 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009030 CXString FileName = clang_getFileName(File);
9031 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
9032 clang_disposeString(FileName);
9033 return *this;
9034}
9035
9036Logger &cxindex::Logger::operator<<(CXSourceRange range) {
9037 CXSourceLocation BLoc = clang_getRangeStart(range);
9038 CXSourceLocation ELoc = clang_getRangeEnd(range);
9039
9040 CXFile BFile;
9041 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009042 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009043
9044 CXFile EFile;
9045 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009046 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009047
9048 CXString BFileName = clang_getFileName(BFile);
9049 if (BFile == EFile) {
9050 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05009051 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009052 } else {
9053 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009054 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9055 BColumn)
9056 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9057 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009058 clang_disposeString(EFileName);
9059 }
9060 clang_disposeString(BFileName);
9061 return *this;
9062}
9063
9064Logger &cxindex::Logger::operator<<(CXString Str) {
9065 *this << clang_getCString(Str);
9066 return *this;
9067}
9068
9069Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9070 LogOS << Fmt;
9071 return *this;
9072}
9073
Benjamin Kramer762bc332019-08-07 14:44:40 +00009074static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009075
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009076cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009077 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009078
9079 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9080
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009081 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009082 OS << "[libclang:" << Name << ':';
9083
Alp Toker1a86ad22014-07-06 06:24:00 +00009084#ifdef USE_DARWIN_THREADS
9085 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009086 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9087 OS << tid << ':';
9088#endif
9089
9090 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9091 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009092 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009093
9094 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009095 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009096 OS << "--------------------------------------------------\n";
9097 }
9098}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009099
9100#ifdef CLANG_TOOL_EXTRA_BUILD
9101// This anchor is used to force the linker to link the clang-tidy plugin.
9102extern volatile int ClangTidyPluginAnchorSource;
9103static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9104 ClangTidyPluginAnchorSource;
9105
9106// This anchor is used to force the linker to link the clang-include-fixer
9107// plugin.
9108extern volatile int ClangIncludeFixerPluginAnchorSource;
9109static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9110 ClangIncludeFixerPluginAnchorSource;
9111#endif