blob: 273b579754aefb759398d21de115e394cd1d17b3 [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
Jan Korousbaf3c772020-09-02 13:11:35 -0700167CharSourceRange cxloc::translateCXRangeToCharRange(CXSourceRange R) {
168 return CharSourceRange::getCharRange(
169 SourceLocation::getFromRawEncoding(R.begin_int_data),
170 SourceLocation::getFromRawEncoding(R.end_int_data));
171}
172
Guy Benyei11169dd2012-12-18 14:30:41 +0000173//===----------------------------------------------------------------------===//
174// Cursor visitor.
175//===----------------------------------------------------------------------===//
176
177static SourceRange getRawCursorExtent(CXCursor C);
178static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
179
Guy Benyei11169dd2012-12-18 14:30:41 +0000180RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
181 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
182}
183
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000184/// Visit the given cursor and, if requested by the visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +0000185/// its children.
186///
187/// \param Cursor the cursor to visit.
188///
189/// \param CheckedRegionOfInterest if true, then the caller already checked
190/// that this cursor is within the region of interest.
191///
192/// \returns true if the visitation should be aborted, false if it
193/// should continue.
194bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
195 if (clang_isInvalid(Cursor.kind))
196 return false;
197
198 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000199 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000200 if (!D) {
201 assert(0 && "Invalid declaration cursor");
202 return true; // abort.
203 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500204
Guy Benyei11169dd2012-12-18 14:30:41 +0000205 // Ignore implicit declarations, unless it's an objc method because
206 // currently we should report implicit methods for properties when indexing.
207 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
208 return false;
209 }
210
211 // If we have a range of interest, and this cursor doesn't intersect with it,
212 // we're done.
213 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
214 SourceRange Range = getRawCursorExtent(Cursor);
215 if (Range.isInvalid() || CompareRegionOfInterest(Range))
216 return false;
217 }
218
219 switch (Visitor(Cursor, Parent, ClientData)) {
220 case CXChildVisit_Break:
221 return true;
222
223 case CXChildVisit_Continue:
224 return false;
225
226 case CXChildVisit_Recurse: {
227 bool ret = VisitChildren(Cursor);
228 if (PostChildrenVisitor)
229 if (PostChildrenVisitor(Cursor, ClientData))
230 return true;
231 return ret;
232 }
233 }
234
235 llvm_unreachable("Invalid CXChildVisitResult!");
236}
237
238static bool visitPreprocessedEntitiesInRange(SourceRange R,
239 PreprocessingRecord &PPRec,
240 CursorVisitor &Visitor) {
241 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
242 FileID FID;
Michael Kruse7520cf02020-03-25 09:26:14 -0500243
Guy Benyei11169dd2012-12-18 14:30:41 +0000244 if (!Visitor.shouldVisitIncludedEntities()) {
245 // If the begin/end of the range lie in the same FileID, do the optimization
Michael Kruse7520cf02020-03-25 09:26:14 -0500246 // where we skip preprocessed entities that do not come from the same
247 // FileID.
Guy Benyei11169dd2012-12-18 14:30:41 +0000248 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
249 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
250 FID = FileID();
251 }
252
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000253 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
254 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000255 PPRec, FID);
256}
257
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000258bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000259 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000260 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000261
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000262 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000263 SourceManager &SM = Unit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -0500264
265 std::pair<FileID, unsigned> Begin = SM.getDecomposedLoc(
266 SM.getFileLoc(RegionOfInterest.getBegin())),
267 End = SM.getDecomposedLoc(
268 SM.getFileLoc(RegionOfInterest.getEnd()));
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
270 if (End.first != Begin.first) {
271 // If the end does not reside in the same file, try to recover by
272 // picking the end of the file of begin location.
273 End.first = Begin.first;
274 End.second = SM.getFileIDSize(Begin.first);
275 }
276
277 assert(Begin.first == End.first);
278 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -0500280
Guy Benyei11169dd2012-12-18 14:30:41 +0000281 FileID File = Begin.first;
282 unsigned Offset = Begin.second;
283 unsigned Length = End.second - Begin.second;
284
285 if (!VisitDeclsOnly && !VisitPreprocessorLast)
286 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000287 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000288
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000289 if (visitDeclsFromFileRegion(File, Offset, Length))
290 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000291
292 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000293 return visitPreprocessedEntitiesInRegion();
294
295 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000296}
297
298static bool isInLexicalContext(Decl *D, DeclContext *DC) {
299 if (!DC)
300 return false;
301
Michael Kruse7520cf02020-03-25 09:26:14 -0500302 for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;
303 DeclDC = DeclDC->getLexicalParent()) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000304 if (DeclDC == DC)
305 return true;
306 }
307 return false;
308}
309
Michael Kruse7520cf02020-03-25 09:26:14 -0500310bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,
311 unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000312 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000313 SourceManager &SM = Unit->getSourceManager();
314 SourceRange Range = RegionOfInterest;
315
316 SmallVector<Decl *, 16> Decls;
317 Unit->findFileRegionDecls(File, Offset, Length, Decls);
318
319 // If we didn't find any file level decls for the file, try looking at the
320 // file that it was included from.
321 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
322 bool Invalid = false;
323 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
324 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000325 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000326
327 SourceLocation Outer;
328 if (SLEntry.isFile())
329 Outer = SLEntry.getFile().getIncludeLoc();
330 else
331 Outer = SLEntry.getExpansion().getExpansionLocStart();
332 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000333 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000334
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000335 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Length = 0;
337 Unit->findFileRegionDecls(File, Offset, Length, Decls);
338 }
339
340 assert(!Decls.empty());
341
342 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000343 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000344 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
345 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000346 Decl *D = *DIt;
347 if (D->getSourceRange().isInvalid())
348 continue;
349
350 if (isInLexicalContext(D, CurDC))
351 continue;
352
353 CurDC = dyn_cast<DeclContext>(D);
354
355 if (TagDecl *TD = dyn_cast<TagDecl>(D))
356 if (!TD->isFreeStanding())
357 continue;
358
Michael Kruse7520cf02020-03-25 09:26:14 -0500359 RangeComparisonResult CompRes =
360 RangeCompare(SM, D->getSourceRange(), Range);
Guy Benyei11169dd2012-12-18 14:30:41 +0000361 if (CompRes == RangeBefore)
362 continue;
363 if (CompRes == RangeAfter)
364 break;
365
366 assert(CompRes == RangeOverlap);
367 VisitedAtLeastOnce = true;
368
369 if (isa<ObjCContainerDecl>(D)) {
370 FileDI_current = &DIt;
371 FileDE_current = DE;
372 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000373 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000374 }
375
376 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000378 }
379
380 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000381 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000382
383 // No Decls overlapped with the range. Move up the lexical context until there
384 // is a context that contains the range or we reach the translation unit
385 // level.
Michael Kruse7520cf02020-03-25 09:26:14 -0500386 DeclContext *DC = DIt == Decls.begin()
387 ? (*DIt)->getLexicalDeclContext()
388 : (*(DIt - 1))->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +0000389
390 while (DC && !DC->isTranslationUnit()) {
391 Decl *D = cast<Decl>(DC);
392 SourceRange CurDeclRange = D->getSourceRange();
393 if (CurDeclRange.isInvalid())
394 break;
395
396 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000397 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
398 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000399 }
400
401 DC = D->getLexicalDeclContext();
402 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000403
404 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000405}
406
407bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
408 if (!AU->getPreprocessor().getPreprocessingRecord())
409 return false;
410
Michael Kruse7520cf02020-03-25 09:26:14 -0500411 PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();
Guy Benyei11169dd2012-12-18 14:30:41 +0000412 SourceManager &SM = AU->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -0500413
Guy Benyei11169dd2012-12-18 14:30:41 +0000414 if (RegionOfInterest.isValid()) {
415 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
416 SourceLocation B = MappedRange.getBegin();
417 SourceLocation E = MappedRange.getEnd();
418
419 if (AU->isInPreambleFileID(B)) {
420 if (SM.isLoadedSourceLocation(E))
Michael Kruse7520cf02020-03-25 09:26:14 -0500421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,
422 *this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000423
424 // Beginning of range lies in the preamble but it also extends beyond
425 // it into the main file. Split the range into 2 parts, one covering
426 // the preamble and another covering the main file. This allows subsequent
427 // calls to visitPreprocessedEntitiesInRange to accept a source range that
428 // lies in the same FileID, allowing it to skip preprocessed entities that
429 // do not come from the same FileID.
Michael Kruse7520cf02020-03-25 09:26:14 -0500430 bool breaked = visitPreprocessedEntitiesInRange(
431 SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);
432 if (breaked)
433 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000434 return visitPreprocessedEntitiesInRange(
Michael Kruse7520cf02020-03-25 09:26:14 -0500435 SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);
Guy Benyei11169dd2012-12-18 14:30:41 +0000436 }
437
438 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
439 }
440
Michael Kruse7520cf02020-03-25 09:26:14 -0500441 bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
442
Guy Benyei11169dd2012-12-18 14:30:41 +0000443 if (OnlyLocalDecls)
444 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
445 PPRec);
446
447 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
448}
449
Michael Kruse7520cf02020-03-25 09:26:14 -0500450template <typename InputIterator>
Guy Benyei11169dd2012-12-18 14:30:41 +0000451bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
452 InputIterator Last,
453 PreprocessingRecord &PPRec,
454 FileID FID) {
455 for (; First != Last; ++First) {
456 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
457 continue;
458
459 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000460 if (!PPE)
461 continue;
462
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
464 if (Visit(MakeMacroExpansionCursor(ME, TU)))
465 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000466
Guy Benyei11169dd2012-12-18 14:30:41 +0000467 continue;
468 }
Richard Smith66a81862015-05-04 02:25:31 +0000469
470 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000471 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
472 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000473
Guy Benyei11169dd2012-12-18 14:30:41 +0000474 continue;
475 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500476
Guy Benyei11169dd2012-12-18 14:30:41 +0000477 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
478 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
479 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500480
Guy Benyei11169dd2012-12-18 14:30:41 +0000481 continue;
482 }
483 }
484
485 return false;
486}
487
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000488/// Visit the children of the given cursor.
Michael Kruse7520cf02020-03-25 09:26:14 -0500489///
Guy Benyei11169dd2012-12-18 14:30:41 +0000490/// \returns true if the visitation should be aborted, false if it
491/// should continue.
492bool CursorVisitor::VisitChildren(CXCursor Cursor) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500493 if (clang_isReference(Cursor.kind) &&
Guy Benyei11169dd2012-12-18 14:30:41 +0000494 Cursor.kind != CXCursor_CXXBaseSpecifier) {
495 // By definition, references have no children.
496 return false;
497 }
498
499 // Set the Parent field to Cursor, then back to its old value once we're
500 // done.
501 SetParentRAII SetParent(Parent, StmtParent, Cursor);
502
503 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000504 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 if (!D)
506 return false;
507
508 return VisitAttributes(D) || Visit(D);
509 }
510
511 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000512 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000513 return Visit(S);
514
515 return false;
516 }
517
518 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000519 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000520 return Visit(E);
521
522 return false;
523 }
524
525 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000526 CXTranslationUnit TU = getCursorTU(Cursor);
527 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -0500528
529 int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 for (unsigned I = 0; I != 2; ++I) {
531 if (VisitOrder[I]) {
532 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
533 RegionOfInterest.isInvalid()) {
534 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -0500535 TLEnd = CXXUnit->top_level_end();
Guy Benyei11169dd2012-12-18 14:30:41 +0000536 TL != TLEnd; ++TL) {
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000537 const Optional<bool> V = handleDeclForVisitation(*TL);
538 if (!V.hasValue())
539 continue;
540 return V.getValue();
Guy Benyei11169dd2012-12-18 14:30:41 +0000541 }
542 } else if (VisitDeclContext(
Michael Kruse7520cf02020-03-25 09:26:14 -0500543 CXXUnit->getASTContext().getTranslationUnitDecl()))
Guy Benyei11169dd2012-12-18 14:30:41 +0000544 return true;
545 continue;
546 }
547
548 // Walk the preprocessing record.
549 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
550 visitPreprocessedEntitiesInRegion();
551 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500552
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 return false;
554 }
555
556 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000557 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000558 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
559 return Visit(BaseTSInfo->getTypeLoc());
560 }
561 }
562 }
563
564 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000565 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -0500566 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000567 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000568 return Visit(cxcursor::MakeCursorObjCClassRef(
569 ObjT->getInterface(),
Stephen Kellyf2ceec42018-08-09 21:08:08 +0000570 A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000571 }
572
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000573 // If pointing inside a macro definition, check if the token is an identifier
574 // that was ever defined as a macro. In such a case, create a "pseudo" macro
575 // expansion cursor for that token.
576 SourceLocation BeginLoc = RegionOfInterest.getBegin();
577 if (Cursor.kind == CXCursor_MacroDefinition &&
578 BeginLoc == RegionOfInterest.getEnd()) {
579 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000580 const MacroInfo *MI =
581 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000582 if (MacroDefinitionRecord *MacroDef =
583 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000584 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
585 }
586
Guy Benyei11169dd2012-12-18 14:30:41 +0000587 // Nothing to visit at the moment.
588 return false;
589}
590
591bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
592 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
593 if (Visit(TSInfo->getTypeLoc()))
Michael Kruse7520cf02020-03-25 09:26:14 -0500594 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000595
596 if (Stmt *Body = B->getBody())
597 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
598
599 return false;
600}
601
Ted Kremenek03325582013-02-21 01:29:01 +0000602Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000603 if (RegionOfInterest.isValid()) {
604 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
605 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000606 return None;
Michael Kruse7520cf02020-03-25 09:26:14 -0500607
Guy Benyei11169dd2012-12-18 14:30:41 +0000608 switch (CompareRegionOfInterest(Range)) {
609 case RangeBefore:
610 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000611 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000612
613 case RangeAfter:
614 // This declaration comes after the region of interest; we're done.
615 return false;
616
617 case RangeOverlap:
618 // This declaration overlaps the region of interest; visit it.
619 break;
620 }
621 }
622 return true;
623}
624
625bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
626 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
627
628 // FIXME: Eventually remove. This part of a hack to support proper
629 // iteration over all Decls contained lexically within an ObjC container.
Michael Kruse7520cf02020-03-25 09:26:14 -0500630 SaveAndRestore<DeclContext::decl_iterator *> DI_saved(DI_current, &I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000631 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
632
Michael Kruse7520cf02020-03-25 09:26:14 -0500633 for (; I != E; ++I) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000634 Decl *D = *I;
635 if (D->getLexicalDeclContext() != DC)
636 continue;
Adrian Prantl2073dd22019-11-04 14:28:14 -0800637 // Filter out synthesized property accessor redeclarations.
638 if (isa<ObjCImplDecl>(DC))
639 if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
640 if (OMD->isSynthesizedAccessorStub())
641 continue;
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000642 const Optional<bool> V = handleDeclForVisitation(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000643 if (!V.hasValue())
644 continue;
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000645 return V.getValue();
Guy Benyei11169dd2012-12-18 14:30:41 +0000646 }
647 return false;
648}
649
Argyrios Kyrtzidise7c91042016-07-01 19:10:54 +0000650Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
651 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
652
653 // Ignore synthesized ivars here, otherwise if we have something like:
654 // @synthesize prop = _prop;
655 // and '_prop' is not declared, we will encounter a '_prop' ivar before
656 // encountering the 'prop' synthesize declaration and we will think that
657 // we passed the region-of-interest.
658 if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
659 if (ivarD->getSynthesize())
660 return None;
661 }
662
663 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
664 // declarations is a mismatch with the compiler semantics.
665 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
666 auto *ID = cast<ObjCInterfaceDecl>(D);
667 if (!ID->isThisDeclarationADefinition())
668 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
669
670 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
671 auto *PD = cast<ObjCProtocolDecl>(D);
672 if (!PD->isThisDeclarationADefinition())
673 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
674 }
675
676 const Optional<bool> V = shouldVisitCursor(Cursor);
677 if (!V.hasValue())
678 return None;
679 if (!V.getValue())
680 return false;
681 if (Visit(Cursor, true))
682 return true;
683 return None;
684}
685
Guy Benyei11169dd2012-12-18 14:30:41 +0000686bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
687 llvm_unreachable("Translation units are visited directly by Visit()");
688}
689
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000690bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500691 if (VisitTemplateParameters(D->getTemplateParameters()))
692 return true;
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000693
Michael Kruse7520cf02020-03-25 09:26:14 -0500694 return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +0000695}
696
Guy Benyei11169dd2012-12-18 14:30:41 +0000697bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
698 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
699 return Visit(TSInfo->getTypeLoc());
700
701 return false;
702}
703
704bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
705 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
706 return Visit(TSInfo->getTypeLoc());
707
708 return false;
709}
710
Michael Kruse7520cf02020-03-25 09:26:14 -0500711bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }
Guy Benyei11169dd2012-12-18 14:30:41 +0000712
713bool CursorVisitor::VisitClassTemplateSpecializationDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -0500714 ClassTemplateSpecializationDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000715 bool ShouldVisitBody = false;
716 switch (D->getSpecializationKind()) {
717 case TSK_Undeclared:
718 case TSK_ImplicitInstantiation:
719 // Nothing to visit
720 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -0500721
Guy Benyei11169dd2012-12-18 14:30:41 +0000722 case TSK_ExplicitInstantiationDeclaration:
723 case TSK_ExplicitInstantiationDefinition:
724 break;
Michael Kruse7520cf02020-03-25 09:26:14 -0500725
Guy Benyei11169dd2012-12-18 14:30:41 +0000726 case TSK_ExplicitSpecialization:
727 ShouldVisitBody = true;
728 break;
729 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500730
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 // Visit the template arguments used in the specialization.
732 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
733 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000734 if (TemplateSpecializationTypeLoc TSTLoc =
735 TL.getAs<TemplateSpecializationTypeLoc>()) {
736 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
737 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000738 return true;
739 }
740 }
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000741
742 return ShouldVisitBody && VisitCXXRecordDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +0000743}
744
745bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -0500746 ClassTemplatePartialSpecializationDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000747 // FIXME: Visit the "outer" template parameter lists on the TagDecl
748 // before visiting these template parameters.
749 if (VisitTemplateParameters(D->getTemplateParameters()))
750 return true;
751
752 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000753 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
754 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
755 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000756 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
757 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500758
Guy Benyei11169dd2012-12-18 14:30:41 +0000759 return VisitCXXRecordDecl(D);
760}
761
762bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
Saar Razff1e0fc2020-01-15 02:48:42 +0200763 if (const auto *TC = D->getTypeConstraint())
764 if (Visit(MakeCXCursor(TC->getImmediatelyDeclaredConstraint(), StmtParent,
765 TU, RegionOfInterest)))
766 return true;
767
Guy Benyei11169dd2012-12-18 14:30:41 +0000768 // Visit the default argument.
769 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
770 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
771 if (Visit(DefArg->getTypeLoc()))
772 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500773
Guy Benyei11169dd2012-12-18 14:30:41 +0000774 return false;
775}
776
777bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
778 if (Expr *Init = D->getInitExpr())
779 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
780 return false;
781}
782
783bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000784 unsigned NumParamList = DD->getNumTemplateParameterLists();
785 for (unsigned i = 0; i < NumParamList; i++) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500786 TemplateParameterList *Params = DD->getTemplateParameterList(i);
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000787 if (VisitTemplateParameters(Params))
788 return true;
789 }
790
Guy Benyei11169dd2012-12-18 14:30:41 +0000791 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
792 if (Visit(TSInfo->getTypeLoc()))
793 return true;
794
795 // Visit the nested-name-specifier, if present.
796 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
797 if (VisitNestedNameSpecifierLoc(QualifierLoc))
798 return true;
799
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000800 return false;
801}
802
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000803static bool HasTrailingReturnType(FunctionDecl *ND) {
804 const QualType Ty = ND->getType();
805 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
806 if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
807 return FT->hasTrailingReturn();
808 }
809
810 return false;
811}
812
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000813/// Compare two base or member initializers based on their source order.
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000814static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
815 CXXCtorInitializer *const *Y) {
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000816 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
817}
818
Guy Benyei11169dd2012-12-18 14:30:41 +0000819bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000820 unsigned NumParamList = ND->getNumTemplateParameterLists();
821 for (unsigned i = 0; i < NumParamList; i++) {
Michael Kruse7520cf02020-03-25 09:26:14 -0500822 TemplateParameterList *Params = ND->getTemplateParameterList(i);
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000823 if (VisitTemplateParameters(Params))
824 return true;
825 }
826
Guy Benyei11169dd2012-12-18 14:30:41 +0000827 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
828 // Visit the function declaration's syntactic components in the order
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000829 // written. This requires a bit of work.
830 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
831 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000832 const bool HasTrailingRT = HasTrailingReturnType(ND);
Michael Kruse7520cf02020-03-25 09:26:14 -0500833
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000834 // If we have a function declared directly (without the use of a typedef),
835 // visit just the return type. Otherwise, just visit the function's type
836 // now.
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000837 if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
838 Visit(FTL.getReturnLoc())) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000839 (!FTL && Visit(TL)))
840 return true;
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000841
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000842 // Visit the nested-name-specifier, if present.
843 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
844 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +0000845 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500846
Guy Benyei11169dd2012-12-18 14:30:41 +0000847 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000848 if (!isa<CXXDestructorDecl>(ND))
849 if (VisitDeclarationNameInfo(ND->getNameInfo()))
850 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500851
Guy Benyei11169dd2012-12-18 14:30:41 +0000852 // FIXME: Visit explicitly-specified template arguments!
Michael Kruse7520cf02020-03-25 09:26:14 -0500853
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000854 // Visit the function parameters, if we have a function type.
855 if (FTL && VisitFunctionTypeLoc(FTL, true))
856 return true;
Ivan Donchevskii1d187132018-01-03 14:35:48 +0000857
858 // Visit the function's trailing return type.
859 if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
860 return true;
861
Ivan Donchevskii1c27b152018-01-03 10:33:21 +0000862 // FIXME: Attributes?
863 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500864
Guy Benyei11169dd2012-12-18 14:30:41 +0000865 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
866 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
867 // Find the initializers that were written in the source.
868 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000869 for (auto *I : Constructor->inits()) {
870 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000871 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -0500872
Aaron Ballman0ad78302014-03-13 17:34:31 +0000873 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000874 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500875
Guy Benyei11169dd2012-12-18 14:30:41 +0000876 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000877 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
878 &CompareCXXCtorInitializers);
Michael Kruse7520cf02020-03-25 09:26:14 -0500879
Guy Benyei11169dd2012-12-18 14:30:41 +0000880 // Visit the initializers in source order
881 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
882 CXXCtorInitializer *Init = WrittenInits[I];
883 if (Init->isAnyMemberInitializer()) {
884 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
885 Init->getMemberLocation(), TU)))
886 return true;
887 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
888 if (Visit(TInfo->getTypeLoc()))
889 return true;
890 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500891
Guy Benyei11169dd2012-12-18 14:30:41 +0000892 // Visit the initializer value.
893 if (Expr *Initializer = Init->getInit())
894 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
895 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500896 }
Guy Benyei11169dd2012-12-18 14:30:41 +0000897 }
Michael Kruse7520cf02020-03-25 09:26:14 -0500898
Guy Benyei11169dd2012-12-18 14:30:41 +0000899 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
900 return true;
901 }
902
903 return false;
904}
905
906bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
907 if (VisitDeclaratorDecl(D))
908 return true;
909
910 if (Expr *BitWidth = D->getBitWidth())
911 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
912
Benjamin Kramer99f97592017-11-15 12:20:41 +0000913 if (Expr *Init = D->getInClassInitializer())
914 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
915
Guy Benyei11169dd2012-12-18 14:30:41 +0000916 return false;
917}
918
919bool CursorVisitor::VisitVarDecl(VarDecl *D) {
920 if (VisitDeclaratorDecl(D))
921 return true;
922
923 if (Expr *Init = D->getInit())
924 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
925
926 return false;
927}
928
929bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
930 if (VisitDeclaratorDecl(D))
931 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500932
Guy Benyei11169dd2012-12-18 14:30:41 +0000933 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
934 if (Expr *DefArg = D->getDefaultArgument())
935 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
Michael Kruse7520cf02020-03-25 09:26:14 -0500936
937 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000938}
939
940bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
941 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
942 // before visiting these template parameters.
943 if (VisitTemplateParameters(D->getTemplateParameters()))
944 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500945
946 auto *FD = D->getTemplatedDecl();
Jonathan Coe578ac7a2017-10-16 23:43:02 +0000947 return VisitAttributes(FD) || VisitFunctionDecl(FD);
Guy Benyei11169dd2012-12-18 14:30:41 +0000948}
949
950bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
951 // FIXME: Visit the "outer" template parameter lists on the TagDecl
952 // before visiting these template parameters.
953 if (VisitTemplateParameters(D->getTemplateParameters()))
954 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500955
956 auto *CD = D->getTemplatedDecl();
Jonathan Coe578ac7a2017-10-16 23:43:02 +0000957 return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
Guy Benyei11169dd2012-12-18 14:30:41 +0000958}
959
960bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
961 if (VisitTemplateParameters(D->getTemplateParameters()))
962 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500963
Guy Benyei11169dd2012-12-18 14:30:41 +0000964 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
965 VisitTemplateArgumentLoc(D->getDefaultArgument()))
966 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -0500967
Guy Benyei11169dd2012-12-18 14:30:41 +0000968 return false;
969}
970
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000971bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
972 // Visit the bound, if it's explicit.
973 if (D->hasExplicitBound()) {
974 if (auto TInfo = D->getTypeSourceInfo()) {
975 if (Visit(TInfo->getTypeLoc()))
976 return true;
977 }
978 }
979
980 return false;
981}
982
Guy Benyei11169dd2012-12-18 14:30:41 +0000983bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000984 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000985 if (Visit(TSInfo->getTypeLoc()))
986 return true;
987
David Majnemer59f77922016-06-24 04:05:48 +0000988 for (const auto *P : ND->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +0000989 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000990 return true;
991 }
992
Alexander Kornienko1a9f1842015-12-28 15:24:08 +0000993 return ND->isThisDeclarationADefinition() &&
994 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
Guy Benyei11169dd2012-12-18 14:30:41 +0000995}
996
997template <typename DeclIt>
998static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
999 SourceManager &SM, SourceLocation EndLoc,
1000 SmallVectorImpl<Decl *> &Decls) {
1001 DeclIt next = *DI_current;
1002 while (++next != DE_current) {
1003 Decl *D_next = *next;
1004 if (!D_next)
1005 break;
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001006 SourceLocation L = D_next->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00001007 if (!L.isValid())
1008 break;
1009 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
1010 *DI_current = next;
1011 Decls.push_back(D_next);
1012 continue;
1013 }
1014 break;
1015 }
1016}
1017
Guy Benyei11169dd2012-12-18 14:30:41 +00001018bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
1019 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
1020 // an @implementation can lexically contain Decls that are not properly
1021 // nested in the AST. When we identify such cases, we need to retrofit
1022 // this nesting here.
1023 if (!DI_current && !FileDI_current)
1024 return VisitDeclContext(D);
1025
1026 // Scan the Decls that immediately come after the container
1027 // in the current DeclContext. If any fall within the
1028 // container's lexical region, stash them into a vector
1029 // for later processing.
1030 SmallVector<Decl *, 24> DeclsInContainer;
1031 SourceLocation EndLoc = D->getSourceRange().getEnd();
1032 SourceManager &SM = AU->getSourceManager();
1033 if (EndLoc.isValid()) {
1034 if (DI_current) {
1035 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
1036 DeclsInContainer);
1037 } else {
1038 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
1039 DeclsInContainer);
1040 }
1041 }
1042
1043 // The common case.
1044 if (DeclsInContainer.empty())
1045 return VisitDeclContext(D);
1046
1047 // Get all the Decls in the DeclContext, and sort them with the
1048 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001049 for (auto *SubDecl : D->decls()) {
1050 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001051 SubDecl->getBeginLoc().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001052 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001053 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001054 }
1055
1056 // Now sort the Decls so that they appear in lexical order.
Michael Kruse7520cf02020-03-25 09:26:14 -05001057 llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {
1058 SourceLocation L_A = A->getBeginLoc();
1059 SourceLocation L_B = B->getBeginLoc();
1060 return L_A != L_B
1061 ? SM.isBeforeInTranslationUnit(L_A, L_B)
1062 : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());
1063 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001064
1065 // Now visit the decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05001066 for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),
1067 E = DeclsInContainer.end();
1068 I != E; ++I) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001069 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001070 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001071 if (!V.hasValue())
1072 continue;
1073 if (!V.getValue())
1074 return false;
1075 if (Visit(Cursor, true))
1076 return true;
1077 }
1078 return false;
1079}
1080
1081bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1082 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1083 TU)))
1084 return true;
1085
Douglas Gregore9d95f12015-07-07 03:57:35 +00001086 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1087 return true;
1088
Guy Benyei11169dd2012-12-18 14:30:41 +00001089 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1090 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001091 E = ND->protocol_end();
1092 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001093 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1094 return true;
1095
1096 return VisitObjCContainerDecl(ND);
1097}
1098
1099bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1100 if (!PID->isThisDeclarationADefinition())
1101 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001102
Guy Benyei11169dd2012-12-18 14:30:41 +00001103 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1104 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001105 E = PID->protocol_end();
1106 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001107 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1108 return true;
1109
1110 return VisitObjCContainerDecl(PID);
1111}
1112
1113bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1114 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1115 return true;
1116
1117 // FIXME: This implements a workaround with @property declarations also being
1118 // installed in the DeclContext for the @interface. Eventually this code
1119 // should be removed.
1120 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1121 if (!CDecl || !CDecl->IsClassExtension())
1122 return false;
1123
1124 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1125 if (!ID)
1126 return false;
1127
1128 IdentifierInfo *PropertyId = PD->getIdentifier();
Michael Kruse7520cf02020-03-25 09:26:14 -05001129 ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
1130 cast<DeclContext>(ID), PropertyId, PD->getQueryKind());
Guy Benyei11169dd2012-12-18 14:30:41 +00001131
1132 if (!prevDecl)
1133 return false;
1134
1135 // Visit synthesized methods since they will be skipped when visiting
1136 // the @interface.
1137 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1138 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1139 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1140 return true;
1141
1142 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1143 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1144 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1145 return true;
1146
1147 return false;
1148}
1149
Douglas Gregore9d95f12015-07-07 03:57:35 +00001150bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1151 if (!typeParamList)
1152 return false;
1153
1154 for (auto *typeParam : *typeParamList) {
1155 // Visit the type parameter.
1156 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1157 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001158 }
1159
1160 return false;
1161}
1162
Guy Benyei11169dd2012-12-18 14:30:41 +00001163bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1164 if (!D->isThisDeclarationADefinition()) {
1165 // Forward declaration is treated like a reference.
1166 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1167 }
1168
Douglas Gregore9d95f12015-07-07 03:57:35 +00001169 // Objective-C type parameters.
1170 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1171 return true;
1172
Guy Benyei11169dd2012-12-18 14:30:41 +00001173 // Issue callbacks for super class.
Michael Kruse7520cf02020-03-25 09:26:14 -05001174 if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
1175 D->getSuperClass(), D->getSuperClassLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001176 return true;
1177
Douglas Gregore9d95f12015-07-07 03:57:35 +00001178 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1179 if (Visit(SuperClassTInfo->getTypeLoc()))
1180 return true;
1181
Guy Benyei11169dd2012-12-18 14:30:41 +00001182 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1183 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001184 E = D->protocol_end();
1185 I != E; ++I, ++PL)
Guy Benyei11169dd2012-12-18 14:30:41 +00001186 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1187 return true;
1188
1189 return VisitObjCContainerDecl(D);
1190}
1191
1192bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1193 return VisitObjCContainerDecl(D);
1194}
1195
1196bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1197 // 'ID' could be null when dealing with invalid code.
1198 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1199 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1200 return true;
1201
1202 return VisitObjCImplDecl(D);
1203}
1204
1205bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1206#if 0
1207 // Issue callbacks for super class.
1208 // FIXME: No source location information!
1209 if (D->getSuperClass() &&
1210 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1211 D->getSuperClassLoc(),
1212 TU)))
1213 return true;
1214#endif
1215
1216 return VisitObjCImplDecl(D);
1217}
1218
1219bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1220 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1221 if (PD->isIvarNameSpecified())
1222 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001223
Guy Benyei11169dd2012-12-18 14:30:41 +00001224 return false;
1225}
1226
1227bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1228 return VisitDeclContext(D);
1229}
1230
1231bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1232 // Visit nested-name-specifier.
1233 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1234 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1235 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001236
1237 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001238 D->getTargetNameLoc(), TU));
1239}
1240
1241bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1242 // Visit nested-name-specifier.
1243 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1244 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1245 return true;
1246 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001247
Guy Benyei11169dd2012-12-18 14:30:41 +00001248 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1249 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001250
Guy Benyei11169dd2012-12-18 14:30:41 +00001251 return VisitDeclarationNameInfo(D->getNameInfo());
1252}
1253
1254bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1255 // Visit nested-name-specifier.
1256 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1257 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1258 return true;
1259
1260 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1261 D->getIdentLocation(), TU));
1262}
1263
1264bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1265 // Visit nested-name-specifier.
1266 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1267 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1268 return true;
1269 }
1270
1271 return VisitDeclarationNameInfo(D->getNameInfo());
1272}
1273
1274bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
Michael Kruse7520cf02020-03-25 09:26:14 -05001275 UnresolvedUsingTypenameDecl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001276 // Visit nested-name-specifier.
1277 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1278 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1279 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001280
Guy Benyei11169dd2012-12-18 14:30:41 +00001281 return false;
1282}
1283
Olivier Goffart81978012016-06-09 16:15:55 +00001284bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
1285 if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
1286 return true;
Richard Trieuf3b77662016-09-13 01:37:01 +00001287 if (StringLiteral *Message = D->getMessage())
1288 if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
1289 return true;
Olivier Goffart81978012016-06-09 16:15:55 +00001290 return false;
1291}
1292
Olivier Goffartd211c642016-11-04 06:29:27 +00001293bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {
1294 if (NamedDecl *FriendD = D->getFriendDecl()) {
1295 if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))
1296 return true;
1297 } else if (TypeSourceInfo *TI = D->getFriendType()) {
1298 if (Visit(TI->getTypeLoc()))
1299 return true;
1300 }
1301 return false;
1302}
1303
Milian Wolff4597e3b2020-05-02 22:17:59 +02001304bool CursorVisitor::VisitDecompositionDecl(DecompositionDecl *D) {
1305 for (auto *B : D->bindings()) {
1306 if (Visit(MakeCXCursor(B, TU, RegionOfInterest)))
1307 return true;
1308 }
1309 return VisitVarDecl(D);
1310}
1311
Guy Benyei11169dd2012-12-18 14:30:41 +00001312bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1313 switch (Name.getName().getNameKind()) {
1314 case clang::DeclarationName::Identifier:
1315 case clang::DeclarationName::CXXLiteralOperatorName:
Richard Smith35845152017-02-07 01:37:30 +00001316 case clang::DeclarationName::CXXDeductionGuideName:
Guy Benyei11169dd2012-12-18 14:30:41 +00001317 case clang::DeclarationName::CXXOperatorName:
1318 case clang::DeclarationName::CXXUsingDirective:
1319 return false;
Richard Smith35845152017-02-07 01:37:30 +00001320
Guy Benyei11169dd2012-12-18 14:30:41 +00001321 case clang::DeclarationName::CXXConstructorName:
1322 case clang::DeclarationName::CXXDestructorName:
1323 case clang::DeclarationName::CXXConversionFunctionName:
1324 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1325 return Visit(TSInfo->getTypeLoc());
1326 return false;
1327
1328 case clang::DeclarationName::ObjCZeroArgSelector:
1329 case clang::DeclarationName::ObjCOneArgSelector:
1330 case clang::DeclarationName::ObjCMultiArgSelector:
1331 // FIXME: Per-identifier location info?
1332 return false;
1333 }
1334
1335 llvm_unreachable("Invalid DeclarationName::Kind!");
1336}
1337
Michael Kruse7520cf02020-03-25 09:26:14 -05001338bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
Guy Benyei11169dd2012-12-18 14:30:41 +00001339 SourceRange Range) {
1340 // FIXME: This whole routine is a hack to work around the lack of proper
1341 // source information in nested-name-specifiers (PR5791). Since we do have
1342 // a beginning source location, we can visit the first component of the
1343 // nested-name-specifier, if it's a single-token component.
1344 if (!NNS)
1345 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001346
Guy Benyei11169dd2012-12-18 14:30:41 +00001347 // Get the first component in the nested-name-specifier.
1348 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1349 NNS = Prefix;
Michael Kruse7520cf02020-03-25 09:26:14 -05001350
Guy Benyei11169dd2012-12-18 14:30:41 +00001351 switch (NNS->getKind()) {
1352 case NestedNameSpecifier::Namespace:
Michael Kruse7520cf02020-03-25 09:26:14 -05001353 return Visit(
1354 MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001355
1356 case NestedNameSpecifier::NamespaceAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05001357 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001358 Range.getBegin(), TU));
1359
1360 case NestedNameSpecifier::TypeSpec: {
1361 // If the type has a form where we know that the beginning of the source
1362 // range matches up with a reference cursor. Visit the appropriate reference
1363 // cursor.
1364 const Type *T = NNS->getAsType();
1365 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1366 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1367 if (const TagType *Tag = dyn_cast<TagType>(T))
1368 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
Michael Kruse7520cf02020-03-25 09:26:14 -05001369 if (const TemplateSpecializationType *TST =
1370 dyn_cast<TemplateSpecializationType>(T))
Guy Benyei11169dd2012-12-18 14:30:41 +00001371 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1372 break;
1373 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001374
Guy Benyei11169dd2012-12-18 14:30:41 +00001375 case NestedNameSpecifier::TypeSpecWithTemplate:
1376 case NestedNameSpecifier::Global:
1377 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001378 case NestedNameSpecifier::Super:
Michael Kruse7520cf02020-03-25 09:26:14 -05001379 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001380 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001381
Guy Benyei11169dd2012-12-18 14:30:41 +00001382 return false;
1383}
1384
Michael Kruse7520cf02020-03-25 09:26:14 -05001385bool CursorVisitor::VisitNestedNameSpecifierLoc(
1386 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001387 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1388 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1389 Qualifiers.push_back(Qualifier);
Michael Kruse7520cf02020-03-25 09:26:14 -05001390
Guy Benyei11169dd2012-12-18 14:30:41 +00001391 while (!Qualifiers.empty()) {
1392 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1393 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1394 switch (NNS->getKind()) {
1395 case NestedNameSpecifier::Namespace:
Michael Kruse7520cf02020-03-25 09:26:14 -05001396 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1397 Q.getLocalBeginLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001398 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001399
Guy Benyei11169dd2012-12-18 14:30:41 +00001400 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001401
Guy Benyei11169dd2012-12-18 14:30:41 +00001402 case NestedNameSpecifier::NamespaceAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05001403 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1404 Q.getLocalBeginLoc(), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001405 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001406
Guy Benyei11169dd2012-12-18 14:30:41 +00001407 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001408
Guy Benyei11169dd2012-12-18 14:30:41 +00001409 case NestedNameSpecifier::TypeSpec:
1410 case NestedNameSpecifier::TypeSpecWithTemplate:
1411 if (Visit(Q.getTypeLoc()))
1412 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001413
Guy Benyei11169dd2012-12-18 14:30:41 +00001414 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05001415
Guy Benyei11169dd2012-12-18 14:30:41 +00001416 case NestedNameSpecifier::Global:
1417 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001418 case NestedNameSpecifier::Super:
Michael Kruse7520cf02020-03-25 09:26:14 -05001419 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00001420 }
1421 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001422
Guy Benyei11169dd2012-12-18 14:30:41 +00001423 return false;
1424}
1425
1426bool CursorVisitor::VisitTemplateParameters(
Michael Kruse7520cf02020-03-25 09:26:14 -05001427 const TemplateParameterList *Params) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001428 if (!Params)
1429 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001430
Guy Benyei11169dd2012-12-18 14:30:41 +00001431 for (TemplateParameterList::const_iterator P = Params->begin(),
Michael Kruse7520cf02020-03-25 09:26:14 -05001432 PEnd = Params->end();
Guy Benyei11169dd2012-12-18 14:30:41 +00001433 P != PEnd; ++P) {
1434 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1435 return true;
1436 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001437
Guy Benyei11169dd2012-12-18 14:30:41 +00001438 return false;
1439}
1440
1441bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1442 switch (Name.getKind()) {
1443 case TemplateName::Template:
1444 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1445
1446 case TemplateName::OverloadedTemplate:
1447 // Visit the overloaded template set.
1448 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1449 return true;
1450
1451 return false;
1452
Richard Smithb23c5e82019-05-09 03:31:27 +00001453 case TemplateName::AssumedTemplate:
1454 // FIXME: Visit DeclarationName?
1455 return false;
1456
Guy Benyei11169dd2012-12-18 14:30:41 +00001457 case TemplateName::DependentTemplate:
1458 // FIXME: Visit nested-name-specifier.
1459 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001460
Guy Benyei11169dd2012-12-18 14:30:41 +00001461 case TemplateName::QualifiedTemplate:
1462 // FIXME: Visit nested-name-specifier.
1463 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001464 Name.getAsQualifiedTemplateName()->getDecl(), Loc, TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001465
1466 case TemplateName::SubstTemplateTemplateParm:
1467 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001468 Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));
1469
Guy Benyei11169dd2012-12-18 14:30:41 +00001470 case TemplateName::SubstTemplateTemplateParmPack:
1471 return Visit(MakeCursorTemplateRef(
Michael Kruse7520cf02020-03-25 09:26:14 -05001472 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
1473 TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001474 }
1475
1476 llvm_unreachable("Invalid TemplateName::Kind!");
1477}
1478
1479bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1480 switch (TAL.getArgument().getKind()) {
1481 case TemplateArgument::Null:
1482 case TemplateArgument::Integral:
1483 case TemplateArgument::Pack:
1484 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001485
Guy Benyei11169dd2012-12-18 14:30:41 +00001486 case TemplateArgument::Type:
1487 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1488 return Visit(TSInfo->getTypeLoc());
1489 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001490
Guy Benyei11169dd2012-12-18 14:30:41 +00001491 case TemplateArgument::Declaration:
1492 if (Expr *E = TAL.getSourceDeclExpression())
1493 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1494 return false;
1495
1496 case TemplateArgument::NullPtr:
1497 if (Expr *E = TAL.getSourceNullPtrExpression())
1498 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1499 return false;
1500
1501 case TemplateArgument::Expression:
1502 if (Expr *E = TAL.getSourceExpression())
1503 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1504 return false;
Michael Kruse7520cf02020-03-25 09:26:14 -05001505
Guy Benyei11169dd2012-12-18 14:30:41 +00001506 case TemplateArgument::Template:
1507 case TemplateArgument::TemplateExpansion:
1508 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1509 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001510
1511 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001512 TAL.getTemplateNameLoc());
1513 }
1514
1515 llvm_unreachable("Invalid TemplateArgument::Kind!");
1516}
1517
1518bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1519 return VisitDeclContext(D);
1520}
1521
1522bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1523 return Visit(TL.getUnqualifiedLoc());
1524}
1525
1526bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1527 ASTContext &Context = AU->getASTContext();
1528
1529 // Some builtin types (such as Objective-C's "id", "sel", and
1530 // "Class") have associated declarations. Create cursors for those.
1531 QualType VisitType;
1532 switch (TL.getTypePtr()->getKind()) {
1533
1534 case BuiltinType::Void:
1535 case BuiltinType::NullPtr:
1536 case BuiltinType::Dependent:
Michael Kruse7520cf02020-03-25 09:26:14 -05001537#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
Alexey Bader954ba212016-04-08 13:40:33 +00001538 case BuiltinType::Id:
Alexey Baderb62f1442016-04-13 08:33:41 +00001539#include "clang/Basic/OpenCLImageTypes.def"
Michael Kruse7520cf02020-03-25 09:26:14 -05001540#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
Andrew Savonichev3fee3512018-11-08 11:25:41 +00001541#include "clang/Basic/OpenCLExtensionTypes.def"
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001542 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001543 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001544 case BuiltinType::OCLClkEvent:
1545 case BuiltinType::OCLQueue:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001546 case BuiltinType::OCLReserveID:
Michael Kruse7520cf02020-03-25 09:26:14 -05001547#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
Richard Sandifordeb485fb2019-08-09 08:52:54 +00001548#include "clang/Basic/AArch64SVEACLETypes.def"
Baptiste Saleil40dd4d52020-10-28 13:14:48 -05001549#define PPC_MMA_VECTOR_TYPE(Name, Id, Size) case BuiltinType::Id:
1550#include "clang/Basic/PPCTypes.def"
Guy Benyei11169dd2012-12-18 14:30:41 +00001551#define BUILTIN_TYPE(Id, SingletonId)
1552#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1553#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1554#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1555#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1556#include "clang/AST/BuiltinTypes.def"
1557 break;
1558
1559 case BuiltinType::ObjCId:
1560 VisitType = Context.getObjCIdType();
1561 break;
1562
1563 case BuiltinType::ObjCClass:
1564 VisitType = Context.getObjCClassType();
1565 break;
1566
1567 case BuiltinType::ObjCSel:
1568 VisitType = Context.getObjCSelType();
1569 break;
1570 }
1571
1572 if (!VisitType.isNull()) {
1573 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Michael Kruse7520cf02020-03-25 09:26:14 -05001574 return Visit(
1575 MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001576 }
1577
1578 return false;
1579}
1580
1581bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1582 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1583}
1584
1585bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1586 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1587}
1588
1589bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1590 if (TL.isDefinition())
1591 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1592
1593 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1594}
1595
1596bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1597 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1598}
1599
1600bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001601 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001602}
1603
Manman Rene6be26c2016-09-13 17:25:08 +00001604bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001605 if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
Manman Rene6be26c2016-09-13 17:25:08 +00001606 return true;
1607 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1608 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1609 TU)))
1610 return true;
1611 }
1612
1613 return false;
1614}
1615
Guy Benyei11169dd2012-12-18 14:30:41 +00001616bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1617 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1618 return true;
1619
Douglas Gregore9d95f12015-07-07 03:57:35 +00001620 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1621 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1622 return true;
1623 }
1624
Guy Benyei11169dd2012-12-18 14:30:41 +00001625 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1626 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1627 TU)))
1628 return true;
1629 }
1630
1631 return false;
1632}
1633
1634bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1635 return Visit(TL.getPointeeLoc());
1636}
1637
1638bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1639 return Visit(TL.getInnerLoc());
1640}
1641
Leonard Chanc72aaf62019-05-07 03:20:17 +00001642bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
1643 return Visit(TL.getInnerLoc());
1644}
1645
Guy Benyei11169dd2012-12-18 14:30:41 +00001646bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1647 return Visit(TL.getPointeeLoc());
1648}
1649
1650bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1651 return Visit(TL.getPointeeLoc());
1652}
1653
1654bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1655 return Visit(TL.getPointeeLoc());
1656}
1657
1658bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1659 return Visit(TL.getPointeeLoc());
1660}
1661
1662bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1663 return Visit(TL.getPointeeLoc());
1664}
1665
1666bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1667 return Visit(TL.getModifiedLoc());
1668}
1669
Michael Kruse7520cf02020-03-25 09:26:14 -05001670bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
Guy Benyei11169dd2012-12-18 14:30:41 +00001671 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001672 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001673 return true;
1674
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001675 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1676 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001677 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1678 return true;
1679
1680 return false;
1681}
1682
1683bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1684 if (Visit(TL.getElementLoc()))
1685 return true;
1686
1687 if (Expr *Size = TL.getSizeExpr())
1688 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1689
1690 return false;
1691}
1692
Reid Kleckner8a365022013-06-24 17:51:48 +00001693bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1694 return Visit(TL.getOriginalLoc());
1695}
1696
Reid Kleckner0503a872013-12-05 01:23:43 +00001697bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1698 return Visit(TL.getOriginalLoc());
1699}
1700
Richard Smith600b5262017-01-26 20:40:47 +00001701bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
1702 DeducedTemplateSpecializationTypeLoc TL) {
Michael Kruse7520cf02020-03-25 09:26:14 -05001703 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Richard Smith600b5262017-01-26 20:40:47 +00001704 TL.getTemplateNameLoc()))
1705 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001706
Richard Smith600b5262017-01-26 20:40:47 +00001707 return false;
1708}
1709
Guy Benyei11169dd2012-12-18 14:30:41 +00001710bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001711 TemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 // Visit the template name.
Michael Kruse7520cf02020-03-25 09:26:14 -05001713 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 TL.getTemplateNameLoc()))
1715 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001716
Guy Benyei11169dd2012-12-18 14:30:41 +00001717 // Visit the template arguments.
1718 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1719 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1720 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001721
Guy Benyei11169dd2012-12-18 14:30:41 +00001722 return false;
1723}
1724
1725bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1726 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1727}
1728
1729bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1730 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1731 return Visit(TSInfo->getTypeLoc());
1732
1733 return false;
1734}
1735
1736bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1737 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1738 return Visit(TSInfo->getTypeLoc());
1739
1740 return false;
1741}
1742
1743bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001744 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001745}
1746
1747bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001748 DependentTemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001749 // Visit the nested-name-specifier, if there is one.
Michael Kruse7520cf02020-03-25 09:26:14 -05001750 if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001751 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001752
Guy Benyei11169dd2012-12-18 14:30:41 +00001753 // Visit the template arguments.
1754 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1755 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1756 return true;
1757
1758 return false;
1759}
1760
1761bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1762 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1763 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001764
Guy Benyei11169dd2012-12-18 14:30:41 +00001765 return Visit(TL.getNamedTypeLoc());
1766}
1767
1768bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1769 return Visit(TL.getPatternLoc());
1770}
1771
1772bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1773 if (Expr *E = TL.getUnderlyingExpr())
1774 return Visit(MakeCXCursor(E, StmtParent, TU));
1775
1776 return false;
1777}
1778
1779bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1780 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1781}
1782
1783bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1784 return Visit(TL.getValueLoc());
1785}
1786
Xiuli Pan9c14e282016-01-09 12:53:17 +00001787bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1788 return Visit(TL.getValueLoc());
1789}
1790
Michael Kruse7520cf02020-03-25 09:26:14 -05001791#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1792 bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1793 return Visit##PARENT##Loc(TL); \
1794 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001795
1796DEFAULT_TYPELOC_IMPL(Complex, Type)
1797DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1798DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1799DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1800DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
Andrew Gozillon572bbb02017-10-02 06:25:51 +00001801DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
Erich Keanef702b022018-07-13 19:46:04 +00001802DEFAULT_TYPELOC_IMPL(DependentVector, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001803DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1804DEFAULT_TYPELOC_IMPL(Vector, Type)
1805DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
Florian Hahn10658692020-05-11 17:45:51 +01001806DEFAULT_TYPELOC_IMPL(ConstantMatrix, MatrixType)
1807DEFAULT_TYPELOC_IMPL(DependentSizedMatrix, MatrixType)
Guy Benyei11169dd2012-12-18 14:30:41 +00001808DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1809DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1810DEFAULT_TYPELOC_IMPL(Record, TagType)
1811DEFAULT_TYPELOC_IMPL(Enum, TagType)
1812DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1813DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1814DEFAULT_TYPELOC_IMPL(Auto, Type)
Erich Keane5f0903e2020-04-17 10:44:19 -07001815DEFAULT_TYPELOC_IMPL(ExtInt, Type)
1816DEFAULT_TYPELOC_IMPL(DependentExtInt, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001817
1818bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1819 // Visit the nested-name-specifier, if present.
1820 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1821 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1822 return true;
1823
1824 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001825 for (const auto &I : D->bases()) {
1826 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001827 return true;
1828 }
1829 }
1830
1831 return VisitTagDecl(D);
1832}
1833
1834bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001835 for (const auto *I : D->attrs())
Michael Wu40ff1052018-08-03 05:20:23 +00001836 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1837 !I->isImplicit()) &&
1838 Visit(MakeCXCursor(I, D, TU)))
Michael Kruse7520cf02020-03-25 09:26:14 -05001839 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00001840
1841 return false;
1842}
1843
1844//===----------------------------------------------------------------------===//
1845// Data-recursive visitor methods.
1846//===----------------------------------------------------------------------===//
1847
1848namespace {
Michael Kruse7520cf02020-03-25 09:26:14 -05001849#define DEF_JOB(NAME, DATA, KIND) \
1850 class NAME : public VisitorJob { \
1851 public: \
1852 NAME(const DATA *d, CXCursor parent) \
1853 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1854 static bool classof(const VisitorJob *VJ) { \
1855 return VJ->getKind() == KIND; \
1856 } \
1857 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1858 };
Guy Benyei11169dd2012-12-18 14:30:41 +00001859
1860DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1861DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1862DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1863DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001864DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1865DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1866DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1867#undef DEF_JOB
1868
James Y Knight04ec5bf2015-12-24 02:59:37 +00001869class ExplicitTemplateArgsVisit : public VisitorJob {
1870public:
1871 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1872 const TemplateArgumentLoc *End, CXCursor parent)
1873 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1874 End) {}
1875 static bool classof(const VisitorJob *VJ) {
1876 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1877 }
1878 const TemplateArgumentLoc *begin() const {
1879 return static_cast<const TemplateArgumentLoc *>(data[0]);
1880 }
1881 const TemplateArgumentLoc *end() {
1882 return static_cast<const TemplateArgumentLoc *>(data[1]);
1883 }
1884};
Guy Benyei11169dd2012-12-18 14:30:41 +00001885class DeclVisit : public VisitorJob {
1886public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001887 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1888 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1889 isFirst ? (void *)1 : (void *)nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 static bool classof(const VisitorJob *VJ) {
1891 return VJ->getKind() == DeclVisitKind;
1892 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001894 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001895};
1896class TypeLocVisit : public VisitorJob {
1897public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001898 TypeLocVisit(TypeLoc tl, CXCursor parent)
1899 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1900 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001901
1902 static bool classof(const VisitorJob *VJ) {
1903 return VJ->getKind() == TypeLocVisitKind;
1904 }
1905
Michael Kruse7520cf02020-03-25 09:26:14 -05001906 TypeLoc get() const {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001909 }
1910};
1911
1912class LabelRefVisit : public VisitorJob {
1913public:
1914 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001915 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1916 labelLoc.getPtrEncoding()) {}
1917
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 static bool classof(const VisitorJob *VJ) {
1919 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1920 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001921 const LabelDecl *get() const {
1922 return static_cast<const LabelDecl *>(data[0]);
1923 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001924 SourceLocation getLoc() const {
1925 return SourceLocation::getFromPtrEncoding(data[1]);
1926 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001927};
Michael Kruse7520cf02020-03-25 09:26:14 -05001928
Guy Benyei11169dd2012-12-18 14:30:41 +00001929class NestedNameSpecifierLocVisit : public VisitorJob {
1930public:
1931 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001932 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1933 Qualifier.getNestedNameSpecifier(),
1934 Qualifier.getOpaqueData()) {}
1935
Guy Benyei11169dd2012-12-18 14:30:41 +00001936 static bool classof(const VisitorJob *VJ) {
1937 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1938 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001939
Guy Benyei11169dd2012-12-18 14:30:41 +00001940 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001941 return NestedNameSpecifierLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001942 const_cast<NestedNameSpecifier *>(
1943 static_cast<const NestedNameSpecifier *>(data[0])),
1944 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001945 }
1946};
Michael Kruse7520cf02020-03-25 09:26:14 -05001947
Guy Benyei11169dd2012-12-18 14:30:41 +00001948class DeclarationNameInfoVisit : public VisitorJob {
1949public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001950 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001951 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001952 static bool classof(const VisitorJob *VJ) {
1953 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1954 }
1955 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001956 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001957 switch (S->getStmtClass()) {
1958 default:
1959 llvm_unreachable("Unhandled Stmt");
1960 case clang::Stmt::MSDependentExistsStmtClass:
1961 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1962 case Stmt::CXXDependentScopeMemberExprClass:
1963 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1964 case Stmt::DependentScopeDeclRefExprClass:
1965 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001966 case Stmt::OMPCriticalDirectiveClass:
1967 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001968 }
1969 }
1970};
1971class MemberRefVisit : public VisitorJob {
1972public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001974 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1975 L.getPtrEncoding()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 static bool classof(const VisitorJob *VJ) {
1977 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1978 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001979 const FieldDecl *get() const {
1980 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001981 }
1982 SourceLocation getLoc() const {
Michael Kruse7520cf02020-03-25 09:26:14 -05001983 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 }
1985};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001986class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001987 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001988 VisitorWorkList &WL;
1989 CXCursor Parent;
Michael Kruse7520cf02020-03-25 09:26:14 -05001990
Guy Benyei11169dd2012-12-18 14:30:41 +00001991public:
1992 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001993 : WL(wl), Parent(parent) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001994
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001995 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1996 void VisitBlockExpr(const BlockExpr *B);
1997 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1998 void VisitCompoundStmt(const CompoundStmt *S);
Michael Kruse7520cf02020-03-25 09:26:14 -05001999 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
2000 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002001 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
2002 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
2003 void VisitCXXNewExpr(const CXXNewExpr *E);
2004 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
2005 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
2006 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
2007 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
2008 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
2009 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
2010 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
2011 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002012 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002013 void VisitDeclRefExpr(const DeclRefExpr *D);
2014 void VisitDeclStmt(const DeclStmt *S);
2015 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
2016 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
2017 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
2018 void VisitForStmt(const ForStmt *FS);
2019 void VisitGotoStmt(const GotoStmt *GS);
2020 void VisitIfStmt(const IfStmt *If);
2021 void VisitInitListExpr(const InitListExpr *IE);
2022 void VisitMemberExpr(const MemberExpr *M);
2023 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2024 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2025 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2026 void VisitOverloadExpr(const OverloadExpr *E);
2027 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2028 void VisitStmt(const Stmt *S);
2029 void VisitSwitchStmt(const SwitchStmt *S);
2030 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002031 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2032 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2033 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2034 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2035 void VisitVAArgExpr(const VAArgExpr *E);
2036 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2037 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2038 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2039 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002040 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00002041 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002042 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002043 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002044 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00002045 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002046 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002047 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002048 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00002049 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002050 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002051 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002052 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
cchen47d60942019-12-05 13:43:48 -05002053 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002054 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002055 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00002056 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002057 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00002058 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002059 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002060 void
2061 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00002062 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00002063 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataevc112e942020-02-28 09:52:15 -05002064 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002065 void VisitOMPScanDirective(const OMPScanDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002066 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00002067 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002068 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00002069 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00002070 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00002071 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002072 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002073 void
2074 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00002075 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00002076 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002077 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Alexey Bataev60e51c42019-10-10 20:13:02 +00002078 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002079 void
2080 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002081 void VisitOMPParallelMasterTaskLoopDirective(
2082 const OMPParallelMasterTaskLoopDirective *D);
Alexey Bataev14a388f2019-10-25 10:27:13 -04002083 void VisitOMPParallelMasterTaskLoopSimdDirective(
2084 const OMPParallelMasterTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002085 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002086 void VisitOMPDistributeParallelForDirective(
2087 const OMPDistributeParallelForDirective *D);
Kelvin Li4a39add2016-07-05 05:00:15 +00002088 void VisitOMPDistributeParallelForSimdDirective(
2089 const OMPDistributeParallelForSimdDirective *D);
Kelvin Li787f3fc2016-07-06 04:45:38 +00002090 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
Kelvin Lia579b912016-07-14 02:54:56 +00002091 void VisitOMPTargetParallelForSimdDirective(
2092 const OMPTargetParallelForSimdDirective *D);
Kelvin Li986330c2016-07-20 22:57:10 +00002093 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
Kelvin Li02532872016-08-05 14:37:37 +00002094 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
Kelvin Li4e325f72016-10-25 12:50:55 +00002095 void VisitOMPTeamsDistributeSimdDirective(
2096 const OMPTeamsDistributeSimdDirective *D);
Kelvin Li579e41c2016-11-30 23:51:03 +00002097 void VisitOMPTeamsDistributeParallelForSimdDirective(
2098 const OMPTeamsDistributeParallelForSimdDirective *D);
Kelvin Li7ade93f2016-12-09 03:24:30 +00002099 void VisitOMPTeamsDistributeParallelForDirective(
2100 const OMPTeamsDistributeParallelForDirective *D);
Kelvin Libf594a52016-12-17 05:48:59 +00002101 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
Kelvin Li83c451e2016-12-25 04:52:54 +00002102 void VisitOMPTargetTeamsDistributeDirective(
2103 const OMPTargetTeamsDistributeDirective *D);
Kelvin Li80e8f562016-12-29 22:16:30 +00002104 void VisitOMPTargetTeamsDistributeParallelForDirective(
2105 const OMPTargetTeamsDistributeParallelForDirective *D);
Kelvin Li1851df52017-01-03 05:23:48 +00002106 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2107 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
Kelvin Lida681182017-01-10 18:08:18 +00002108 void VisitOMPTargetTeamsDistributeSimdDirective(
2109 const OMPTargetTeamsDistributeSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110
Guy Benyei11169dd2012-12-18 14:30:41 +00002111private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00002114 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2115 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2117 void AddStmt(const Stmt *S);
2118 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002121 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002122};
Michael Kruse7520cf02020-03-25 09:26:14 -05002123} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00002124
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 // 'S' should always be non-null, since it comes from the
2127 // statement we are visiting.
2128 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2129}
2130
Michael Kruse7520cf02020-03-25 09:26:14 -05002131void EnqueueVisitor::AddNestedNameSpecifierLoc(
2132 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 if (Qualifier)
2134 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2135}
2136
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 if (S)
2139 WL.push_back(StmtVisit(S, Parent));
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 if (D)
2143 WL.push_back(DeclVisit(D, Parent, isFirst));
2144}
James Y Knight04ec5bf2015-12-24 02:59:37 +00002145void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2146 unsigned NumTemplateArgs) {
2147 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 if (D)
2151 WL.push_back(MemberRefVisit(D, L, Parent));
2152}
2153void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2154 if (TI)
2155 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002156}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002157void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002158 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002159 for (const Stmt *SubStmt : S->children()) {
2160 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002161 }
2162 if (size == WL.size())
2163 return;
2164 // Now reverse the entries we just added. This will match the DFS
2165 // ordering performed by the worklist.
2166 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2167 std::reverse(I, E);
2168}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002169namespace {
2170class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2171 EnqueueVisitor *Visitor;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002172 /// Process clauses with list of variables.
Michael Kruse7520cf02020-03-25 09:26:14 -05002173 template <typename T> void VisitOMPClauseList(T *Node);
2174
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002175public:
Michael Kruse7520cf02020-03-25 09:26:14 -05002176 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
Johannes Doerfert419a5592020-03-30 19:58:40 -05002177#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2178#include "llvm/Frontend/OpenMP/OMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002179 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002180 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002181};
2182
Alexey Bataev3392d762016-02-16 11:18:12 +00002183void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2184 const OMPClauseWithPreInit *C) {
2185 Visitor->AddStmt(C->getPreInitStmt());
2186}
2187
Alexey Bataev005248a2016-02-25 05:25:57 +00002188void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2189 const OMPClauseWithPostUpdate *C) {
Alexey Bataev37e594c2016-03-04 07:21:16 +00002190 VisitOMPClauseWithPreInit(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002191 Visitor->AddStmt(C->getPostUpdateExpr());
2192}
2193
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002194void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00002195 VisitOMPClauseWithPreInit(C);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002196 Visitor->AddStmt(C->getCondition());
2197}
2198
Alexey Bataev3778b602014-07-17 07:32:53 +00002199void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2200 Visitor->AddStmt(C->getCondition());
2201}
2202
Alexey Bataev568a8332014-03-06 06:15:19 +00002203void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00002204 VisitOMPClauseWithPreInit(C);
Alexey Bataev568a8332014-03-06 06:15:19 +00002205 Visitor->AddStmt(C->getNumThreads());
2206}
2207
Alexey Bataev62c87d22014-03-21 04:51:18 +00002208void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2209 Visitor->AddStmt(C->getSafelen());
2210}
2211
Alexey Bataev66b15b52015-08-21 11:14:16 +00002212void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2213 Visitor->AddStmt(C->getSimdlen());
2214}
2215
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002216void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2217 Visitor->AddStmt(C->getAllocator());
2218}
2219
Alexander Musman8bd31e62014-05-27 15:12:19 +00002220void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2221 Visitor->AddStmt(C->getNumForLoops());
2222}
2223
Michael Kruse7520cf02020-03-25 09:26:14 -05002224void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
Alexey Bataev756c1962013-09-24 03:17:45 +00002225
Michael Kruse7520cf02020-03-25 09:26:14 -05002226void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002227
Alexey Bataev56dafe82014-06-20 07:16:17 +00002228void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002229 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002230 Visitor->AddStmt(C->getChunkSize());
2231}
2232
Alexey Bataev10e775f2015-07-30 11:36:16 +00002233void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2234 Visitor->AddStmt(C->getNumForLoops());
2235}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002236
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002237void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2238 Visitor->AddStmt(C->getEventHandler());
2239}
2240
Alexey Bataev236070f2014-06-20 11:19:47 +00002241void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2242
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002243void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2244
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002245void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2246
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002247void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2248
Alexey Bataevdea47612014-07-23 07:46:59 +00002249void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2250
Alexey Bataev67a4f222014-07-23 10:25:33 +00002251void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2252
Alexey Bataev459dec02014-07-24 06:46:57 +00002253void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2254
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002255void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2256
Alexey Bataevea9166b2020-02-06 16:30:23 -05002257void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2258
Alexey Bataev04a830f2020-02-10 14:30:39 -05002259void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2260
Alexey Bataev95598342020-02-10 15:49:05 -05002261void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2262
Alexey Bataev9a8defc2020-02-11 11:10:43 -05002263void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2264
Alexey Bataev346265e2015-09-25 10:37:12 +00002265void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2266
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002267void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2268
Alexey Bataevb825de12015-12-07 10:51:44 +00002269void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2270
Alexey Bataev375437a2020-03-02 14:21:20 -05002271void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {}
2272
Kelvin Li1408f912018-09-26 04:28:39 +00002273void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2274 const OMPUnifiedAddressClause *) {}
2275
Patrick Lyster4a370b92018-10-01 13:47:43 +00002276void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2277 const OMPUnifiedSharedMemoryClause *) {}
2278
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00002279void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2280 const OMPReverseOffloadClause *) {}
2281
Patrick Lyster3fe9e392018-10-11 14:41:10 +00002282void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2283 const OMPDynamicAllocatorsClause *) {}
2284
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002285void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2286 const OMPAtomicDefaultMemOrderClause *) {}
2287
Michael Wonge710d542015-08-07 16:16:36 +00002288void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2289 Visitor->AddStmt(C->getDevice());
2290}
2291
Kelvin Li099bb8c2015-11-24 20:50:12 +00002292void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00002293 VisitOMPClauseWithPreInit(C);
Kelvin Li099bb8c2015-11-24 20:50:12 +00002294 Visitor->AddStmt(C->getNumTeams());
2295}
2296
Michael Kruse7520cf02020-03-25 09:26:14 -05002297void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2298 const OMPThreadLimitClause *C) {
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00002299 VisitOMPClauseWithPreInit(C);
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002300 Visitor->AddStmt(C->getThreadLimit());
2301}
2302
Alexey Bataeva0569352015-12-01 10:17:31 +00002303void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2304 Visitor->AddStmt(C->getPriority());
2305}
2306
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002307void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2308 Visitor->AddStmt(C->getGrainsize());
2309}
2310
Alexey Bataev382967a2015-12-08 12:06:20 +00002311void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2312 Visitor->AddStmt(C->getNumTasks());
2313}
2314
Alexey Bataev28c75412015-12-15 08:19:24 +00002315void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2316 Visitor->AddStmt(C->getHint());
2317}
2318
Michael Kruse7520cf02020-03-25 09:26:14 -05002319template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002320 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002321 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002322 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002323}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002324
Alexey Bataev06dea732020-03-20 09:41:22 -04002325void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2326 VisitOMPClauseList(C);
2327}
Alexey Bataev63828a32020-03-23 10:41:08 -04002328void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2329 VisitOMPClauseList(C);
2330}
Alexey Bataeve04483e2019-03-27 14:14:31 +00002331void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2332 VisitOMPClauseList(C);
2333 Visitor->AddStmt(C->getAllocator());
2334}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002335void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002336 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002337 for (const auto *E : C->private_copies()) {
2338 Visitor->AddStmt(E);
2339 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002340}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002341void OMPClauseEnqueue::VisitOMPFirstprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002342 const OMPFirstprivateClause *C) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002343 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002344 VisitOMPClauseWithPreInit(C);
2345 for (const auto *E : C->private_copies()) {
2346 Visitor->AddStmt(E);
2347 }
2348 for (const auto *E : C->inits()) {
2349 Visitor->AddStmt(E);
2350 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002351}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002352void OMPClauseEnqueue::VisitOMPLastprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002353 const OMPLastprivateClause *C) {
Alexander Musman1bb328c2014-06-04 13:06:39 +00002354 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002355 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002356 for (auto *E : C->private_copies()) {
2357 Visitor->AddStmt(E);
2358 }
2359 for (auto *E : C->source_exprs()) {
2360 Visitor->AddStmt(E);
2361 }
2362 for (auto *E : C->destination_exprs()) {
2363 Visitor->AddStmt(E);
2364 }
2365 for (auto *E : C->assignment_ops()) {
2366 Visitor->AddStmt(E);
2367 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002368}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002369void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002370 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002371}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002372void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2373 VisitOMPClauseList(C);
Alexey Bataev61205072016-03-02 04:57:40 +00002374 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002375 for (auto *E : C->privates()) {
2376 Visitor->AddStmt(E);
2377 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002378 for (auto *E : C->lhs_exprs()) {
2379 Visitor->AddStmt(E);
2380 }
2381 for (auto *E : C->rhs_exprs()) {
2382 Visitor->AddStmt(E);
2383 }
2384 for (auto *E : C->reduction_ops()) {
2385 Visitor->AddStmt(E);
2386 }
Alexey Bataevbd1c03d2020-05-04 16:19:31 -04002387 if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
2388 for (auto *E : C->copy_ops()) {
2389 Visitor->AddStmt(E);
2390 }
2391 for (auto *E : C->copy_array_temps()) {
2392 Visitor->AddStmt(E);
2393 }
2394 for (auto *E : C->copy_array_elems()) {
2395 Visitor->AddStmt(E);
2396 }
2397 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002398}
Alexey Bataev169d96a2017-07-18 20:17:46 +00002399void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2400 const OMPTaskReductionClause *C) {
2401 VisitOMPClauseList(C);
2402 VisitOMPClauseWithPostUpdate(C);
2403 for (auto *E : C->privates()) {
2404 Visitor->AddStmt(E);
2405 }
2406 for (auto *E : C->lhs_exprs()) {
2407 Visitor->AddStmt(E);
2408 }
2409 for (auto *E : C->rhs_exprs()) {
2410 Visitor->AddStmt(E);
2411 }
2412 for (auto *E : C->reduction_ops()) {
2413 Visitor->AddStmt(E);
2414 }
2415}
Alexey Bataevfa312f32017-07-21 18:48:21 +00002416void OMPClauseEnqueue::VisitOMPInReductionClause(
2417 const OMPInReductionClause *C) {
2418 VisitOMPClauseList(C);
2419 VisitOMPClauseWithPostUpdate(C);
2420 for (auto *E : C->privates()) {
2421 Visitor->AddStmt(E);
2422 }
2423 for (auto *E : C->lhs_exprs()) {
2424 Visitor->AddStmt(E);
2425 }
2426 for (auto *E : C->rhs_exprs()) {
2427 Visitor->AddStmt(E);
2428 }
2429 for (auto *E : C->reduction_ops()) {
2430 Visitor->AddStmt(E);
2431 }
Alexey Bataev88202be2017-07-27 13:20:36 +00002432 for (auto *E : C->taskgroup_descriptors())
2433 Visitor->AddStmt(E);
Alexey Bataevfa312f32017-07-21 18:48:21 +00002434}
Alexander Musman8dba6642014-04-22 13:09:42 +00002435void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2436 VisitOMPClauseList(C);
Alexey Bataev78849fb2016-03-09 09:49:00 +00002437 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002438 for (const auto *E : C->privates()) {
2439 Visitor->AddStmt(E);
2440 }
Alexander Musman3276a272015-03-21 10:12:56 +00002441 for (const auto *E : C->inits()) {
2442 Visitor->AddStmt(E);
2443 }
2444 for (const auto *E : C->updates()) {
2445 Visitor->AddStmt(E);
2446 }
2447 for (const auto *E : C->finals()) {
2448 Visitor->AddStmt(E);
2449 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002450 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002451 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002452}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002453void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2454 VisitOMPClauseList(C);
2455 Visitor->AddStmt(C->getAlignment());
2456}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002457void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2458 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002459 for (auto *E : C->source_exprs()) {
2460 Visitor->AddStmt(E);
2461 }
2462 for (auto *E : C->destination_exprs()) {
2463 Visitor->AddStmt(E);
2464 }
2465 for (auto *E : C->assignment_ops()) {
2466 Visitor->AddStmt(E);
2467 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002468}
Michael Kruse7520cf02020-03-25 09:26:14 -05002469void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2470 const OMPCopyprivateClause *C) {
Alexey Bataevbae9a792014-06-27 10:37:06 +00002471 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002472 for (auto *E : C->source_exprs()) {
2473 Visitor->AddStmt(E);
2474 }
2475 for (auto *E : C->destination_exprs()) {
2476 Visitor->AddStmt(E);
2477 }
2478 for (auto *E : C->assignment_ops()) {
2479 Visitor->AddStmt(E);
2480 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002481}
Alexey Bataev6125da92014-07-21 11:26:11 +00002482void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2483 VisitOMPClauseList(C);
2484}
Alexey Bataevc112e942020-02-28 09:52:15 -05002485void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2486 Visitor->AddStmt(C->getDepobj());
2487}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002488void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2489 VisitOMPClauseList(C);
2490}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002491void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2492 VisitOMPClauseList(C);
2493}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002494void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2495 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002496 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002497 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002498}
Alexey Bataev3392d762016-02-16 11:18:12 +00002499void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2500 const OMPDefaultmapClause * /*C*/) {}
Samuel Antao661c0902016-05-26 17:39:58 +00002501void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2502 VisitOMPClauseList(C);
2503}
Samuel Antaoec172c62016-05-26 17:49:04 +00002504void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2505 VisitOMPClauseList(C);
2506}
Michael Kruse7520cf02020-03-25 09:26:14 -05002507void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2508 const OMPUseDevicePtrClause *C) {
Carlo Bertolli2404b172016-07-13 15:37:16 +00002509 VisitOMPClauseList(C);
2510}
Alexey Bataeva888fc62020-05-21 08:30:23 -04002511void OMPClauseEnqueue::VisitOMPUseDeviceAddrClause(
2512 const OMPUseDeviceAddrClause *C) {
2513 VisitOMPClauseList(C);
2514}
Michael Kruse7520cf02020-03-25 09:26:14 -05002515void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2516 const OMPIsDevicePtrClause *C) {
Carlo Bertolli70594e92016-07-13 17:16:49 +00002517 VisitOMPClauseList(C);
2518}
Alexey Bataevb6e70842019-12-16 15:54:17 -05002519void OMPClauseEnqueue::VisitOMPNontemporalClause(
2520 const OMPNontemporalClause *C) {
2521 VisitOMPClauseList(C);
Alexey Bataev0860db92019-12-19 10:01:10 -05002522 for (const auto *E : C->private_refs())
2523 Visitor->AddStmt(E);
Alexey Bataevb6e70842019-12-16 15:54:17 -05002524}
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002525void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
Alexey Bataevb5be1c52020-04-21 13:21:00 -04002526void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
2527 const OMPUsesAllocatorsClause *C) {
2528 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
2529 const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);
2530 Visitor->AddStmt(D.Allocator);
2531 Visitor->AddStmt(D.AllocatorTraits);
2532 }
2533}
Alexey Bataev2e499ee2020-05-18 13:37:53 -04002534void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) {
2535 Visitor->AddStmt(C->getModifier());
2536 for (const Expr *E : C->varlists())
2537 Visitor->AddStmt(E);
2538}
Michael Kruse7520cf02020-03-25 09:26:14 -05002539} // namespace
Alexey Bataev756c1962013-09-24 03:17:45 +00002540
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002541void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2542 unsigned size = WL.size();
2543 OMPClauseEnqueue Visitor(this);
2544 Visitor.Visit(S);
2545 if (size == WL.size())
2546 return;
2547 // Now reverse the entries we just added. This will match the DFS
2548 // ordering performed by the worklist.
2549 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2550 std::reverse(I, E);
2551}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002552void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002553 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2554}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002555void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002556 AddDecl(B->getBlockDecl());
2557}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002558void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002559 EnqueueChildren(E);
2560 AddTypeLoc(E->getTypeSourceInfo());
2561}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002562void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002563 for (auto &I : llvm::reverse(S->body()))
2564 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002565}
Michael Kruse7520cf02020-03-25 09:26:14 -05002566void EnqueueVisitor::VisitMSDependentExistsStmt(
2567 const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002568 AddStmt(S->getSubStmt());
2569 AddDeclarationNameInfo(S);
2570 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2571 AddNestedNameSpecifierLoc(QualifierLoc);
2572}
2573
Michael Kruse7520cf02020-03-25 09:26:14 -05002574void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2575 const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002576 if (E->hasExplicitTemplateArgs())
2577 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002578 AddDeclarationNameInfo(E);
2579 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2580 AddNestedNameSpecifierLoc(QualifierLoc);
2581 if (!E->isImplicitAccess())
2582 AddStmt(E->getBase());
2583}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002584void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002585 // Enqueue the initializer , if any.
2586 AddStmt(E->getInitializer());
2587 // Enqueue the array size, if any.
Richard Smithb9fb1212019-05-06 03:47:15 +00002588 AddStmt(E->getArraySize().getValueOr(nullptr));
Guy Benyei11169dd2012-12-18 14:30:41 +00002589 // Enqueue the allocated type.
2590 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2591 // Enqueue the placement arguments.
2592 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002593 AddStmt(E->getPlacementArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002594}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002595void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002596 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002597 AddStmt(CE->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002598 AddStmt(CE->getCallee());
2599 AddStmt(CE->getArg(0));
2600}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002601void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002602 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002603 // Visit the name of the type being destroyed.
2604 AddTypeLoc(E->getDestroyedTypeInfo());
2605 // Visit the scope type that looks disturbingly like the nested-name-specifier
2606 // but isn't.
2607 AddTypeLoc(E->getScopeTypeInfo());
2608 // Visit the nested-name-specifier.
2609 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2610 AddNestedNameSpecifierLoc(QualifierLoc);
2611 // Visit base expression.
2612 AddStmt(E->getBase());
2613}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002614void EnqueueVisitor::VisitCXXScalarValueInitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002615 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002616 AddTypeLoc(E->getTypeSourceInfo());
2617}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002618void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002619 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002620 EnqueueChildren(E);
2621 AddTypeLoc(E->getTypeSourceInfo());
2622}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002623void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002624 EnqueueChildren(E);
2625 if (E->isTypeOperand())
2626 AddTypeLoc(E->getTypeOperandSourceInfo());
2627}
2628
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002629void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002630 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002631 EnqueueChildren(E);
2632 AddTypeLoc(E->getTypeSourceInfo());
2633}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002634void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002635 EnqueueChildren(E);
2636 if (E->isTypeOperand())
2637 AddTypeLoc(E->getTypeOperandSourceInfo());
2638}
2639
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002640void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002641 EnqueueChildren(S);
2642 AddDecl(S->getExceptionDecl());
2643}
2644
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002645void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002646 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002647 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002648 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002649}
2650
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002651void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002652 if (DR->hasExplicitTemplateArgs())
2653 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002654 WL.push_back(DeclRefExprParts(DR, Parent));
2655}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002656void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002657 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002658 if (E->hasExplicitTemplateArgs())
2659 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002660 AddDeclarationNameInfo(E);
2661 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2662}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002663void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002664 unsigned size = WL.size();
2665 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002666 for (const auto *D : S->decls()) {
2667 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002668 isFirst = false;
2669 }
2670 if (size == WL.size())
2671 return;
2672 // Now reverse the entries we just added. This will match the DFS
2673 // ordering performed by the worklist.
2674 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2675 std::reverse(I, E);
2676}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002677void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002678 AddStmt(E->getInit());
David Majnemerf7e36092016-06-23 00:15:04 +00002679 for (const DesignatedInitExpr::Designator &D :
2680 llvm::reverse(E->designators())) {
2681 if (D.isFieldDesignator()) {
2682 if (FieldDecl *Field = D.getField())
2683 AddMemberRef(Field, D.getFieldLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00002684 continue;
2685 }
David Majnemerf7e36092016-06-23 00:15:04 +00002686 if (D.isArrayDesignator()) {
2687 AddStmt(E->getArrayIndex(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002688 continue;
2689 }
David Majnemerf7e36092016-06-23 00:15:04 +00002690 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2691 AddStmt(E->getArrayRangeEnd(D));
2692 AddStmt(E->getArrayRangeStart(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002693 }
2694}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002695void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002696 EnqueueChildren(E);
2697 AddTypeLoc(E->getTypeInfoAsWritten());
2698}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002699void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002700 AddStmt(FS->getBody());
2701 AddStmt(FS->getInc());
2702 AddStmt(FS->getCond());
2703 AddDecl(FS->getConditionVariable());
2704 AddStmt(FS->getInit());
2705}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002706void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002707 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2708}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002709void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002710 AddStmt(If->getElse());
2711 AddStmt(If->getThen());
2712 AddStmt(If->getCond());
Milian Wolff08e18122020-05-02 22:18:09 +02002713 AddStmt(If->getInit());
Guy Benyei11169dd2012-12-18 14:30:41 +00002714 AddDecl(If->getConditionVariable());
2715}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002716void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002717 // We care about the syntactic form of the initializer list, only.
2718 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2719 IE = Syntactic;
2720 EnqueueChildren(IE);
2721}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002722void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002723 WL.push_back(MemberExprParts(M, Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002724
Guy Benyei11169dd2012-12-18 14:30:41 +00002725 // If the base of the member access expression is an implicit 'this', don't
2726 // visit it.
2727 // FIXME: If we ever want to show these implicit accesses, this will be
2728 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002729 if (M->isImplicitAccess())
2730 return;
2731
2732 // Ignore base anonymous struct/union fields, otherwise they will shadow the
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00002733 // real field that we are interested in.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002734 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2735 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2736 if (FD->isAnonymousStructOrUnion()) {
2737 AddStmt(SubME->getBase());
2738 return;
2739 }
2740 }
2741 }
2742
2743 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002744}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002745void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002746 AddTypeLoc(E->getEncodedTypeSourceInfo());
2747}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002748void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002749 EnqueueChildren(M);
2750 AddTypeLoc(M->getClassReceiverTypeInfo());
2751}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002752void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002753 // Visit the components of the offsetof expression.
2754 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Michael Kruse7520cf02020-03-25 09:26:14 -05002755 const OffsetOfNode &Node = E->getComponent(I - 1);
Guy Benyei11169dd2012-12-18 14:30:41 +00002756 switch (Node.getKind()) {
2757 case OffsetOfNode::Array:
2758 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2759 break;
2760 case OffsetOfNode::Field:
2761 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2762 break;
2763 case OffsetOfNode::Identifier:
2764 case OffsetOfNode::Base:
2765 continue;
2766 }
2767 }
2768 // Visit the type into which we're computing the offset.
2769 AddTypeLoc(E->getTypeSourceInfo());
2770}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002771void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002772 if (E->hasExplicitTemplateArgs())
2773 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002774 WL.push_back(OverloadExprParts(E, Parent));
2775}
2776void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002777 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002778 EnqueueChildren(E);
2779 if (E->isArgumentType())
2780 AddTypeLoc(E->getArgumentTypeInfo());
2781}
Michael Kruse7520cf02020-03-25 09:26:14 -05002782void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002783void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002784 AddStmt(S->getBody());
2785 AddStmt(S->getCond());
2786 AddDecl(S->getConditionVariable());
2787}
2788
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002789void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002790 AddStmt(W->getBody());
2791 AddStmt(W->getCond());
2792 AddDecl(W->getConditionVariable());
2793}
2794
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002795void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002796 for (unsigned I = E->getNumArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002797 AddTypeLoc(E->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002798}
2799
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002800void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002801 AddTypeLoc(E->getQueriedTypeSourceInfo());
2802}
2803
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002804void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002805 EnqueueChildren(E);
2806}
2807
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002808void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002809 VisitOverloadExpr(U);
2810 if (!U->isImplicitAccess())
2811 AddStmt(U->getBase());
2812}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002813void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002814 AddStmt(E->getSubExpr());
2815 AddTypeLoc(E->getWrittenTypeInfo());
2816}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002817void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002818 WL.push_back(SizeOfPackExprParts(E, Parent));
2819}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002820void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002821 // If the opaque value has a source expression, just transparently
2822 // visit that. This is useful for (e.g.) pseudo-object expressions.
2823 if (Expr *SourceExpr = E->getSourceExpr())
2824 return Visit(SourceExpr);
2825}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002826void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002827 AddStmt(E->getBody());
2828 WL.push_back(LambdaExprParts(E, Parent));
2829}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002830void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002831 // Treat the expression like its syntactic form.
2832 Visit(E->getSyntacticForm());
2833}
2834
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002835void EnqueueVisitor::VisitOMPExecutableDirective(
Michael Kruse7520cf02020-03-25 09:26:14 -05002836 const OMPExecutableDirective *D) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002837 EnqueueChildren(D);
2838 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2839 E = D->clauses().end();
2840 I != E; ++I)
2841 EnqueueChildren(*I);
2842}
2843
Alexander Musman3aaab662014-08-19 11:27:13 +00002844void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2845 VisitOMPExecutableDirective(D);
2846}
2847
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002848void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2849 VisitOMPExecutableDirective(D);
2850}
2851
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002852void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002853 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002854}
2855
Alexey Bataevf29276e2014-06-18 04:14:57 +00002856void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002857 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002858}
2859
Alexander Musmanf82886e2014-09-18 05:12:34 +00002860void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2861 VisitOMPLoopDirective(D);
2862}
2863
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002864void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2865 VisitOMPExecutableDirective(D);
2866}
2867
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002868void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2869 VisitOMPExecutableDirective(D);
2870}
2871
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002872void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2873 VisitOMPExecutableDirective(D);
2874}
2875
Alexander Musman80c22892014-07-17 08:54:58 +00002876void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2877 VisitOMPExecutableDirective(D);
2878}
2879
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002880void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2881 VisitOMPExecutableDirective(D);
2882 AddDeclarationNameInfo(D);
2883}
2884
Michael Kruse7520cf02020-03-25 09:26:14 -05002885void EnqueueVisitor::VisitOMPParallelForDirective(
2886 const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002887 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002888}
2889
Alexander Musmane4e893b2014-09-23 09:33:00 +00002890void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2891 const OMPParallelForSimdDirective *D) {
2892 VisitOMPLoopDirective(D);
2893}
2894
cchen47d60942019-12-05 13:43:48 -05002895void EnqueueVisitor::VisitOMPParallelMasterDirective(
2896 const OMPParallelMasterDirective *D) {
2897 VisitOMPExecutableDirective(D);
2898}
2899
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002900void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2901 const OMPParallelSectionsDirective *D) {
2902 VisitOMPExecutableDirective(D);
2903}
2904
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002905void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2906 VisitOMPExecutableDirective(D);
2907}
2908
Michael Kruse7520cf02020-03-25 09:26:14 -05002909void EnqueueVisitor::VisitOMPTaskyieldDirective(
2910 const OMPTaskyieldDirective *D) {
Alexey Bataev68446b72014-07-18 07:47:19 +00002911 VisitOMPExecutableDirective(D);
2912}
2913
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002914void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2915 VisitOMPExecutableDirective(D);
2916}
2917
Alexey Bataev2df347a2014-07-18 10:17:07 +00002918void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2919 VisitOMPExecutableDirective(D);
2920}
2921
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002922void EnqueueVisitor::VisitOMPTaskgroupDirective(
2923 const OMPTaskgroupDirective *D) {
2924 VisitOMPExecutableDirective(D);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00002925 if (const Expr *E = D->getReductionRef())
2926 VisitStmt(E);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002927}
2928
Alexey Bataev6125da92014-07-21 11:26:11 +00002929void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2930 VisitOMPExecutableDirective(D);
2931}
2932
Alexey Bataevc112e942020-02-28 09:52:15 -05002933void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
2934 VisitOMPExecutableDirective(D);
2935}
2936
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002937void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
2938 VisitOMPExecutableDirective(D);
2939}
2940
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002941void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2942 VisitOMPExecutableDirective(D);
2943}
2944
Alexey Bataev0162e452014-07-22 10:10:35 +00002945void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2946 VisitOMPExecutableDirective(D);
2947}
2948
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002949void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2950 VisitOMPExecutableDirective(D);
2951}
2952
Alexey Bataevc112e942020-02-28 09:52:15 -05002953void EnqueueVisitor::VisitOMPTargetDataDirective(
2954 const OMPTargetDataDirective *D) {
Michael Wong65f367f2015-07-21 13:44:28 +00002955 VisitOMPExecutableDirective(D);
2956}
2957
Samuel Antaodf67fc42016-01-19 19:15:56 +00002958void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2959 const OMPTargetEnterDataDirective *D) {
2960 VisitOMPExecutableDirective(D);
2961}
2962
Samuel Antao72590762016-01-19 20:04:50 +00002963void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2964 const OMPTargetExitDataDirective *D) {
2965 VisitOMPExecutableDirective(D);
2966}
2967
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002968void EnqueueVisitor::VisitOMPTargetParallelDirective(
2969 const OMPTargetParallelDirective *D) {
2970 VisitOMPExecutableDirective(D);
2971}
2972
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002973void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2974 const OMPTargetParallelForDirective *D) {
2975 VisitOMPLoopDirective(D);
2976}
2977
Alexey Bataev13314bf2014-10-09 04:18:56 +00002978void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2979 VisitOMPExecutableDirective(D);
2980}
2981
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002982void EnqueueVisitor::VisitOMPCancellationPointDirective(
2983 const OMPCancellationPointDirective *D) {
2984 VisitOMPExecutableDirective(D);
2985}
2986
Alexey Bataev80909872015-07-02 11:25:17 +00002987void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2988 VisitOMPExecutableDirective(D);
2989}
2990
Alexey Bataev49f6e782015-12-01 04:18:41 +00002991void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2992 VisitOMPLoopDirective(D);
2993}
2994
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002995void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2996 const OMPTaskLoopSimdDirective *D) {
2997 VisitOMPLoopDirective(D);
2998}
2999
Alexey Bataev60e51c42019-10-10 20:13:02 +00003000void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
3001 const OMPMasterTaskLoopDirective *D) {
3002 VisitOMPLoopDirective(D);
3003}
3004
Alexey Bataevb8552ab2019-10-18 16:47:35 +00003005void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
3006 const OMPMasterTaskLoopSimdDirective *D) {
3007 VisitOMPLoopDirective(D);
3008}
3009
Alexey Bataev5bbcead2019-10-14 17:17:41 +00003010void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
3011 const OMPParallelMasterTaskLoopDirective *D) {
3012 VisitOMPLoopDirective(D);
3013}
3014
Alexey Bataev14a388f2019-10-25 10:27:13 -04003015void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
3016 const OMPParallelMasterTaskLoopSimdDirective *D) {
3017 VisitOMPLoopDirective(D);
3018}
3019
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003020void EnqueueVisitor::VisitOMPDistributeDirective(
3021 const OMPDistributeDirective *D) {
3022 VisitOMPLoopDirective(D);
3023}
3024
Carlo Bertolli9925f152016-06-27 14:55:37 +00003025void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
3026 const OMPDistributeParallelForDirective *D) {
3027 VisitOMPLoopDirective(D);
3028}
3029
Kelvin Li4a39add2016-07-05 05:00:15 +00003030void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
3031 const OMPDistributeParallelForSimdDirective *D) {
3032 VisitOMPLoopDirective(D);
3033}
3034
Kelvin Li787f3fc2016-07-06 04:45:38 +00003035void EnqueueVisitor::VisitOMPDistributeSimdDirective(
3036 const OMPDistributeSimdDirective *D) {
3037 VisitOMPLoopDirective(D);
3038}
3039
Kelvin Lia579b912016-07-14 02:54:56 +00003040void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
3041 const OMPTargetParallelForSimdDirective *D) {
3042 VisitOMPLoopDirective(D);
3043}
3044
Kelvin Li986330c2016-07-20 22:57:10 +00003045void EnqueueVisitor::VisitOMPTargetSimdDirective(
3046 const OMPTargetSimdDirective *D) {
3047 VisitOMPLoopDirective(D);
3048}
3049
Kelvin Li02532872016-08-05 14:37:37 +00003050void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3051 const OMPTeamsDistributeDirective *D) {
3052 VisitOMPLoopDirective(D);
3053}
3054
Kelvin Li4e325f72016-10-25 12:50:55 +00003055void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3056 const OMPTeamsDistributeSimdDirective *D) {
3057 VisitOMPLoopDirective(D);
3058}
3059
Kelvin Li579e41c2016-11-30 23:51:03 +00003060void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3061 const OMPTeamsDistributeParallelForSimdDirective *D) {
3062 VisitOMPLoopDirective(D);
3063}
3064
Kelvin Li7ade93f2016-12-09 03:24:30 +00003065void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3066 const OMPTeamsDistributeParallelForDirective *D) {
3067 VisitOMPLoopDirective(D);
3068}
3069
Kelvin Libf594a52016-12-17 05:48:59 +00003070void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3071 const OMPTargetTeamsDirective *D) {
3072 VisitOMPExecutableDirective(D);
3073}
3074
Kelvin Li83c451e2016-12-25 04:52:54 +00003075void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3076 const OMPTargetTeamsDistributeDirective *D) {
3077 VisitOMPLoopDirective(D);
3078}
3079
Kelvin Li80e8f562016-12-29 22:16:30 +00003080void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3081 const OMPTargetTeamsDistributeParallelForDirective *D) {
3082 VisitOMPLoopDirective(D);
3083}
3084
Kelvin Li1851df52017-01-03 05:23:48 +00003085void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3086 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3087 VisitOMPLoopDirective(D);
3088}
3089
Kelvin Lida681182017-01-10 18:08:18 +00003090void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3091 const OMPTargetTeamsDistributeSimdDirective *D) {
3092 VisitOMPLoopDirective(D);
3093}
3094
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003095void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003096 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3097 .Visit(S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003098}
3099
3100bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3101 if (RegionOfInterest.isValid()) {
3102 SourceRange Range = getRawCursorExtent(C);
3103 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3104 return false;
3105 }
3106 return true;
3107}
3108
3109bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3110 while (!WL.empty()) {
3111 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00003112 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00003113
3114 // Set the Parent field, then back to its old value once we're done.
3115 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
Michael Kruse7520cf02020-03-25 09:26:14 -05003116
Guy Benyei11169dd2012-12-18 14:30:41 +00003117 switch (LI.getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003118 case VisitorJob::DeclVisitKind: {
3119 const Decl *D = cast<DeclVisit>(&LI)->get();
3120 if (!D)
3121 continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00003122
Michael Kruse7520cf02020-03-25 09:26:14 -05003123 // For now, perform default visitation for Decls.
3124 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3125 cast<DeclVisit>(&LI)->isFirst())))
3126 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003127
Michael Kruse7520cf02020-03-25 09:26:14 -05003128 continue;
3129 }
3130 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3131 for (const TemplateArgumentLoc &Arg :
3132 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3133 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003135 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003136 continue;
3137 }
3138 case VisitorJob::TypeLocVisitKind: {
3139 // Perform default visitation for TypeLocs.
3140 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3141 return true;
3142 continue;
3143 }
3144 case VisitorJob::LabelRefVisitKind: {
3145 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3146 if (LabelStmt *stmt = LS->getStmt()) {
3147 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3148 TU))) {
3149 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003150 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003151 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003152 continue;
3153 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003154
Michael Kruse7520cf02020-03-25 09:26:14 -05003155 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3156 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3157 if (VisitNestedNameSpecifierLoc(V->get()))
3158 return true;
3159 continue;
3160 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003161
Michael Kruse7520cf02020-03-25 09:26:14 -05003162 case VisitorJob::DeclarationNameInfoVisitKind: {
3163 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3164 return true;
3165 continue;
3166 }
3167 case VisitorJob::MemberRefVisitKind: {
3168 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3169 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3170 return true;
3171 continue;
3172 }
3173 case VisitorJob::StmtVisitKind: {
3174 const Stmt *S = cast<StmtVisit>(&LI)->get();
3175 if (!S)
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 continue;
Richard Smithba71c082013-05-16 06:20:58 +00003177
Michael Kruse7520cf02020-03-25 09:26:14 -05003178 // Update the current cursor.
3179 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3180 if (!IsInRegionOfInterest(Cursor))
3181 continue;
3182 switch (Visitor(Cursor, Parent, ClientData)) {
3183 case CXChildVisit_Break:
3184 return true;
3185 case CXChildVisit_Continue:
3186 break;
3187 case CXChildVisit_Recurse:
3188 if (PostChildrenVisitor)
3189 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3190 EnqueueWorkList(WL, S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003191 break;
3192 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003193 continue;
3194 }
3195 case VisitorJob::MemberExprPartsKind: {
3196 // Handle the other pieces in the MemberExpr besides the base.
3197 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00003198
Michael Kruse7520cf02020-03-25 09:26:14 -05003199 // Visit the nested-name-specifier
3200 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3201 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05003203
3204 // Visit the declaration name.
3205 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3206 return true;
3207
3208 // Visit the explicitly-specified template arguments, if any.
3209 if (M->hasExplicitTemplateArgs()) {
3210 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3211 *ArgEnd = Arg + M->getNumTemplateArgs();
3212 Arg != ArgEnd; ++Arg) {
3213 if (VisitTemplateArgumentLoc(*Arg))
3214 return true;
3215 }
3216 }
3217 continue;
3218 }
3219 case VisitorJob::DeclRefExprPartsKind: {
3220 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3221 // Visit nested-name-specifier, if present.
3222 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3223 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3224 return true;
3225 // Visit declaration name.
3226 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3227 return true;
3228 continue;
3229 }
3230 case VisitorJob::OverloadExprPartsKind: {
3231 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3232 // Visit the nested-name-specifier.
3233 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3234 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3235 return true;
3236 // Visit the declaration name.
3237 if (VisitDeclarationNameInfo(O->getNameInfo()))
3238 return true;
3239 // Visit the overloaded declaration reference.
3240 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3241 return true;
3242 continue;
3243 }
3244 case VisitorJob::SizeOfPackExprPartsKind: {
3245 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3246 NamedDecl *Pack = E->getPack();
3247 if (isa<TemplateTypeParmDecl>(Pack)) {
3248 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3249 E->getPackLoc(), TU)))
3250 return true;
3251
3252 continue;
3253 }
3254
3255 if (isa<TemplateTemplateParmDecl>(Pack)) {
3256 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3257 E->getPackLoc(), TU)))
3258 return true;
3259
3260 continue;
3261 }
3262
3263 // Non-type template parameter packs and function parameter packs are
3264 // treated like DeclRefExpr cursors.
3265 continue;
3266 }
3267
3268 case VisitorJob::LambdaExprPartsKind: {
3269 // Visit non-init captures.
3270 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3271 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3272 CEnd = E->explicit_capture_end();
3273 C != CEnd; ++C) {
3274 if (!C->capturesVariable())
3275 continue;
3276
3277 if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
3278 TU)))
3279 return true;
3280 }
3281 // Visit init captures
3282 for (auto InitExpr : E->capture_inits()) {
Christian Kandeler6e089e92020-07-08 12:19:49 -07003283 if (InitExpr && Visit(InitExpr))
Michael Kruse7520cf02020-03-25 09:26:14 -05003284 return true;
3285 }
3286
3287 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3288 // Visit parameters and return type, if present.
3289 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3290 if (E->hasExplicitParameters()) {
3291 // Visit parameters.
3292 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3293 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3294 return true;
3295 }
3296 if (E->hasExplicitResultType()) {
3297 // Visit result type.
3298 if (Visit(Proto.getReturnLoc()))
3299 return true;
3300 }
3301 }
3302 break;
3303 }
3304
3305 case VisitorJob::PostChildrenVisitKind:
3306 if (PostChildrenVisitor(Parent, ClientData))
3307 return true;
3308 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 }
3310 }
3311 return false;
3312}
3313
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003314bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00003315 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 if (!WorkListFreeList.empty()) {
3317 WL = WorkListFreeList.back();
3318 WL->clear();
3319 WorkListFreeList.pop_back();
Michael Kruse7520cf02020-03-25 09:26:14 -05003320 } else {
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 WL = new VisitorWorkList();
3322 WorkListCache.push_back(WL);
3323 }
3324 EnqueueWorkList(*WL, S);
3325 bool result = RunVisitorWorkList(*WL);
3326 WorkListFreeList.push_back(WL);
3327 return result;
3328}
3329
3330namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003331typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00003332RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3333 const DeclarationNameInfo &NI, SourceRange QLoc,
3334 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3336 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3337 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
Michael Kruse7520cf02020-03-25 09:26:14 -05003338
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
Michael Kruse7520cf02020-03-25 09:26:14 -05003340
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 RefNamePieces Pieces;
3342
3343 if (WantQualifier && QLoc.isValid())
3344 Pieces.push_back(QLoc);
Michael Kruse7520cf02020-03-25 09:26:14 -05003345
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3347 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00003348
3349 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3350 Pieces.push_back(*TemplateArgsLoc);
3351
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 if (Kind == DeclarationName::CXXOperatorName) {
3353 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003354 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003356 NI.getInfo().CXXOperatorName.EndOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003358
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 if (WantSinglePiece) {
3360 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3361 Pieces.clear();
3362 Pieces.push_back(R);
Michael Kruse7520cf02020-03-25 09:26:14 -05003363 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003364
Michael Kruse7520cf02020-03-25 09:26:14 -05003365 return Pieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00003366}
Michael Kruse7520cf02020-03-25 09:26:14 -05003367} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00003368
3369//===----------------------------------------------------------------------===//
3370// Misc. API hooks.
Michael Kruse7520cf02020-03-25 09:26:14 -05003371//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00003372
Chandler Carruth66660742014-06-27 16:37:27 +00003373namespace {
3374struct RegisterFatalErrorHandler {
3375 RegisterFatalErrorHandler() {
Jan Korousf7d23762019-09-12 22:55:55 +00003376 clang_install_aborting_llvm_fatal_error_handler();
Chandler Carruth66660742014-06-27 16:37:27 +00003377 }
3378};
Michael Kruse7520cf02020-03-25 09:26:14 -05003379} // namespace
Chandler Carruth66660742014-06-27 16:37:27 +00003380
Michael Kruse7520cf02020-03-25 09:26:14 -05003381static llvm::ManagedStatic<RegisterFatalErrorHandler>
3382 RegisterFatalErrorHandlerOnce;
Chandler Carruth66660742014-06-27 16:37:27 +00003383
Guy Benyei11169dd2012-12-18 14:30:41 +00003384CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3385 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 // We use crash recovery to make some of our APIs more reliable, implicitly
3387 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003388 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3389 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003390
Chandler Carruth66660742014-06-27 16:37:27 +00003391 // Look through the managed static to trigger construction of the managed
3392 // static which registers our fatal error handler. This ensures it is only
3393 // registered once.
3394 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003395
Adrian Prantlbc068582015-07-08 01:00:30 +00003396 // Initialize targets for clang module support.
3397 llvm::InitializeAllTargets();
3398 llvm::InitializeAllTargetMCs();
3399 llvm::InitializeAllAsmPrinters();
3400 llvm::InitializeAllAsmParsers();
3401
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003402 CIndexer *CIdxr = new CIndexer();
3403
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 if (excludeDeclarationsFromPCH)
3405 CIdxr->setOnlyLocalDecls();
3406 if (displayDiagnostics)
3407 CIdxr->setDisplayDiagnostics();
3408
3409 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3410 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3411 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3412 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3413 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3414 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3415
3416 return CIdxr;
3417}
3418
3419void clang_disposeIndex(CXIndex CIdx) {
3420 if (CIdx)
3421 delete static_cast<CIndexer *>(CIdx);
3422}
3423
3424void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3425 if (CIdx)
3426 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3427}
3428
3429unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3430 if (CIdx)
3431 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3432 return 0;
3433}
3434
Alex Lorenz08615792017-12-04 21:56:36 +00003435void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
3436 const char *Path) {
3437 if (CIdx)
3438 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
3439}
3440
Guy Benyei11169dd2012-12-18 14:30:41 +00003441void clang_toggleCrashRecovery(unsigned isEnabled) {
3442 if (isEnabled)
3443 llvm::CrashRecoveryContext::Enable();
3444 else
3445 llvm::CrashRecoveryContext::Disable();
3446}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003447
Guy Benyei11169dd2012-12-18 14:30:41 +00003448CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3449 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003450 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003451 enum CXErrorCode Result =
3452 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003453 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003454 assert((TU && Result == CXError_Success) ||
3455 (!TU && Result != CXError_Success));
3456 return TU;
3457}
3458
3459enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3460 const char *ast_filename,
3461 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003462 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003463 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003464
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003465 if (!CIdx || !ast_filename || !out_TU)
3466 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003467
Michael Kruse7520cf02020-03-25 09:26:14 -05003468 LOG_FUNC_SECTION { *Log << ast_filename; }
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003469
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3471 FileSystemOptions FileSystemOpts;
3472
Justin Bognerd512c1e2014-10-15 00:33:06 +00003473 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3474 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003475 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Richard Smithdbafb6c2017-06-29 23:23:46 +00003476 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
Michael Kruse7520cf02020-03-25 09:26:14 -05003477 ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3478 CXXIdx->getOnlyLocalDecls(), None, CaptureDiagsKind::All,
David Blaikie6f7382d2014-08-10 19:08:04 +00003479 /*AllowPCHWithCompilerErrors=*/true,
3480 /*UserFilesAreVolatile=*/true);
David Blaikieea4395e2017-01-06 19:49:01 +00003481 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003482 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003483}
3484
3485unsigned clang_defaultEditingTranslationUnitOptions() {
Michael Kruse7520cf02020-03-25 09:26:14 -05003486 return CXTranslationUnit_PrecompiledPreamble |
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 CXTranslationUnit_CacheCompletionResults;
3488}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003489
Michael Kruse7520cf02020-03-25 09:26:14 -05003490CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3491 CXIndex CIdx, const char *source_filename, int num_command_line_args,
3492 const char *const *command_line_args, unsigned num_unsaved_files,
3493 struct CXUnsavedFile *unsaved_files) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
Michael Kruse7520cf02020-03-25 09:26:14 -05003495 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3496 num_command_line_args, unsaved_files,
3497 num_unsaved_files, Options);
Guy Benyei11169dd2012-12-18 14:30:41 +00003498}
3499
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003500static CXErrorCode
3501clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3502 const char *const *command_line_args,
3503 int num_command_line_args,
3504 ArrayRef<CXUnsavedFile> unsaved_files,
3505 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003506 // Set up the initial return values.
3507 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003508 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003509
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003510 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003511 if (!CIdx || !out_TU)
3512 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003513
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3515
3516 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3517 setThreadBackgroundPriority();
3518
3519 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003520 bool CreatePreambleOnFirstParse =
3521 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003522 // FIXME: Add a flag for modules.
Michael Kruse7520cf02020-03-25 09:26:14 -05003523 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3524 CXTranslationUnit_SingleFileParse))
3525 ? TU_Prefix
3526 : TU_Complete;
3527 bool CacheCodeCompletionResults =
3528 options & CXTranslationUnit_CacheCompletionResults;
3529 bool IncludeBriefCommentsInCodeCompletion =
3530 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003531 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
3532 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
Michael Kruse7520cf02020-03-25 09:26:14 -05003533 bool RetainExcludedCB =
3534 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
Ivan Donchevskii6e895282018-05-17 09:24:37 +00003535 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
3536 if (options & CXTranslationUnit_SkipFunctionBodies) {
3537 SkipFunctionBodies =
3538 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
3539 ? SkipFunctionBodiesScope::Preamble
3540 : SkipFunctionBodiesScope::PreambleAndMainFile;
3541 }
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003542
3543 // Configure the diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05003544 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3545 CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003546
Manuel Klimek016c0242016-03-01 10:56:19 +00003547 if (options & CXTranslationUnit_KeepGoing)
Ivan Donchevskii878271b2019-03-07 10:13:50 +00003548 Diags->setFatalsAsError(true);
Manuel Klimek016c0242016-03-01 10:56:19 +00003549
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003550 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
3551 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
3552 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
3553
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003555 llvm::CrashRecoveryContextCleanupRegistrar<
3556 DiagnosticsEngine,
3557 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
3558 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003559
Ahmed Charlesb8984322014-03-07 20:03:18 +00003560 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3561 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003562
3563 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003564 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3565 RemappedCleanup(RemappedFiles.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003566
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003567 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003568 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003569 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003570 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 }
3572
Ahmed Charlesb8984322014-03-07 20:03:18 +00003573 std::unique_ptr<std::vector<const char *>> Args(
3574 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003575
3576 // Recover resources if we crash before exiting this method.
Michael Kruse7520cf02020-03-25 09:26:14 -05003577 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
3578 ArgsCleanup(Args.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003579
3580 // Since the Clang C library is primarily used by batch tools dealing with
3581 // (often very broken) source code, where spell-checking can have a
Michael Kruse7520cf02020-03-25 09:26:14 -05003582 // significant negative impact on performance (particularly when
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 // precompiled headers are involved), we disable it by default.
3584 // Only do this if we haven't found a spell-checking-related argument.
3585 bool FoundSpellCheckingArgument = false;
3586 for (int I = 0; I != num_command_line_args; ++I) {
3587 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3588 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3589 FoundSpellCheckingArgument = true;
3590 break;
3591 }
3592 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 Args->insert(Args->end(), command_line_args,
3594 command_line_args + num_command_line_args);
3595
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003596 if (!FoundSpellCheckingArgument)
3597 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3598
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 // The 'source_filename' argument is optional. If the caller does not
3600 // specify it then it is assumed that the source file is specified
3601 // in the actual argument list.
3602 // Put the source file after command_line_args otherwise if '-x' flag is
3603 // present it will be unused.
3604 if (source_filename)
3605 Args->push_back(source_filename);
3606
3607 // Do we need the detailed preprocessing record?
3608 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3609 Args->push_back("-Xclang");
3610 Args->push_back("-detailed-preprocessing-record");
3611 }
Alex Lorenzcb006402017-04-27 13:47:03 +00003612
3613 // Suppress any editor placeholder diagnostics.
3614 Args->push_back("-fallow-editor-placeholders");
3615
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003617 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003618 // Unless the user specified that they want the preamble on the first parse
3619 // set it up to be created on the first reparse. This makes the first parse
3620 // faster, trading for a slower (first) reparse.
3621 unsigned PrecompilePreambleAfterNParses =
3622 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Alex Lorenz08615792017-12-04 21:56:36 +00003623
Alex Lorenz08615792017-12-04 21:56:36 +00003624 LibclangInvocationReporter InvocationReporter(
3625 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
Alex Lorenz690f0e22017-12-07 20:37:50 +00003626 options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
3627 unsaved_files);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003628 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003629 Args->data(), Args->data() + Args->size(),
3630 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003631 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003632 CaptureDiagnostics, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003633 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3634 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Argyrios Kyrtzidis735e92c2017-06-09 01:20:48 +00003635 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
Evgeny Mankov2ed2e622019-08-27 22:15:32 +00003636 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003637 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3638 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003639
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003640 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003641 if (!Unit && !ErrUnit)
3642 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003643
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 if (NumErrors != Diags->getClient()->getNumErrors()) {
3645 // Make sure to check that 'Unit' is non-NULL.
3646 if (CXXIdx->getDisplayDiagnostics())
3647 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3648 }
3649
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003650 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3651 return CXError_ASTReadError;
3652
David Blaikieea4395e2017-01-06 19:49:01 +00003653 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
Alex Lorenz690f0e22017-12-07 20:37:50 +00003654 if (CXTranslationUnitImpl *TU = *out_TU) {
3655 TU->ParsingOptions = options;
3656 TU->Arguments.reserve(Args->size());
3657 for (const char *Arg : *Args)
3658 TU->Arguments.push_back(Arg);
3659 return CXError_Success;
3660 }
3661 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003662}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003663
3664CXTranslationUnit
Michael Kruse7520cf02020-03-25 09:26:14 -05003665clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003666 const char *const *command_line_args,
3667 int num_command_line_args,
3668 struct CXUnsavedFile *unsaved_files,
Michael Kruse7520cf02020-03-25 09:26:14 -05003669 unsigned num_unsaved_files, unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003670 CXTranslationUnit TU;
3671 enum CXErrorCode Result = clang_parseTranslationUnit2(
3672 CIdx, source_filename, command_line_args, num_command_line_args,
3673 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003674 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003675 assert((TU && Result == CXError_Success) ||
3676 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003677 return TU;
3678}
3679
3680enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003681 CXIndex CIdx, const char *source_filename,
3682 const char *const *command_line_args, int num_command_line_args,
3683 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3684 unsigned options, CXTranslationUnit *out_TU) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003685 noteBottomOfStack();
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003686 SmallVector<const char *, 4> Args;
3687 Args.push_back("clang");
3688 Args.append(command_line_args, command_line_args + num_command_line_args);
3689 return clang_parseTranslationUnit2FullArgv(
3690 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3691 num_unsaved_files, options, out_TU);
3692}
3693
3694enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3695 CXIndex CIdx, const char *source_filename,
3696 const char *const *command_line_args, int num_command_line_args,
3697 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3698 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003699 LOG_FUNC_SECTION {
3700 *Log << source_filename << ": ";
3701 for (int i = 0; i != num_command_line_args; ++i)
3702 *Log << command_line_args[i] << " ";
3703 }
3704
Alp Toker9d85b182014-07-07 01:23:14 +00003705 if (num_unsaved_files && !unsaved_files)
3706 return CXError_InvalidArguments;
3707
Alp Toker5c532982014-07-07 22:42:03 +00003708 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003709 auto ParseTranslationUnitImpl = [=, &result] {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003710 noteBottomOfStack();
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003711 result = clang_parseTranslationUnit_Impl(
3712 CIdx, source_filename, command_line_args, num_command_line_args,
3713 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3714 };
Erik Verbruggen284848d2017-08-29 09:08:02 +00003715
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 llvm::CrashRecoveryContext CRC;
3717
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003718 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3720 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3721 fprintf(stderr, " 'command_line_args' : [");
3722 for (int i = 0; i != num_command_line_args; ++i) {
3723 if (i)
3724 fprintf(stderr, ", ");
3725 fprintf(stderr, "'%s'", command_line_args[i]);
3726 }
3727 fprintf(stderr, "],\n");
3728 fprintf(stderr, " 'unsaved_files' : [");
3729 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3730 if (i)
3731 fprintf(stderr, ", ");
3732 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3733 unsaved_files[i].Length);
3734 }
3735 fprintf(stderr, "],\n");
3736 fprintf(stderr, " 'options' : %d,\n", options);
3737 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003738
3739 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003741 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003742 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 }
Alp Toker5c532982014-07-07 22:42:03 +00003744
3745 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003746}
3747
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003748CXString clang_Type_getObjCEncoding(CXType CT) {
3749 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3750 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3751 std::string encoding;
Michael Kruse7520cf02020-03-25 09:26:14 -05003752 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003753
3754 return cxstring::createDup(encoding);
3755}
3756
3757static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3758 if (C.kind == CXCursor_MacroDefinition) {
3759 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3760 return MDR->getName();
3761 } else if (C.kind == CXCursor_MacroExpansion) {
3762 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3763 return ME.getName();
3764 }
3765 return nullptr;
3766}
3767
3768unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3769 const IdentifierInfo *II = getMacroIdentifier(C);
3770 if (!II) {
3771 return false;
3772 }
3773 ASTUnit *ASTU = getCursorASTUnit(C);
3774 Preprocessor &PP = ASTU->getPreprocessor();
3775 if (const MacroInfo *MI = PP.getMacroInfo(II))
3776 return MI->isFunctionLike();
3777 return false;
3778}
3779
3780unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3781 const IdentifierInfo *II = getMacroIdentifier(C);
3782 if (!II) {
3783 return false;
3784 }
3785 ASTUnit *ASTU = getCursorASTUnit(C);
3786 Preprocessor &PP = ASTU->getPreprocessor();
3787 if (const MacroInfo *MI = PP.getMacroInfo(II))
3788 return MI->isBuiltinMacro();
3789 return false;
3790}
3791
3792unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3793 const Decl *D = getCursorDecl(C);
3794 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3795 if (!FD) {
3796 return false;
3797 }
3798 return FD->isInlined();
3799}
3800
Michael Kruse7520cf02020-03-25 09:26:14 -05003801static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003802 if (callExpr->getNumArgs() != 1) {
3803 return nullptr;
3804 }
3805
3806 StringLiteral *S = nullptr;
3807 auto *arg = callExpr->getArg(0);
3808 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3809 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3810 auto *subExpr = I->getSubExprAsWritten();
3811
Michael Kruse7520cf02020-03-25 09:26:14 -05003812 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003813 return nullptr;
3814 }
3815
3816 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3817 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3818 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3819 } else {
3820 return nullptr;
3821 }
3822 return S;
3823}
3824
David Blaikie59272572016-04-13 18:23:33 +00003825struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003826 CXEvalResultKind EvalType;
3827 union {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003828 unsigned long long unsignedVal;
3829 long long intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003830 double floatVal;
3831 char *stringVal;
3832 } EvalData;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003833 bool IsUnsignedInt;
David Blaikie59272572016-04-13 18:23:33 +00003834 ~ExprEvalResult() {
3835 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3836 EvalType != CXEval_Int) {
Alex Lorenza19cb2e2019-01-08 23:28:37 +00003837 delete[] EvalData.stringVal;
David Blaikie59272572016-04-13 18:23:33 +00003838 }
3839 }
3840};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003841
3842void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003843 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003844}
3845
3846CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3847 if (!E) {
3848 return CXEval_UnExposed;
3849 }
3850 return ((ExprEvalResult *)E)->EvalType;
3851}
3852
3853int clang_EvalResult_getAsInt(CXEvalResult E) {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003854 return clang_EvalResult_getAsLongLong(E);
3855}
3856
3857long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003858 if (!E) {
3859 return 0;
3860 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003861 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003862 if (Result->IsUnsignedInt)
3863 return Result->EvalData.unsignedVal;
3864 return Result->EvalData.intVal;
3865}
3866
3867unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
3868 return ((ExprEvalResult *)E)->IsUnsignedInt;
3869}
3870
3871unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
3872 if (!E) {
3873 return 0;
3874 }
3875
Michael Kruse7520cf02020-03-25 09:26:14 -05003876 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003877 if (Result->IsUnsignedInt)
3878 return Result->EvalData.unsignedVal;
3879 return Result->EvalData.intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003880}
3881
3882double clang_EvalResult_getAsDouble(CXEvalResult E) {
3883 if (!E) {
3884 return 0;
3885 }
3886 return ((ExprEvalResult *)E)->EvalData.floatVal;
3887}
3888
Michael Kruse7520cf02020-03-25 09:26:14 -05003889const char *clang_EvalResult_getAsStr(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003890 if (!E) {
3891 return nullptr;
3892 }
3893 return ((ExprEvalResult *)E)->EvalData.stringVal;
3894}
3895
Michael Kruse7520cf02020-03-25 09:26:14 -05003896static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003897 Expr::EvalResult ER;
3898 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003899 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003900 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003901
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003902 expr = expr->IgnoreParens();
Emilio Cobos Alvarez74375452019-07-09 14:27:01 +00003903 if (expr->isValueDependent())
3904 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003905 if (!expr->EvaluateAsRValue(ER, ctx))
3906 return nullptr;
3907
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003908 QualType rettype;
3909 CallExpr *callExpr;
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00003910 auto result = std::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003911 result->EvalType = CXEval_UnExposed;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003912 result->IsUnsignedInt = false;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003913
David Blaikiebbc00882016-04-13 18:36:19 +00003914 if (ER.Val.isInt()) {
3915 result->EvalType = CXEval_Int;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003916
Michael Kruse7520cf02020-03-25 09:26:14 -05003917 auto &val = ER.Val.getInt();
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003918 if (val.isUnsigned()) {
3919 result->IsUnsignedInt = true;
3920 result->EvalData.unsignedVal = val.getZExtValue();
3921 } else {
3922 result->EvalData.intVal = val.getExtValue();
3923 }
3924
David Blaikiebbc00882016-04-13 18:36:19 +00003925 return result.release();
3926 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003927
David Blaikiebbc00882016-04-13 18:36:19 +00003928 if (ER.Val.isFloat()) {
3929 llvm::SmallVector<char, 100> Buffer;
3930 ER.Val.getFloat().toString(Buffer);
3931 std::string floatStr(Buffer.data(), Buffer.size());
3932 result->EvalType = CXEval_Float;
3933 bool ignored;
3934 llvm::APFloat apFloat = ER.Val.getFloat();
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003935 apFloat.convert(llvm::APFloat::IEEEdouble(),
David Blaikiebbc00882016-04-13 18:36:19 +00003936 llvm::APFloat::rmNearestTiesToEven, &ignored);
3937 result->EvalData.floatVal = apFloat.convertToDouble();
3938 return result.release();
3939 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003940
David Blaikiebbc00882016-04-13 18:36:19 +00003941 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3942 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3943 auto *subExpr = I->getSubExprAsWritten();
3944 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3945 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003946 const StringLiteral *StrE = nullptr;
3947 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003948 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003949
3950 if (ObjCExpr) {
3951 StrE = ObjCExpr->getString();
3952 result->EvalType = CXEval_ObjCStrLiteral;
3953 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003954 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003955 result->EvalType = CXEval_StrLiteral;
3956 }
3957
3958 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003959 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003960 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3961 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003962 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003963 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003964 }
3965 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3966 expr->getStmtClass() == Stmt::StringLiteralClass) {
3967 const StringLiteral *StrE = nullptr;
3968 const ObjCStringLiteral *ObjCExpr;
3969 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003970
David Blaikiebbc00882016-04-13 18:36:19 +00003971 if (ObjCExpr) {
3972 StrE = ObjCExpr->getString();
3973 result->EvalType = CXEval_ObjCStrLiteral;
3974 } else {
3975 StrE = cast<StringLiteral>(expr);
3976 result->EvalType = CXEval_StrLiteral;
3977 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003978
David Blaikiebbc00882016-04-13 18:36:19 +00003979 std::string strRef(StrE->getString().str());
3980 result->EvalData.stringVal = new char[strRef.size() + 1];
3981 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3982 result->EvalData.stringVal[strRef.size()] = '\0';
3983 return result.release();
3984 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003985
David Blaikiebbc00882016-04-13 18:36:19 +00003986 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3987 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003988
David Blaikiebbc00882016-04-13 18:36:19 +00003989 rettype = CC->getType();
3990 if (rettype.getAsString() == "CFStringRef" &&
3991 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003992
David Blaikiebbc00882016-04-13 18:36:19 +00003993 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3994 StringLiteral *S = getCFSTR_value(callExpr);
3995 if (S) {
3996 std::string strLiteral(S->getString().str());
3997 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003998
David Blaikiebbc00882016-04-13 18:36:19 +00003999 result->EvalData.stringVal = new char[strLiteral.size() + 1];
4000 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
4001 strLiteral.size());
4002 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00004003 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004004 }
4005 }
4006
David Blaikiebbc00882016-04-13 18:36:19 +00004007 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
4008 callExpr = static_cast<CallExpr *>(expr);
4009 rettype = callExpr->getCallReturnType(ctx);
4010
4011 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
4012 return nullptr;
4013
4014 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
4015 if (callExpr->getNumArgs() == 1 &&
4016 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
4017 return nullptr;
4018 } else if (rettype.getAsString() == "CFStringRef") {
4019
4020 StringLiteral *S = getCFSTR_value(callExpr);
4021 if (S) {
4022 std::string strLiteral(S->getString().str());
4023 result->EvalType = CXEval_CFStr;
4024 result->EvalData.stringVal = new char[strLiteral.size() + 1];
4025 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
4026 strLiteral.size());
4027 result->EvalData.stringVal[strLiteral.size()] = '\0';
4028 return result.release();
4029 }
4030 }
4031 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
4032 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
4033 ValueDecl *V = D->getDecl();
4034 if (V->getKind() == Decl::Function) {
4035 std::string strName = V->getNameAsString();
4036 result->EvalType = CXEval_Other;
4037 result->EvalData.stringVal = new char[strName.size() + 1];
4038 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
4039 result->EvalData.stringVal[strName.size()] = '\0';
4040 return result.release();
4041 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004042 }
4043
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004044 return nullptr;
4045}
4046
Alex Lorenz65317e12019-01-08 22:32:51 +00004047static const Expr *evaluateDeclExpr(const Decl *D) {
4048 if (!D)
Evgeniy Stepanov9b871492018-07-10 19:48:53 +00004049 return nullptr;
Alex Lorenz65317e12019-01-08 22:32:51 +00004050 if (auto *Var = dyn_cast<VarDecl>(D))
4051 return Var->getInit();
4052 else if (auto *Field = dyn_cast<FieldDecl>(D))
4053 return Field->getInClassInitializer();
4054 return nullptr;
4055}
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004056
Alex Lorenz65317e12019-01-08 22:32:51 +00004057static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4058 assert(CS && "invalid compound statement");
4059 for (auto *bodyIterator : CS->body()) {
4060 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4061 return E;
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004062 }
Alex Lorenzc4cf96e2018-07-09 19:56:45 +00004063 return nullptr;
4064}
4065
Alex Lorenz65317e12019-01-08 22:32:51 +00004066CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
Christian Kandeler72131422020-06-24 11:56:45 +01004067 const Expr *E = nullptr;
4068 if (clang_getCursorKind(C) == CXCursor_CompoundStmt)
4069 E = evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)));
4070 else if (clang_isDeclaration(C.kind))
4071 E = evaluateDeclExpr(getCursorDecl(C));
4072 else if (clang_isExpression(C.kind))
4073 E = getCursorExpr(C);
4074 if (E)
Alex Lorenz65317e12019-01-08 22:32:51 +00004075 return const_cast<CXEvalResult>(
4076 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4077 return nullptr;
4078}
4079
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004080unsigned clang_Cursor_hasAttrs(CXCursor C) {
4081 const Decl *D = getCursorDecl(C);
4082 if (!D) {
4083 return 0;
4084 }
4085
4086 if (D->hasAttrs()) {
4087 return 1;
4088 }
4089
4090 return 0;
4091}
Guy Benyei11169dd2012-12-18 14:30:41 +00004092unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4093 return CXSaveTranslationUnit_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05004094}
Guy Benyei11169dd2012-12-18 14:30:41 +00004095
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004096static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4097 const char *FileName,
4098 unsigned options) {
4099 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4101 setThreadBackgroundPriority();
4102
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004103 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4104 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00004105}
4106
4107int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4108 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004109 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004110
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004111 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004112 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004114 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004115
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004116 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4118 if (!CXXUnit->hasSema())
4119 return CXSaveError_InvalidTU;
4120
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004121 CXSaveError result;
4122 auto SaveTranslationUnitImpl = [=, &result]() {
4123 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4124 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004125
Erik Verbruggen3cc39112017-11-14 09:34:39 +00004126 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004127 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00004128
4129 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4130 PrintLibclangResourceUsage(TU);
4131
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004132 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 }
4134
4135 // We have an AST that has invalid nodes due to compiler errors.
4136 // Use a crash recovery thread for protection.
4137
4138 llvm::CrashRecoveryContext CRC;
4139
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004140 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4142 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4143 fprintf(stderr, " 'options' : %d,\n", options);
4144 fprintf(stderr, "}\n");
4145
4146 return CXSaveError_Unknown;
4147
4148 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4149 PrintLibclangResourceUsage(TU);
4150 }
4151
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004152 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004153}
4154
4155void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4156 if (CTUnit) {
4157 // If the translation unit has been marked as unsafe to free, just discard
4158 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004159 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4160 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 return;
4162
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004163 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00004164 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4166 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00004167 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00004168 delete CTUnit;
4169 }
4170}
4171
Erik Verbruggen346066b2017-05-30 14:25:54 +00004172unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4173 if (CTUnit) {
4174 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4175
4176 if (Unit && Unit->isUnsafeToFree())
4177 return false;
4178
4179 Unit->ResetForParse();
4180 return true;
4181 }
4182
4183 return false;
4184}
4185
Guy Benyei11169dd2012-12-18 14:30:41 +00004186unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4187 return CXReparse_None;
4188}
4189
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004190static CXErrorCode
4191clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4192 ArrayRef<CXUnsavedFile> unsaved_files,
4193 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004194 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004195 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004196 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004197 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004198 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004199
4200 // Reset the associated diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05004201 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00004202 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004203
Dmitri Gribenko183436e2013-01-26 21:49:50 +00004204 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4206 setThreadBackgroundPriority();
4207
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004208 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00004210
4211 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4212 new std::vector<ASTUnit::RemappedFile>());
4213
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05004215 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4216 RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00004217
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004218 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004219 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00004220 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004221 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004223
Adrian Prantlbb165fb2015-06-20 18:53:08 +00004224 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4225 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004226 return CXError_Success;
4227 if (isASTReadError(CXXUnit))
4228 return CXError_ASTReadError;
4229 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00004230}
4231
4232int clang_reparseTranslationUnit(CXTranslationUnit TU,
4233 unsigned num_unsaved_files,
4234 struct CXUnsavedFile *unsaved_files,
4235 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004236 LOG_FUNC_SECTION { *Log << TU; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004237
Alp Toker9d85b182014-07-07 01:23:14 +00004238 if (num_unsaved_files && !unsaved_files)
4239 return CXError_InvalidArguments;
4240
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004241 CXErrorCode result;
4242 auto ReparseTranslationUnitImpl = [=, &result]() {
4243 result = clang_reparseTranslationUnit_Impl(
4244 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
4245 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004246
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 llvm::CrashRecoveryContext CRC;
4248
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004249 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004251 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004252 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00004253 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4254 PrintLibclangResourceUsage(TU);
4255
Alp Toker5c532982014-07-07 22:42:03 +00004256 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004257}
4258
Guy Benyei11169dd2012-12-18 14:30:41 +00004259CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004260 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004261 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004262 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004263 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004264
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004265 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004266 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004267}
4268
4269CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004270 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004271 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004272 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004273 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004274
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004275 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4277}
4278
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004279CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4280 if (isNotUsableTU(CTUnit)) {
4281 LOG_BAD_TU(CTUnit);
4282 return nullptr;
4283 }
4284
Michael Kruse7520cf02020-03-25 09:26:14 -05004285 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004286 impl->TranslationUnit = CTUnit;
4287 return impl;
4288}
4289
4290CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4291 if (!TargetInfo)
4292 return cxstring::createEmpty();
4293
4294 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4295 assert(!isNotUsableTU(CTUnit) &&
4296 "Unexpected unusable translation unit in TargetInfo");
4297
4298 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4299 std::string Triple =
Michael Kruse7520cf02020-03-25 09:26:14 -05004300 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004301 return cxstring::createDup(Triple);
4302}
4303
4304int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4305 if (!TargetInfo)
4306 return -1;
4307
4308 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4309 assert(!isNotUsableTU(CTUnit) &&
4310 "Unexpected unusable translation unit in TargetInfo");
4311
4312 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4313 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4314}
4315
4316void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4317 if (!TargetInfo)
4318 return;
4319
4320 delete TargetInfo;
4321}
4322
Guy Benyei11169dd2012-12-18 14:30:41 +00004323//===----------------------------------------------------------------------===//
4324// CXFile Operations.
4325//===----------------------------------------------------------------------===//
4326
Guy Benyei11169dd2012-12-18 14:30:41 +00004327CXString clang_getFileName(CXFile SFile) {
4328 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00004329 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00004330
4331 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004332 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004333}
4334
4335time_t clang_getFileTime(CXFile SFile) {
4336 if (!SFile)
4337 return 0;
4338
4339 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4340 return FEnt->getModificationTime();
4341}
4342
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004343CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004344 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004345 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00004346 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004347 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004348
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004349 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004350
4351 FileManager &FMgr = CXXUnit->getFileManager();
Harlan Haskins8d323d12019-08-01 21:31:56 +00004352 auto File = FMgr.getFile(file_name);
4353 if (!File)
4354 return nullptr;
4355 return const_cast<FileEntry *>(*File);
Guy Benyei11169dd2012-12-18 14:30:41 +00004356}
4357
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004358const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4359 size_t *size) {
4360 if (isNotUsableTU(TU)) {
4361 LOG_BAD_TU(TU);
4362 return nullptr;
4363 }
4364
4365 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4366 FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
Duncan P. N. Exon Smith00651982020-10-14 14:36:00 -04004367 llvm::Optional<llvm::MemoryBufferRef> buf = SM.getBufferOrNone(fid);
4368 if (!buf) {
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004369 if (size)
4370 *size = 0;
4371 return nullptr;
4372 }
4373 if (size)
4374 *size = buf->getBufferSize();
4375 return buf->getBufferStart();
4376}
4377
Michael Kruse7520cf02020-03-25 09:26:14 -05004378unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004379 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004380 LOG_BAD_TU(TU);
4381 return 0;
4382 }
4383
4384 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00004385 return 0;
4386
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004387 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 FileEntry *FEnt = static_cast<FileEntry *>(file);
Michael Kruse7520cf02020-03-25 09:26:14 -05004389 return CXXUnit->getPreprocessor()
4390 .getHeaderSearchInfo()
4391 .isFileMultipleIncludeGuarded(FEnt);
Guy Benyei11169dd2012-12-18 14:30:41 +00004392}
4393
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004394int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
4395 if (!file || !outID)
4396 return 1;
4397
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004398 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00004399 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
4400 outID->data[0] = ID.getDevice();
4401 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004402 outID->data[2] = FEnt->getModificationTime();
4403 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004404}
4405
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00004406int clang_File_isEqual(CXFile file1, CXFile file2) {
4407 if (file1 == file2)
4408 return true;
4409
4410 if (!file1 || !file2)
4411 return false;
4412
4413 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
4414 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
4415 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
4416}
4417
Fangrui Songe46ac5f2018-04-07 20:50:35 +00004418CXString clang_File_tryGetRealPathName(CXFile SFile) {
4419 if (!SFile)
4420 return cxstring::createNull();
4421
4422 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4423 return cxstring::createRef(FEnt->tryGetRealPathName());
4424}
4425
Guy Benyei11169dd2012-12-18 14:30:41 +00004426//===----------------------------------------------------------------------===//
4427// CXCursor Operations.
4428//===----------------------------------------------------------------------===//
4429
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004430static const Decl *getDeclFromExpr(const Stmt *E) {
4431 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 return getDeclFromExpr(CE->getSubExpr());
4433
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004434 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004436 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004437 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004438 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004440 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004441 if (PRE->isExplicitProperty())
4442 return PRE->getExplicitProperty();
4443 // It could be messaging both getter and setter as in:
4444 // ++myobj.myprop;
4445 // in which case prefer to associate the setter since it is less obvious
4446 // from inspecting the source that the setter is going to get called.
4447 if (PRE->isMessagingSetter())
4448 return PRE->getImplicitPropertySetter();
4449 return PRE->getImplicitPropertyGetter();
4450 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004451 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004453 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 if (Expr *Src = OVE->getSourceExpr())
4455 return getDeclFromExpr(Src);
Michael Kruse7520cf02020-03-25 09:26:14 -05004456
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004457 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004459 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 if (!CE->isElidable())
Michael Kruse7520cf02020-03-25 09:26:14 -05004461 return CE->getConstructor();
Richard Smith5179eb72016-06-28 19:03:57 +00004462 if (const CXXInheritedCtorInitExpr *CE =
4463 dyn_cast<CXXInheritedCtorInitExpr>(E))
4464 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004465 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 return OME->getMethodDecl();
4467
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004468 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004469 return PE->getProtocol();
Michael Kruse7520cf02020-03-25 09:26:14 -05004470 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4471 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004473 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004474 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
Guy Benyei11169dd2012-12-18 14:30:41 +00004475 isa<ParmVarDecl>(SizeOfPack->getPack()))
4476 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00004477
4478 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004479}
4480
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004481static SourceLocation getLocationFromExpr(const Expr *E) {
4482 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 return getLocationFromExpr(CE->getSubExpr());
4484
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004485 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004486 return /*FIXME:*/ Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004487 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004489 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004491 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004493 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004495 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 return PropRef->getLocation();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004497
4498 return E->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00004499}
4500
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00004501extern "C" {
4502
Michael Kruse7520cf02020-03-25 09:26:14 -05004503unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 CXClientData client_data) {
4505 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4506 /*VisitPreprocessorLast=*/false);
4507 return CursorVis.VisitChildren(parent);
4508}
4509
4510#ifndef __has_feature
4511#define __has_feature(x) 0
4512#endif
4513#if __has_feature(blocks)
Michael Kruse7520cf02020-03-25 09:26:14 -05004514typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4515 CXCursor parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00004516
4517static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004518 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4520 return block(cursor, parent);
4521}
4522#else
4523// If we are compiled with a compiler that doesn't have native blocks support,
Michael Kruse7520cf02020-03-25 09:26:14 -05004524// define and call the block manually, so the
4525typedef struct _CXChildVisitResult {
4526 void *isa;
4527 int flags;
4528 int reserved;
4529 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
4530 CXCursor);
4531} * CXCursorVisitorBlock;
Guy Benyei11169dd2012-12-18 14:30:41 +00004532
4533static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004534 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4536 return block->invoke(block, cursor, parent);
4537}
4538#endif
4539
Guy Benyei11169dd2012-12-18 14:30:41 +00004540unsigned clang_visitChildrenWithBlock(CXCursor parent,
4541 CXCursorVisitorBlock block) {
4542 return clang_visitChildren(parent, visitWithBlock, block);
4543}
4544
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004545static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004547 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004548
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004549 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004551 if (const ObjCPropertyImplDecl *PropImpl =
4552 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004554 return cxstring::createDup(Property->getIdentifier()->getName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004555
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004556 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004558 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004559
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004560 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004562
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004563 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004564 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004565
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004566 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4568 // and returns different names. NamedDecl returns the class name and
4569 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004570 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004571
4572 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004573 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05004574
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 SmallString<1024> S;
4576 llvm::raw_svector_ostream os(S);
4577 ND->printName(os);
Michael Kruse7520cf02020-03-25 09:26:14 -05004578
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004579 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004580}
4581
4582CXString clang_getCursorSpelling(CXCursor C) {
4583 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004584 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004585
4586 if (clang_isReference(C.kind)) {
4587 switch (C.kind) {
4588 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004589 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004590 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 }
4592 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004593 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004594 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004595 }
4596 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004597 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004599 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 }
4601 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004602 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004603 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 }
4605 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004606 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 assert(Type && "Missing type decl");
4608
Michael Kruse7520cf02020-03-25 09:26:14 -05004609 return cxstring::createDup(
4610 getCursorContext(C).getTypeDeclType(Type).getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004611 }
4612 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004613 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 assert(Template && "Missing template decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004615
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004616 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004617 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004618
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004620 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 assert(NS && "Missing namespace decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004622
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004623 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 }
4625
4626 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004627 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 assert(Field && "Missing member decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004629
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004630 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 }
4632
4633 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004634 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 assert(Label && "Missing label");
Michael Kruse7520cf02020-03-25 09:26:14 -05004636
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004637 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 }
4639
4640 case CXCursor_OverloadedDeclRef: {
4641 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004642 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4643 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004644 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004645 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004647 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004648 return cxstring::createDup(E->getName().getAsString());
Michael Kruse7520cf02020-03-25 09:26:14 -05004649 OverloadedTemplateStorage *Ovl =
4650 Storage.get<OverloadedTemplateStorage *>();
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004652 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004653 return cxstring::createDup((*Ovl->begin())->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 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004657 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 assert(Var && "Missing variable decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004659
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004660 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004662
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004664 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 }
4666 }
4667
4668 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004669 const Expr *E = getCursorExpr(C);
4670
4671 if (C.kind == CXCursor_ObjCStringLiteral ||
4672 C.kind == CXCursor_StringLiteral) {
4673 const StringLiteral *SLit;
4674 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4675 SLit = OSL->getString();
4676 } else {
4677 SLit = cast<StringLiteral>(E);
4678 }
4679 SmallString<256> Buf;
4680 llvm::raw_svector_ostream OS(Buf);
4681 SLit->outputString(OS);
4682 return cxstring::createDup(OS.str());
4683 }
4684
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004685 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004686 if (D)
4687 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004688 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 }
4690
4691 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004692 const Stmt *S = getCursorStmt(C);
4693 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004694 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004695
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004696 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004698
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 if (C.kind == CXCursor_MacroExpansion)
Michael Kruse7520cf02020-03-25 09:26:14 -05004700 return cxstring::createRef(
4701 getCursorMacroExpansion(C).getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004702
4703 if (C.kind == CXCursor_MacroDefinition)
Michael Kruse7520cf02020-03-25 09:26:14 -05004704 return cxstring::createRef(
4705 getCursorMacroDefinition(C)->getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004706
4707 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004708 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004709
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 if (clang_isDeclaration(C.kind))
4711 return getDeclSpelling(getCursorDecl(C));
4712
4713 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004714 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004715 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004716 }
4717
4718 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004719 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004720 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 }
4722
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004723 if (C.kind == CXCursor_PackedAttr) {
4724 return cxstring::createRef("packed");
4725 }
4726
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004727 if (C.kind == CXCursor_VisibilityAttr) {
4728 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4729 switch (AA->getVisibility()) {
4730 case VisibilityAttr::VisibilityType::Default:
4731 return cxstring::createRef("default");
4732 case VisibilityAttr::VisibilityType::Hidden:
4733 return cxstring::createRef("hidden");
4734 case VisibilityAttr::VisibilityType::Protected:
4735 return cxstring::createRef("protected");
4736 }
4737 llvm_unreachable("unknown visibility type");
4738 }
4739
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004740 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004741}
4742
Michael Kruse7520cf02020-03-25 09:26:14 -05004743CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 unsigned options) {
4745 if (clang_Cursor_isNull(C))
4746 return clang_getNullRange();
4747
4748 ASTContext &Ctx = getCursorContext(C);
4749
4750 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004751 const Stmt *S = getCursorStmt(C);
4752 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 if (pieceIndex > 0)
4754 return clang_getNullRange();
4755 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4756 }
4757
4758 return clang_getNullRange();
4759 }
4760
4761 if (C.kind == CXCursor_ObjCMessageExpr) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004762 if (const ObjCMessageExpr *ME =
4763 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 if (pieceIndex >= ME->getNumSelectorLocs())
4765 return clang_getNullRange();
4766 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4767 }
4768 }
4769
4770 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4771 C.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004772 if (const ObjCMethodDecl *MD =
4773 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 if (pieceIndex >= MD->getNumSelectorLocs())
4775 return clang_getNullRange();
4776 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4777 }
4778 }
4779
4780 if (C.kind == CXCursor_ObjCCategoryDecl ||
4781 C.kind == CXCursor_ObjCCategoryImplDecl) {
4782 if (pieceIndex > 0)
4783 return clang_getNullRange();
Michael Kruse7520cf02020-03-25 09:26:14 -05004784 if (const ObjCCategoryDecl *CD =
4785 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Michael Kruse7520cf02020-03-25 09:26:14 -05004787 if (const ObjCCategoryImplDecl *CID =
4788 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4790 }
4791
4792 if (C.kind == CXCursor_ModuleImportDecl) {
4793 if (pieceIndex > 0)
4794 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004795 if (const ImportDecl *ImportD =
4796 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4798 if (!Locs.empty())
Michael Kruse7520cf02020-03-25 09:26:14 -05004799 return cxloc::translateSourceRange(
4800 Ctx, SourceRange(Locs.front(), Locs.back()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 }
4802 return clang_getNullRange();
4803 }
4804
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004805 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
Kevin Funk4be5d672016-12-20 09:56:56 +00004806 C.kind == CXCursor_ConversionFunction ||
4807 C.kind == CXCursor_FunctionDecl) {
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004808 if (pieceIndex > 0)
4809 return clang_getNullRange();
4810 if (const FunctionDecl *FD =
4811 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4812 DeclarationNameInfo FunctionName = FD->getNameInfo();
4813 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4814 }
4815 return clang_getNullRange();
4816 }
4817
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 // FIXME: A CXCursor_InclusionDirective should give the location of the
4819 // filename, but we don't keep track of this.
4820
4821 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4822 // but we don't keep track of this.
4823
4824 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4825 // but we don't keep track of this.
4826
4827 // Default handling, give the location of the cursor.
4828
4829 if (pieceIndex > 0)
4830 return clang_getNullRange();
4831
4832 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4833 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4834 return cxloc::translateSourceRange(Ctx, Loc);
4835}
4836
Eli Bendersky44a206f2014-07-31 18:04:56 +00004837CXString clang_Cursor_getMangling(CXCursor C) {
4838 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4839 return cxstring::createEmpty();
4840
Eli Bendersky44a206f2014-07-31 18:04:56 +00004841 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004842 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004843 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4844 return cxstring::createEmpty();
4845
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004846 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004847 ASTNameGenerator ASTNameGen(Ctx);
4848 return cxstring::createDup(ASTNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004849}
4850
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004851CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4852 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4853 return nullptr;
4854
4855 const Decl *D = getCursorDecl(C);
4856 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4857 return nullptr;
4858
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004859 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004860 ASTNameGenerator ASTNameGen(Ctx);
4861 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004862 return cxstring::createSet(Manglings);
4863}
4864
Dave Lee1a532c92017-09-22 16:58:57 +00004865CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
4866 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4867 return nullptr;
4868
4869 const Decl *D = getCursorDecl(C);
4870 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
4871 return nullptr;
4872
4873 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004874 ASTNameGenerator ASTNameGen(Ctx);
4875 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Dave Lee1a532c92017-09-22 16:58:57 +00004876 return cxstring::createSet(Manglings);
4877}
4878
Jonathan Coe45ef5032018-01-16 10:19:56 +00004879CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
4880 if (clang_Cursor_isNull(C))
4881 return 0;
4882 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
4883}
4884
4885void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
4886 if (Policy)
4887 delete static_cast<PrintingPolicy *>(Policy);
4888}
4889
4890unsigned
4891clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
4892 enum CXPrintingPolicyProperty Property) {
4893 if (!Policy)
4894 return 0;
4895
4896 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4897 switch (Property) {
4898 case CXPrintingPolicy_Indentation:
4899 return P->Indentation;
4900 case CXPrintingPolicy_SuppressSpecifiers:
4901 return P->SuppressSpecifiers;
4902 case CXPrintingPolicy_SuppressTagKeyword:
4903 return P->SuppressTagKeyword;
4904 case CXPrintingPolicy_IncludeTagDefinition:
4905 return P->IncludeTagDefinition;
4906 case CXPrintingPolicy_SuppressScope:
4907 return P->SuppressScope;
4908 case CXPrintingPolicy_SuppressUnwrittenScope:
4909 return P->SuppressUnwrittenScope;
4910 case CXPrintingPolicy_SuppressInitializers:
4911 return P->SuppressInitializers;
4912 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4913 return P->ConstantArraySizeAsWritten;
4914 case CXPrintingPolicy_AnonymousTagLocations:
4915 return P->AnonymousTagLocations;
4916 case CXPrintingPolicy_SuppressStrongLifetime:
4917 return P->SuppressStrongLifetime;
4918 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4919 return P->SuppressLifetimeQualifiers;
4920 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4921 return P->SuppressTemplateArgsInCXXConstructors;
4922 case CXPrintingPolicy_Bool:
4923 return P->Bool;
4924 case CXPrintingPolicy_Restrict:
4925 return P->Restrict;
4926 case CXPrintingPolicy_Alignof:
4927 return P->Alignof;
4928 case CXPrintingPolicy_UnderscoreAlignof:
4929 return P->UnderscoreAlignof;
4930 case CXPrintingPolicy_UseVoidForZeroParams:
4931 return P->UseVoidForZeroParams;
4932 case CXPrintingPolicy_TerseOutput:
4933 return P->TerseOutput;
4934 case CXPrintingPolicy_PolishForDeclaration:
4935 return P->PolishForDeclaration;
4936 case CXPrintingPolicy_Half:
4937 return P->Half;
4938 case CXPrintingPolicy_MSWChar:
4939 return P->MSWChar;
4940 case CXPrintingPolicy_IncludeNewlines:
4941 return P->IncludeNewlines;
4942 case CXPrintingPolicy_MSVCFormatting:
4943 return P->MSVCFormatting;
4944 case CXPrintingPolicy_ConstantsAsWritten:
4945 return P->ConstantsAsWritten;
4946 case CXPrintingPolicy_SuppressImplicitBase:
4947 return P->SuppressImplicitBase;
4948 case CXPrintingPolicy_FullyQualifiedName:
4949 return P->FullyQualifiedName;
4950 }
4951
4952 assert(false && "Invalid CXPrintingPolicyProperty");
4953 return 0;
4954}
4955
4956void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
4957 enum CXPrintingPolicyProperty Property,
4958 unsigned Value) {
4959 if (!Policy)
4960 return;
4961
4962 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4963 switch (Property) {
4964 case CXPrintingPolicy_Indentation:
4965 P->Indentation = Value;
4966 return;
4967 case CXPrintingPolicy_SuppressSpecifiers:
4968 P->SuppressSpecifiers = Value;
4969 return;
4970 case CXPrintingPolicy_SuppressTagKeyword:
4971 P->SuppressTagKeyword = Value;
4972 return;
4973 case CXPrintingPolicy_IncludeTagDefinition:
4974 P->IncludeTagDefinition = Value;
4975 return;
4976 case CXPrintingPolicy_SuppressScope:
4977 P->SuppressScope = Value;
4978 return;
4979 case CXPrintingPolicy_SuppressUnwrittenScope:
4980 P->SuppressUnwrittenScope = Value;
4981 return;
4982 case CXPrintingPolicy_SuppressInitializers:
4983 P->SuppressInitializers = Value;
4984 return;
4985 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4986 P->ConstantArraySizeAsWritten = Value;
4987 return;
4988 case CXPrintingPolicy_AnonymousTagLocations:
4989 P->AnonymousTagLocations = Value;
4990 return;
4991 case CXPrintingPolicy_SuppressStrongLifetime:
4992 P->SuppressStrongLifetime = Value;
4993 return;
4994 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4995 P->SuppressLifetimeQualifiers = Value;
4996 return;
4997 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4998 P->SuppressTemplateArgsInCXXConstructors = Value;
4999 return;
5000 case CXPrintingPolicy_Bool:
5001 P->Bool = Value;
5002 return;
5003 case CXPrintingPolicy_Restrict:
5004 P->Restrict = Value;
5005 return;
5006 case CXPrintingPolicy_Alignof:
5007 P->Alignof = Value;
5008 return;
5009 case CXPrintingPolicy_UnderscoreAlignof:
5010 P->UnderscoreAlignof = Value;
5011 return;
5012 case CXPrintingPolicy_UseVoidForZeroParams:
5013 P->UseVoidForZeroParams = Value;
5014 return;
5015 case CXPrintingPolicy_TerseOutput:
5016 P->TerseOutput = Value;
5017 return;
5018 case CXPrintingPolicy_PolishForDeclaration:
5019 P->PolishForDeclaration = Value;
5020 return;
5021 case CXPrintingPolicy_Half:
5022 P->Half = Value;
5023 return;
5024 case CXPrintingPolicy_MSWChar:
5025 P->MSWChar = Value;
5026 return;
5027 case CXPrintingPolicy_IncludeNewlines:
5028 P->IncludeNewlines = Value;
5029 return;
5030 case CXPrintingPolicy_MSVCFormatting:
5031 P->MSVCFormatting = Value;
5032 return;
5033 case CXPrintingPolicy_ConstantsAsWritten:
5034 P->ConstantsAsWritten = Value;
5035 return;
5036 case CXPrintingPolicy_SuppressImplicitBase:
5037 P->SuppressImplicitBase = Value;
5038 return;
5039 case CXPrintingPolicy_FullyQualifiedName:
5040 P->FullyQualifiedName = Value;
5041 return;
5042 }
5043
5044 assert(false && "Invalid CXPrintingPolicyProperty");
5045}
5046
5047CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
5048 if (clang_Cursor_isNull(C))
5049 return cxstring::createEmpty();
5050
5051 if (clang_isDeclaration(C.kind)) {
5052 const Decl *D = getCursorDecl(C);
5053 if (!D)
5054 return cxstring::createEmpty();
5055
5056 SmallString<128> Str;
5057 llvm::raw_svector_ostream OS(Str);
5058 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5059 D->print(OS, UserPolicy ? *UserPolicy
5060 : getCursorContext(C).getPrintingPolicy());
5061
5062 return cxstring::createDup(OS.str());
5063 }
5064
5065 return cxstring::createEmpty();
5066}
5067
Guy Benyei11169dd2012-12-18 14:30:41 +00005068CXString clang_getCursorDisplayName(CXCursor C) {
5069 if (!clang_isDeclaration(C.kind))
5070 return clang_getCursorSpelling(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05005071
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005072 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005073 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005074 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005075
5076 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005077 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005078 D = FunTmpl->getTemplatedDecl();
Michael Kruse7520cf02020-03-25 09:26:14 -05005079
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005080 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 SmallString<64> Str;
5082 llvm::raw_svector_ostream OS(Str);
5083 OS << *Function;
5084 if (Function->getPrimaryTemplate())
5085 OS << "<>";
5086 OS << "(";
5087 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5088 if (I)
5089 OS << ", ";
5090 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5091 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005092
Guy Benyei11169dd2012-12-18 14:30:41 +00005093 if (Function->isVariadic()) {
5094 if (Function->getNumParams())
5095 OS << ", ";
5096 OS << "...";
5097 }
5098 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005099 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005100 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005101
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005102 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005103 SmallString<64> Str;
5104 llvm::raw_svector_ostream OS(Str);
5105 OS << *ClassTemplate;
5106 OS << "<";
5107 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5108 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5109 if (I)
5110 OS << ", ";
Michael Kruse7520cf02020-03-25 09:26:14 -05005111
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 NamedDecl *Param = Params->getParam(I);
5113 if (Param->getIdentifier()) {
5114 OS << Param->getIdentifier()->getName();
5115 continue;
5116 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005117
Guy Benyei11169dd2012-12-18 14:30:41 +00005118 // There is no parameter name, which makes this tricky. Try to come up
5119 // with something useful that isn't too long.
5120 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
Saar Razff1e0fc2020-01-15 02:48:42 +02005121 if (const auto *TC = TTP->getTypeConstraint()) {
5122 TC->getConceptNameInfo().printName(OS, Policy);
5123 if (TC->hasExplicitTemplateArgs())
5124 OS << "<...>";
5125 } else
Michael Kruse7520cf02020-03-25 09:26:14 -05005126 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5127 else if (NonTypeTemplateParmDecl *NTTP =
5128 dyn_cast<NonTypeTemplateParmDecl>(Param))
Guy Benyei11169dd2012-12-18 14:30:41 +00005129 OS << NTTP->getType().getAsString(Policy);
5130 else
5131 OS << "template<...> class";
5132 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005133
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005135 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005137
5138 if (const ClassTemplateSpecializationDecl *ClassSpec =
5139 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 // If the type was explicitly written, use that.
5141 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005142 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Serge Pavlov03e672c2017-11-28 16:14:14 +00005143
Benjamin Kramer9170e912013-02-22 15:46:01 +00005144 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00005145 llvm::raw_svector_ostream OS(Str);
5146 OS << *ClassSpec;
Serge Pavlov03e672c2017-11-28 16:14:14 +00005147 printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
5148 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005149 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005151
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 return clang_getCursorSpelling(C);
5153}
Michael Kruse7520cf02020-03-25 09:26:14 -05005154
Guy Benyei11169dd2012-12-18 14:30:41 +00005155CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5156 switch (Kind) {
5157 case CXCursor_FunctionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005158 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005159 case CXCursor_TypedefDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005160 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005161 case CXCursor_EnumDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005162 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005163 case CXCursor_EnumConstantDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005164 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005165 case CXCursor_StructDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005166 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005167 case CXCursor_UnionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005168 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005169 case CXCursor_ClassDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005170 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005171 case CXCursor_FieldDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005172 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005173 case CXCursor_VarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005174 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005175 case CXCursor_ParmDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005176 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 case CXCursor_ObjCInterfaceDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005178 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005179 case CXCursor_ObjCCategoryDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005180 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005181 case CXCursor_ObjCProtocolDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005182 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 case CXCursor_ObjCPropertyDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005184 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005185 case CXCursor_ObjCIvarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005186 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005187 case CXCursor_ObjCInstanceMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005188 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005189 case CXCursor_ObjCClassMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005190 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 case CXCursor_ObjCImplementationDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005192 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 case CXCursor_ObjCCategoryImplDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005194 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005195 case CXCursor_CXXMethod:
Michael Kruse7520cf02020-03-25 09:26:14 -05005196 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00005197 case CXCursor_UnexposedDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005198 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005199 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005200 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 case CXCursor_ObjCProtocolRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005202 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 case CXCursor_ObjCClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005204 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 case CXCursor_TypeRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005206 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005207 case CXCursor_TemplateRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005208 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005210 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005212 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005214 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005216 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005218 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 case CXCursor_IntegerLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005220 return cxstring::createRef("IntegerLiteral");
Leonard Chandb01c3a2018-06-20 17:19:40 +00005221 case CXCursor_FixedPointLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005222 return cxstring::createRef("FixedPointLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 case CXCursor_FloatingLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005224 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005225 case CXCursor_ImaginaryLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005226 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 case CXCursor_StringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005228 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005229 case CXCursor_CharacterLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005230 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005231 case CXCursor_ParenExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005232 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005233 case CXCursor_UnaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005234 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 case CXCursor_ArraySubscriptExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005236 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00005237 case CXCursor_OMPArraySectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005238 return cxstring::createRef("OMPArraySectionExpr");
Alexey Bataev7ac9efb2020-02-05 09:33:05 -05005239 case CXCursor_OMPArrayShapingExpr:
5240 return cxstring::createRef("OMPArrayShapingExpr");
Alexey Bataev13a15042020-04-01 15:06:38 -04005241 case CXCursor_OMPIteratorExpr:
5242 return cxstring::createRef("OMPIteratorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005243 case CXCursor_BinaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005244 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005245 case CXCursor_CompoundAssignOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005246 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005247 case CXCursor_ConditionalOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005248 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005249 case CXCursor_CStyleCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005250 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005251 case CXCursor_CompoundLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005252 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005253 case CXCursor_InitListExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005254 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 case CXCursor_AddrLabelExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005256 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005257 case CXCursor_StmtExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005258 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 case CXCursor_GenericSelectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005260 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005261 case CXCursor_GNUNullExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005262 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 case CXCursor_CXXStaticCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005264 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005265 case CXCursor_CXXDynamicCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005266 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005267 case CXCursor_CXXReinterpretCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005268 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005269 case CXCursor_CXXConstCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005270 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005271 case CXCursor_CXXFunctionalCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005272 return cxstring::createRef("CXXFunctionalCastExpr");
Anastasia Stulovaa6a237f2020-05-18 11:02:01 +01005273 case CXCursor_CXXAddrspaceCastExpr:
5274 return cxstring::createRef("CXXAddrspaceCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 case CXCursor_CXXTypeidExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005276 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 case CXCursor_CXXBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005278 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005279 case CXCursor_CXXNullPtrLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005280 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005281 case CXCursor_CXXThisExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005282 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005283 case CXCursor_CXXThrowExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005284 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 case CXCursor_CXXNewExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005286 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005287 case CXCursor_CXXDeleteExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005288 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005289 case CXCursor_UnaryExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005290 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 case CXCursor_ObjCStringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005292 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 case CXCursor_ObjCBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005294 return cxstring::createRef("ObjCBoolLiteralExpr");
Erik Pilkington29099de2016-07-16 00:35:23 +00005295 case CXCursor_ObjCAvailabilityCheckExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005296 return cxstring::createRef("ObjCAvailabilityCheckExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00005297 case CXCursor_ObjCSelfExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005298 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005299 case CXCursor_ObjCEncodeExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005300 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005301 case CXCursor_ObjCSelectorExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005302 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 case CXCursor_ObjCProtocolExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005304 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 case CXCursor_ObjCBridgedCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005306 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005307 case CXCursor_BlockExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005308 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005309 case CXCursor_PackExpansionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005310 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005311 case CXCursor_SizeOfPackExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005312 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005313 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005314 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005315 case CXCursor_UnexposedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005316 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005317 case CXCursor_DeclRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005318 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005319 case CXCursor_MemberRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005320 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005321 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005322 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 case CXCursor_ObjCMessageExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005324 return cxstring::createRef("ObjCMessageExpr");
Erik Pilkingtoneee944e2019-07-02 18:28:13 +00005325 case CXCursor_BuiltinBitCastExpr:
5326 return cxstring::createRef("BuiltinBitCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005327 case CXCursor_UnexposedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005328 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005329 case CXCursor_DeclStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005330 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005331 case CXCursor_LabelStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005332 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 case CXCursor_CompoundStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005334 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005335 case CXCursor_CaseStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005336 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005337 case CXCursor_DefaultStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005338 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 case CXCursor_IfStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005340 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 case CXCursor_SwitchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005342 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 case CXCursor_WhileStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005344 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005345 case CXCursor_DoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005346 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 case CXCursor_ForStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005348 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 case CXCursor_GotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005350 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005351 case CXCursor_IndirectGotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005352 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005353 case CXCursor_ContinueStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005354 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005355 case CXCursor_BreakStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005356 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 case CXCursor_ReturnStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005358 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005359 case CXCursor_GCCAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005360 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005361 case CXCursor_MSAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005362 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005363 case CXCursor_ObjCAtTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005364 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 case CXCursor_ObjCAtCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005366 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005367 case CXCursor_ObjCAtFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005368 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005369 case CXCursor_ObjCAtThrowStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005370 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005371 case CXCursor_ObjCAtSynchronizedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005372 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 case CXCursor_ObjCAutoreleasePoolStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005374 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005375 case CXCursor_ObjCForCollectionStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005376 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005377 case CXCursor_CXXCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005378 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005379 case CXCursor_CXXTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005380 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 case CXCursor_CXXForRangeStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005382 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005383 case CXCursor_SEHTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005384 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005385 case CXCursor_SEHExceptStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005386 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005387 case CXCursor_SEHFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005388 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00005389 case CXCursor_SEHLeaveStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005390 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005391 case CXCursor_NullStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005392 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005393 case CXCursor_InvalidFile:
Michael Kruse7520cf02020-03-25 09:26:14 -05005394 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00005395 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005396 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00005397 case CXCursor_NoDeclFound:
Michael Kruse7520cf02020-03-25 09:26:14 -05005398 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00005399 case CXCursor_NotImplemented:
Michael Kruse7520cf02020-03-25 09:26:14 -05005400 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00005401 case CXCursor_TranslationUnit:
Michael Kruse7520cf02020-03-25 09:26:14 -05005402 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00005403 case CXCursor_UnexposedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005404 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005405 case CXCursor_IBActionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005406 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005407 case CXCursor_IBOutletAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005408 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005409 case CXCursor_IBOutletCollectionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005410 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005411 case CXCursor_CXXFinalAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005412 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005413 case CXCursor_CXXOverrideAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005414 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005415 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005416 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005417 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005418 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005419 case CXCursor_PackedAttr:
5420 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00005421 case CXCursor_PureAttr:
5422 return cxstring::createRef("attribute(pure)");
5423 case CXCursor_ConstAttr:
5424 return cxstring::createRef("attribute(const)");
5425 case CXCursor_NoDuplicateAttr:
5426 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00005427 case CXCursor_CUDAConstantAttr:
5428 return cxstring::createRef("attribute(constant)");
5429 case CXCursor_CUDADeviceAttr:
5430 return cxstring::createRef("attribute(device)");
5431 case CXCursor_CUDAGlobalAttr:
5432 return cxstring::createRef("attribute(global)");
5433 case CXCursor_CUDAHostAttr:
5434 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00005435 case CXCursor_CUDASharedAttr:
5436 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00005437 case CXCursor_VisibilityAttr:
5438 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00005439 case CXCursor_DLLExport:
5440 return cxstring::createRef("attribute(dllexport)");
5441 case CXCursor_DLLImport:
5442 return cxstring::createRef("attribute(dllimport)");
Michael Wud092d0b2018-08-03 05:03:22 +00005443 case CXCursor_NSReturnsRetained:
5444 return cxstring::createRef("attribute(ns_returns_retained)");
5445 case CXCursor_NSReturnsNotRetained:
5446 return cxstring::createRef("attribute(ns_returns_not_retained)");
5447 case CXCursor_NSReturnsAutoreleased:
5448 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5449 case CXCursor_NSConsumesSelf:
5450 return cxstring::createRef("attribute(ns_consumes_self)");
5451 case CXCursor_NSConsumed:
5452 return cxstring::createRef("attribute(ns_consumed)");
5453 case CXCursor_ObjCException:
5454 return cxstring::createRef("attribute(objc_exception)");
5455 case CXCursor_ObjCNSObject:
5456 return cxstring::createRef("attribute(NSObject)");
5457 case CXCursor_ObjCIndependentClass:
5458 return cxstring::createRef("attribute(objc_independent_class)");
5459 case CXCursor_ObjCPreciseLifetime:
5460 return cxstring::createRef("attribute(objc_precise_lifetime)");
5461 case CXCursor_ObjCReturnsInnerPointer:
5462 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5463 case CXCursor_ObjCRequiresSuper:
5464 return cxstring::createRef("attribute(objc_requires_super)");
5465 case CXCursor_ObjCRootClass:
5466 return cxstring::createRef("attribute(objc_root_class)");
5467 case CXCursor_ObjCSubclassingRestricted:
5468 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5469 case CXCursor_ObjCExplicitProtocolImpl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005470 return cxstring::createRef(
5471 "attribute(objc_protocol_requires_explicit_implementation)");
Michael Wud092d0b2018-08-03 05:03:22 +00005472 case CXCursor_ObjCDesignatedInitializer:
5473 return cxstring::createRef("attribute(objc_designated_initializer)");
5474 case CXCursor_ObjCRuntimeVisible:
5475 return cxstring::createRef("attribute(objc_runtime_visible)");
5476 case CXCursor_ObjCBoxable:
5477 return cxstring::createRef("attribute(objc_boxable)");
Michael Wu58d837d2018-08-03 05:55:40 +00005478 case CXCursor_FlagEnum:
5479 return cxstring::createRef("attribute(flag_enum)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005480 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005481 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005483 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005485 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005486 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005487 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005488 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005489 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00005490 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005491 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00005492 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005493 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005494 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005495 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005497 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005498 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005499 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005500 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005501 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005502 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005503 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005505 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005506 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005507 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005508 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005509 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005510 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005511 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005513 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00005514 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005515 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00005516 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005517 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005519 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005520 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005521 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005522 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005523 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005524 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005525 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005526 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005527 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005528 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00005529 return cxstring::createRef("OMPParallelDirective");
5530 case CXCursor_OMPSimdDirective:
5531 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00005532 case CXCursor_OMPForDirective:
5533 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00005534 case CXCursor_OMPForSimdDirective:
5535 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00005536 case CXCursor_OMPSectionsDirective:
5537 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00005538 case CXCursor_OMPSectionDirective:
5539 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00005540 case CXCursor_OMPSingleDirective:
5541 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00005542 case CXCursor_OMPMasterDirective:
5543 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00005544 case CXCursor_OMPCriticalDirective:
5545 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00005546 case CXCursor_OMPParallelForDirective:
5547 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00005548 case CXCursor_OMPParallelForSimdDirective:
5549 return cxstring::createRef("OMPParallelForSimdDirective");
cchen47d60942019-12-05 13:43:48 -05005550 case CXCursor_OMPParallelMasterDirective:
5551 return cxstring::createRef("OMPParallelMasterDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00005552 case CXCursor_OMPParallelSectionsDirective:
5553 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00005554 case CXCursor_OMPTaskDirective:
5555 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00005556 case CXCursor_OMPTaskyieldDirective:
5557 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00005558 case CXCursor_OMPBarrierDirective:
5559 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00005560 case CXCursor_OMPTaskwaitDirective:
5561 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00005562 case CXCursor_OMPTaskgroupDirective:
5563 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00005564 case CXCursor_OMPFlushDirective:
5565 return cxstring::createRef("OMPFlushDirective");
Alexey Bataevc112e942020-02-28 09:52:15 -05005566 case CXCursor_OMPDepobjDirective:
5567 return cxstring::createRef("OMPDepobjDirective");
Alexey Bataevfcba7c32020-03-20 07:03:01 -04005568 case CXCursor_OMPScanDirective:
5569 return cxstring::createRef("OMPScanDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00005570 case CXCursor_OMPOrderedDirective:
5571 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00005572 case CXCursor_OMPAtomicDirective:
5573 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00005574 case CXCursor_OMPTargetDirective:
5575 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00005576 case CXCursor_OMPTargetDataDirective:
5577 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00005578 case CXCursor_OMPTargetEnterDataDirective:
5579 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00005580 case CXCursor_OMPTargetExitDataDirective:
5581 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00005582 case CXCursor_OMPTargetParallelDirective:
5583 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00005584 case CXCursor_OMPTargetParallelForDirective:
5585 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00005586 case CXCursor_OMPTargetUpdateDirective:
5587 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00005588 case CXCursor_OMPTeamsDirective:
5589 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00005590 case CXCursor_OMPCancellationPointDirective:
5591 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00005592 case CXCursor_OMPCancelDirective:
5593 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00005594 case CXCursor_OMPTaskLoopDirective:
5595 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005596 case CXCursor_OMPTaskLoopSimdDirective:
5597 return cxstring::createRef("OMPTaskLoopSimdDirective");
Alexey Bataev60e51c42019-10-10 20:13:02 +00005598 case CXCursor_OMPMasterTaskLoopDirective:
5599 return cxstring::createRef("OMPMasterTaskLoopDirective");
Alexey Bataevb8552ab2019-10-18 16:47:35 +00005600 case CXCursor_OMPMasterTaskLoopSimdDirective:
5601 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
Alexey Bataev5bbcead2019-10-14 17:17:41 +00005602 case CXCursor_OMPParallelMasterTaskLoopDirective:
5603 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
Alexey Bataev14a388f2019-10-25 10:27:13 -04005604 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5605 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00005606 case CXCursor_OMPDistributeDirective:
5607 return cxstring::createRef("OMPDistributeDirective");
Carlo Bertolli9925f152016-06-27 14:55:37 +00005608 case CXCursor_OMPDistributeParallelForDirective:
5609 return cxstring::createRef("OMPDistributeParallelForDirective");
Kelvin Li4a39add2016-07-05 05:00:15 +00005610 case CXCursor_OMPDistributeParallelForSimdDirective:
5611 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
Kelvin Li787f3fc2016-07-06 04:45:38 +00005612 case CXCursor_OMPDistributeSimdDirective:
5613 return cxstring::createRef("OMPDistributeSimdDirective");
Kelvin Lia579b912016-07-14 02:54:56 +00005614 case CXCursor_OMPTargetParallelForSimdDirective:
5615 return cxstring::createRef("OMPTargetParallelForSimdDirective");
Kelvin Li986330c2016-07-20 22:57:10 +00005616 case CXCursor_OMPTargetSimdDirective:
5617 return cxstring::createRef("OMPTargetSimdDirective");
Kelvin Li02532872016-08-05 14:37:37 +00005618 case CXCursor_OMPTeamsDistributeDirective:
5619 return cxstring::createRef("OMPTeamsDistributeDirective");
Kelvin Li4e325f72016-10-25 12:50:55 +00005620 case CXCursor_OMPTeamsDistributeSimdDirective:
5621 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
Kelvin Li579e41c2016-11-30 23:51:03 +00005622 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5623 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
Kelvin Li7ade93f2016-12-09 03:24:30 +00005624 case CXCursor_OMPTeamsDistributeParallelForDirective:
5625 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
Kelvin Libf594a52016-12-17 05:48:59 +00005626 case CXCursor_OMPTargetTeamsDirective:
5627 return cxstring::createRef("OMPTargetTeamsDirective");
Kelvin Li83c451e2016-12-25 04:52:54 +00005628 case CXCursor_OMPTargetTeamsDistributeDirective:
5629 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
Kelvin Li80e8f562016-12-29 22:16:30 +00005630 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5631 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
Kelvin Li1851df52017-01-03 05:23:48 +00005632 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5633 return cxstring::createRef(
5634 "OMPTargetTeamsDistributeParallelForSimdDirective");
Kelvin Lida681182017-01-10 18:08:18 +00005635 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5636 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00005637 case CXCursor_OverloadCandidate:
Michael Kruse7520cf02020-03-25 09:26:14 -05005638 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00005639 case CXCursor_TypeAliasTemplateDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005640 return cxstring::createRef("TypeAliasTemplateDecl");
Olivier Goffart81978012016-06-09 16:15:55 +00005641 case CXCursor_StaticAssert:
Michael Kruse7520cf02020-03-25 09:26:14 -05005642 return cxstring::createRef("StaticAssert");
Olivier Goffartd211c642016-11-04 06:29:27 +00005643 case CXCursor_FriendDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005644 return cxstring::createRef("FriendDecl");
Sven van Haastregtdc2c9302019-02-11 11:00:56 +00005645 case CXCursor_ConvergentAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005646 return cxstring::createRef("attribute(convergent)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005647 case CXCursor_WarnUnusedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005648 return cxstring::createRef("attribute(warn_unused)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005649 case CXCursor_WarnUnusedResultAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005650 return cxstring::createRef("attribute(warn_unused_result)");
Emilio Cobos Alvarezcd741272019-03-13 16:16:54 +00005651 case CXCursor_AlignedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005652 return cxstring::createRef("attribute(aligned)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 }
5654
5655 llvm_unreachable("Unhandled CXCursorKind");
5656}
5657
5658struct GetCursorData {
5659 SourceLocation TokenBeginLoc;
5660 bool PointsAtMacroArgExpansion;
5661 bool VisitedObjCPropertyImplDecl;
5662 SourceLocation VisitedDeclaratorDeclStartLoc;
5663 CXCursor &BestCursor;
5664
Michael Kruse7520cf02020-03-25 09:26:14 -05005665 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5666 CXCursor &outputCursor)
5667 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005668 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5669 VisitedObjCPropertyImplDecl = false;
5670 }
5671};
5672
Michael Kruse7520cf02020-03-25 09:26:14 -05005673static enum CXChildVisitResult
5674GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5676 CXCursor *BestCursor = &Data->BestCursor;
5677
5678 // If we point inside a macro argument we should provide info of what the
5679 // token is so use the actual cursor, don't replace it with a macro expansion
5680 // cursor.
5681 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5682 return CXChildVisit_Recurse;
Michael Kruse7520cf02020-03-25 09:26:14 -05005683
Guy Benyei11169dd2012-12-18 14:30:41 +00005684 if (clang_isDeclaration(cursor.kind)) {
5685 // Avoid having the implicit methods override the property decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05005686 if (const ObjCMethodDecl *MD =
5687 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 if (MD->isImplicit())
5689 return CXChildVisit_Break;
5690
Michael Kruse7520cf02020-03-25 09:26:14 -05005691 } else if (const ObjCInterfaceDecl *ID =
5692 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005693 // Check that when we have multiple @class references in the same line,
5694 // that later ones do not override the previous ones.
5695 // If we have:
5696 // @class Foo, Bar;
5697 // source ranges for both start at '@', so 'Bar' will end up overriding
5698 // 'Foo' even though the cursor location was at 'Foo'.
5699 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5700 BestCursor->kind == CXCursor_ObjCClassRef)
Michael Kruse7520cf02020-03-25 09:26:14 -05005701 if (const ObjCInterfaceDecl *PrevID =
5702 dyn_cast_or_null<ObjCInterfaceDecl>(
5703 getCursorDecl(*BestCursor))) {
5704 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5705 !ID->isThisDeclarationADefinition())
5706 return CXChildVisit_Break;
Guy Benyei11169dd2012-12-18 14:30:41 +00005707 }
5708
Michael Kruse7520cf02020-03-25 09:26:14 -05005709 } else if (const DeclaratorDecl *DD =
5710 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005711 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5712 // Check that when we have multiple declarators in the same line,
5713 // that later ones do not override the previous ones.
5714 // If we have:
5715 // int Foo, Bar;
5716 // source ranges for both start at 'int', so 'Bar' will end up overriding
5717 // 'Foo' even though the cursor location was at 'Foo'.
5718 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5719 return CXChildVisit_Break;
5720 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5721
Michael Kruse7520cf02020-03-25 09:26:14 -05005722 } else if (const ObjCPropertyImplDecl *PropImp =
5723 dyn_cast_or_null<ObjCPropertyImplDecl>(
5724 getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005725 (void)PropImp;
5726 // Check that when we have multiple @synthesize in the same line,
5727 // that later ones do not override the previous ones.
5728 // If we have:
5729 // @synthesize Foo, Bar;
5730 // source ranges for both start at '@', so 'Bar' will end up overriding
5731 // 'Foo' even though the cursor location was at 'Foo'.
5732 if (Data->VisitedObjCPropertyImplDecl)
5733 return CXChildVisit_Break;
5734 Data->VisitedObjCPropertyImplDecl = true;
5735 }
5736 }
5737
5738 if (clang_isExpression(cursor.kind) &&
5739 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005740 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 // Avoid having the cursor of an expression replace the declaration cursor
5742 // when the expression source range overlaps the declaration range.
5743 // This can happen for C++ constructor expressions whose range generally
5744 // include the variable declaration, e.g.:
Michael Kruse7520cf02020-03-25 09:26:14 -05005745 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5746 // cursor.
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5748 D->getLocation() == Data->TokenBeginLoc)
5749 return CXChildVisit_Break;
5750 }
5751 }
5752
Michael Kruse7520cf02020-03-25 09:26:14 -05005753 // If our current best cursor is the construction of a temporary object,
5754 // don't replace that cursor with a type reference, because we want
Guy Benyei11169dd2012-12-18 14:30:41 +00005755 // clang_getCursor() to point at the constructor.
5756 if (clang_isExpression(BestCursor->kind) &&
5757 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5758 cursor.kind == CXCursor_TypeRef) {
5759 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5760 // as having the actual point on the type reference.
5761 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5762 return CXChildVisit_Recurse;
5763 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005764
5765 // If we already have an Objective-C superclass reference, don't
5766 // update it further.
5767 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5768 return CXChildVisit_Break;
5769
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 *BestCursor = cursor;
5771 return CXChildVisit_Recurse;
5772}
5773
5774CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005775 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005776 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005777 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005778 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005779
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005780 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5782
5783 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5784 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5785
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005786 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 CXFile SearchFile;
5788 unsigned SearchLine, SearchColumn;
5789 CXFile ResultFile;
5790 unsigned ResultLine, ResultColumn;
5791 CXString SearchFileName, ResultFileName, KindSpelling, USR;
Michael Kruse7520cf02020-03-25 09:26:14 -05005792 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
Guy Benyei11169dd2012-12-18 14:30:41 +00005793 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005794
5795 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5796 nullptr);
Michael Kruse7520cf02020-03-25 09:26:14 -05005797 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5798 nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005799 SearchFileName = clang_getFileName(SearchFile);
5800 ResultFileName = clang_getFileName(ResultFile);
5801 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5802 USR = clang_getCursorUSR(Result);
Michael Kruse7520cf02020-03-25 09:26:14 -05005803 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5804 SearchLine, SearchColumn,
5805 clang_getCString(KindSpelling))
5806 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5807 ResultLine, ResultColumn, clang_getCString(USR),
5808 IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005809 clang_disposeString(SearchFileName);
5810 clang_disposeString(ResultFileName);
5811 clang_disposeString(KindSpelling);
5812 clang_disposeString(USR);
Michael Kruse7520cf02020-03-25 09:26:14 -05005813
Guy Benyei11169dd2012-12-18 14:30:41 +00005814 CXCursor Definition = clang_getCursorDefinition(Result);
5815 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5816 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
Michael Kruse7520cf02020-03-25 09:26:14 -05005817 CXString DefinitionKindSpelling =
5818 clang_getCursorKindSpelling(Definition.kind);
Guy Benyei11169dd2012-12-18 14:30:41 +00005819 CXFile DefinitionFile;
5820 unsigned DefinitionLine, DefinitionColumn;
Michael Kruse7520cf02020-03-25 09:26:14 -05005821 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5822 &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005823 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005824 *Log << llvm::format(" -> %s(%s:%d:%d)",
Michael Kruse7520cf02020-03-25 09:26:14 -05005825 clang_getCString(DefinitionKindSpelling),
5826 clang_getCString(DefinitionFileName), DefinitionLine,
5827 DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005828 clang_disposeString(DefinitionFileName);
5829 clang_disposeString(DefinitionKindSpelling);
5830 }
5831 }
5832
5833 return Result;
5834}
5835
5836CXCursor clang_getNullCursor(void) {
5837 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5838}
5839
5840unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005841 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5842 // can't set consistently. For example, when visiting a DeclStmt we will set
5843 // it but we don't set it on the result of clang_getCursorDefinition for
5844 // a reference of the same declaration.
5845 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5846 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5847 // to provide that kind of info.
5848 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005849 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005850 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005851 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005852
Guy Benyei11169dd2012-12-18 14:30:41 +00005853 return X == Y;
5854}
5855
5856unsigned clang_hashCursor(CXCursor C) {
5857 unsigned Index = 0;
5858 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5859 Index = 1;
Michael Kruse7520cf02020-03-25 09:26:14 -05005860
5861 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5862 std::make_pair(C.kind, C.data[Index]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005863}
5864
5865unsigned clang_isInvalid(enum CXCursorKind K) {
5866 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5867}
5868
5869unsigned clang_isDeclaration(enum CXCursorKind K) {
5870 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005871 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5872}
5873
Ivan Donchevskii08ff9102018-01-04 10:59:50 +00005874unsigned clang_isInvalidDeclaration(CXCursor C) {
5875 if (clang_isDeclaration(C.kind)) {
5876 if (const Decl *D = getCursorDecl(C))
5877 return D->isInvalidDecl();
5878 }
5879
5880 return 0;
5881}
5882
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005883unsigned clang_isReference(enum CXCursorKind K) {
5884 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5885}
Guy Benyei11169dd2012-12-18 14:30:41 +00005886
5887unsigned clang_isExpression(enum CXCursorKind K) {
5888 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5889}
5890
5891unsigned clang_isStatement(enum CXCursorKind K) {
5892 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5893}
5894
5895unsigned clang_isAttribute(enum CXCursorKind K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005896 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005897}
5898
5899unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5900 return K == CXCursor_TranslationUnit;
5901}
5902
5903unsigned clang_isPreprocessing(enum CXCursorKind K) {
5904 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5905}
Michael Kruse7520cf02020-03-25 09:26:14 -05005906
Guy Benyei11169dd2012-12-18 14:30:41 +00005907unsigned clang_isUnexposed(enum CXCursorKind K) {
5908 switch (K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005909 case CXCursor_UnexposedDecl:
5910 case CXCursor_UnexposedExpr:
5911 case CXCursor_UnexposedStmt:
5912 case CXCursor_UnexposedAttr:
5913 return true;
5914 default:
5915 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005916 }
5917}
5918
Michael Kruse7520cf02020-03-25 09:26:14 -05005919CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005920
5921CXSourceLocation clang_getCursorLocation(CXCursor C) {
5922 if (clang_isReference(C.kind)) {
5923 switch (C.kind) {
5924 case CXCursor_ObjCSuperClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005925 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5926 getCursorObjCSuperClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005927 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5928 }
5929
5930 case CXCursor_ObjCProtocolRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005931 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5932 getCursorObjCProtocolRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005933 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5934 }
5935
5936 case CXCursor_ObjCClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005937 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5938 getCursorObjCClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005939 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5940 }
5941
5942 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005943 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005944 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5945 }
5946
5947 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005948 std::pair<const TemplateDecl *, SourceLocation> P =
5949 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005950 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5951 }
5952
5953 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005954 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005955 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5956 }
5957
5958 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005959 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005960 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5961 }
5962
5963 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005964 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005965 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5966 }
5967
5968 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005969 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005970 if (!BaseSpec)
5971 return clang_getNullLocation();
Michael Kruse7520cf02020-03-25 09:26:14 -05005972
Guy Benyei11169dd2012-12-18 14:30:41 +00005973 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
Michael Kruse7520cf02020-03-25 09:26:14 -05005974 return cxloc::translateSourceLocation(
5975 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005976
Guy Benyei11169dd2012-12-18 14:30:41 +00005977 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005978 BaseSpec->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005979 }
5980
5981 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005982 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005983 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5984 }
5985
5986 case CXCursor_OverloadedDeclRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005987 return cxloc::translateSourceLocation(
5988 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
Guy Benyei11169dd2012-12-18 14:30:41 +00005989
5990 default:
5991 // FIXME: Need a way to enumerate all non-reference cases.
5992 llvm_unreachable("Missed a reference kind");
5993 }
5994 }
5995
5996 if (clang_isExpression(C.kind))
Michael Kruse7520cf02020-03-25 09:26:14 -05005997 return cxloc::translateSourceLocation(
5998 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
Guy Benyei11169dd2012-12-18 14:30:41 +00005999
6000 if (clang_isStatement(C.kind))
6001 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006002 getCursorStmt(C)->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00006003
6004 if (C.kind == CXCursor_PreprocessingDirective) {
6005 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
6006 return cxloc::translateSourceLocation(getCursorContext(C), L);
6007 }
6008
6009 if (C.kind == CXCursor_MacroExpansion) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006010 SourceLocation L =
6011 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 return cxloc::translateSourceLocation(getCursorContext(C), L);
6013 }
6014
6015 if (C.kind == CXCursor_MacroDefinition) {
6016 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
6017 return cxloc::translateSourceLocation(getCursorContext(C), L);
6018 }
6019
6020 if (C.kind == CXCursor_InclusionDirective) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006021 SourceLocation L =
6022 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00006023 return cxloc::translateSourceLocation(getCursorContext(C), L);
6024 }
6025
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00006026 if (clang_isAttribute(C.kind)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006027 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00006028 return cxloc::translateSourceLocation(getCursorContext(C), L);
6029 }
6030
Guy Benyei11169dd2012-12-18 14:30:41 +00006031 if (!clang_isDeclaration(C.kind))
6032 return clang_getNullLocation();
6033
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006034 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006035 if (!D)
6036 return clang_getNullLocation();
6037
6038 SourceLocation Loc = D->getLocation();
6039 // FIXME: Multiple variables declared in a single declaration
6040 // currently lack the information needed to correctly determine their
6041 // ranges when accounting for the type-specifier. We use context
6042 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6043 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006044 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006045 if (!cxcursor::isFirstInDeclGroup(C))
6046 Loc = VD->getLocation();
6047 }
6048
6049 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006050 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006051 Loc = MD->getSelectorStartLoc();
6052
6053 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
6054}
6055
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00006056} // end extern "C"
6057
Guy Benyei11169dd2012-12-18 14:30:41 +00006058CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6059 assert(TU);
6060
6061 // Guard against an invalid SourceLocation, or we may assert in one
6062 // of the following calls.
6063 if (SLoc.isInvalid())
6064 return clang_getNullCursor();
6065
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006066 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006067
6068 // Translate the given source location to make it point at the beginning of
6069 // the token under the cursor.
6070 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6071 CXXUnit->getASTContext().getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05006072
Guy Benyei11169dd2012-12-18 14:30:41 +00006073 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6074 if (SLoc.isValid()) {
6075 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6076 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Michael Kruse7520cf02020-03-25 09:26:14 -05006077 /*VisitPreprocessorLast=*/true,
Guy Benyei11169dd2012-12-18 14:30:41 +00006078 /*VisitIncludedEntities=*/false,
6079 SourceLocation(SLoc));
6080 CursorVis.visitFileRegion();
6081 }
6082
6083 return Result;
6084}
6085
6086static SourceRange getRawCursorExtent(CXCursor C) {
6087 if (clang_isReference(C.kind)) {
6088 switch (C.kind) {
6089 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05006090 return getCursorObjCSuperClassRef(C).second;
Guy Benyei11169dd2012-12-18 14:30:41 +00006091
6092 case CXCursor_ObjCProtocolRef:
6093 return getCursorObjCProtocolRef(C).second;
6094
6095 case CXCursor_ObjCClassRef:
6096 return getCursorObjCClassRef(C).second;
6097
6098 case CXCursor_TypeRef:
6099 return getCursorTypeRef(C).second;
6100
6101 case CXCursor_TemplateRef:
6102 return getCursorTemplateRef(C).second;
6103
6104 case CXCursor_NamespaceRef:
6105 return getCursorNamespaceRef(C).second;
6106
6107 case CXCursor_MemberRef:
6108 return getCursorMemberRef(C).second;
6109
6110 case CXCursor_CXXBaseSpecifier:
6111 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6112
6113 case CXCursor_LabelRef:
6114 return getCursorLabelRef(C).second;
6115
6116 case CXCursor_OverloadedDeclRef:
6117 return getCursorOverloadedDeclRef(C).second;
6118
6119 case CXCursor_VariableRef:
6120 return getCursorVariableRef(C).second;
Michael Kruse7520cf02020-03-25 09:26:14 -05006121
Guy Benyei11169dd2012-12-18 14:30:41 +00006122 default:
6123 // FIXME: Need a way to enumerate all non-reference cases.
6124 llvm_unreachable("Missed a reference kind");
6125 }
6126 }
6127
6128 if (clang_isExpression(C.kind))
6129 return getCursorExpr(C)->getSourceRange();
6130
6131 if (clang_isStatement(C.kind))
6132 return getCursorStmt(C)->getSourceRange();
6133
6134 if (clang_isAttribute(C.kind))
6135 return getCursorAttr(C)->getRange();
6136
6137 if (C.kind == CXCursor_PreprocessingDirective)
6138 return cxcursor::getCursorPreprocessingDirective(C);
6139
6140 if (C.kind == CXCursor_MacroExpansion) {
6141 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006142 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 return TU->mapRangeFromPreamble(Range);
6144 }
6145
6146 if (C.kind == CXCursor_MacroDefinition) {
6147 ASTUnit *TU = getCursorASTUnit(C);
6148 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6149 return TU->mapRangeFromPreamble(Range);
6150 }
6151
6152 if (C.kind == CXCursor_InclusionDirective) {
6153 ASTUnit *TU = getCursorASTUnit(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05006154 SourceRange Range =
6155 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 return TU->mapRangeFromPreamble(Range);
6157 }
6158
6159 if (C.kind == CXCursor_TranslationUnit) {
6160 ASTUnit *TU = getCursorASTUnit(C);
6161 FileID MainID = TU->getSourceManager().getMainFileID();
6162 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6163 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6164 return SourceRange(Start, End);
6165 }
6166
6167 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006168 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006169 if (!D)
6170 return SourceRange();
6171
6172 SourceRange R = D->getSourceRange();
6173 // FIXME: Multiple variables declared in a single declaration
6174 // currently lack the information needed to correctly determine their
6175 // ranges when accounting for the type-specifier. We use context
6176 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6177 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006178 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006179 if (!cxcursor::isFirstInDeclGroup(C))
6180 R.setBegin(VD->getLocation());
6181 }
6182 return R;
6183 }
6184 return SourceRange();
6185}
6186
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006187/// Retrieves the "raw" cursor extent, which is then extended to include
Guy Benyei11169dd2012-12-18 14:30:41 +00006188/// the decl-specifier-seq for declarations.
6189static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6190 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006191 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006192 if (!D)
6193 return SourceRange();
6194
6195 SourceRange R = D->getSourceRange();
6196
6197 // Adjust the start of the location for declarations preceded by
6198 // declaration specifiers.
6199 SourceLocation StartLoc;
6200 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6201 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006202 StartLoc = TI->getTypeLoc().getBeginLoc();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006203 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006204 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006205 StartLoc = TI->getTypeLoc().getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00006206 }
6207
6208 if (StartLoc.isValid() && R.getBegin().isValid() &&
6209 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6210 R.setBegin(StartLoc);
6211
6212 // FIXME: Multiple variables declared in a single declaration
6213 // currently lack the information needed to correctly determine their
6214 // ranges when accounting for the type-specifier. We use context
6215 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6216 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006217 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006218 if (!cxcursor::isFirstInDeclGroup(C))
6219 R.setBegin(VD->getLocation());
6220 }
6221
Michael Kruse7520cf02020-03-25 09:26:14 -05006222 return R;
Guy Benyei11169dd2012-12-18 14:30:41 +00006223 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006224
Guy Benyei11169dd2012-12-18 14:30:41 +00006225 return getRawCursorExtent(C);
6226}
6227
Guy Benyei11169dd2012-12-18 14:30:41 +00006228CXSourceRange clang_getCursorExtent(CXCursor C) {
6229 SourceRange R = getRawCursorExtent(C);
6230 if (R.isInvalid())
6231 return clang_getNullRange();
6232
6233 return cxloc::translateSourceRange(getCursorContext(C), R);
6234}
6235
6236CXCursor clang_getCursorReferenced(CXCursor C) {
6237 if (clang_isInvalid(C.kind))
6238 return clang_getNullCursor();
6239
6240 CXTranslationUnit tu = getCursorTU(C);
6241 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006242 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006243 if (!D)
6244 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006245 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006246 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006247 if (const ObjCPropertyImplDecl *PropImpl =
6248 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006249 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6250 return MakeCXCursor(Property, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006251
Guy Benyei11169dd2012-12-18 14:30:41 +00006252 return C;
6253 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006254
Guy Benyei11169dd2012-12-18 14:30:41 +00006255 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006256 const Expr *E = getCursorExpr(C);
6257 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00006258 if (D) {
6259 CXCursor declCursor = MakeCXCursor(D, tu);
6260 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6261 declCursor);
6262 return declCursor;
6263 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006264
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006265 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00006266 return MakeCursorOverloadedDeclRef(Ovl, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006267
Guy Benyei11169dd2012-12-18 14:30:41 +00006268 return clang_getNullCursor();
6269 }
6270
6271 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006272 const Stmt *S = getCursorStmt(C);
6273 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00006274 if (LabelDecl *label = Goto->getLabel())
6275 if (LabelStmt *labelS = label->getStmt())
Michael Kruse7520cf02020-03-25 09:26:14 -05006276 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006277
6278 return clang_getNullCursor();
6279 }
Richard Smith66a81862015-05-04 02:25:31 +00006280
Guy Benyei11169dd2012-12-18 14:30:41 +00006281 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00006282 if (const MacroDefinitionRecord *Def =
6283 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006284 return MakeMacroDefinitionCursor(Def, tu);
6285 }
6286
6287 if (!clang_isReference(C.kind))
6288 return clang_getNullCursor();
6289
6290 switch (C.kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006291 case CXCursor_ObjCSuperClassRef:
6292 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006293
Michael Kruse7520cf02020-03-25 09:26:14 -05006294 case CXCursor_ObjCProtocolRef: {
6295 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6296 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6297 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006298
Michael Kruse7520cf02020-03-25 09:26:14 -05006299 return MakeCXCursor(Prot, tu);
6300 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006301
Michael Kruse7520cf02020-03-25 09:26:14 -05006302 case CXCursor_ObjCClassRef: {
6303 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6304 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6305 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006306
Michael Kruse7520cf02020-03-25 09:26:14 -05006307 return MakeCXCursor(Class, tu);
6308 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006309
Michael Kruse7520cf02020-03-25 09:26:14 -05006310 case CXCursor_TypeRef:
6311 return MakeCXCursor(getCursorTypeRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006312
Michael Kruse7520cf02020-03-25 09:26:14 -05006313 case CXCursor_TemplateRef:
6314 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006315
Michael Kruse7520cf02020-03-25 09:26:14 -05006316 case CXCursor_NamespaceRef:
6317 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006318
Michael Kruse7520cf02020-03-25 09:26:14 -05006319 case CXCursor_MemberRef:
6320 return MakeCXCursor(getCursorMemberRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006321
Michael Kruse7520cf02020-03-25 09:26:14 -05006322 case CXCursor_CXXBaseSpecifier: {
6323 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6324 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6325 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006326
Michael Kruse7520cf02020-03-25 09:26:14 -05006327 case CXCursor_LabelRef:
6328 // FIXME: We end up faking the "parent" declaration here because we
6329 // don't want to make CXCursor larger.
6330 return MakeCXCursor(
6331 getCursorLabelRef(C).first,
6332 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006333
Michael Kruse7520cf02020-03-25 09:26:14 -05006334 case CXCursor_OverloadedDeclRef:
6335 return C;
Guy Benyei11169dd2012-12-18 14:30:41 +00006336
Michael Kruse7520cf02020-03-25 09:26:14 -05006337 case CXCursor_VariableRef:
6338 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6339
6340 default:
6341 // We would prefer to enumerate all non-reference cursor kinds here.
6342 llvm_unreachable("Unhandled reference cursor kind");
Guy Benyei11169dd2012-12-18 14:30:41 +00006343 }
6344}
6345
6346CXCursor clang_getCursorDefinition(CXCursor C) {
6347 if (clang_isInvalid(C.kind))
6348 return clang_getNullCursor();
6349
6350 CXTranslationUnit TU = getCursorTU(C);
6351
6352 bool WasReference = false;
6353 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6354 C = clang_getCursorReferenced(C);
6355 WasReference = true;
6356 }
6357
6358 if (C.kind == CXCursor_MacroExpansion)
6359 return clang_getCursorReferenced(C);
6360
6361 if (!clang_isDeclaration(C.kind))
6362 return clang_getNullCursor();
6363
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006364 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 if (!D)
6366 return clang_getNullCursor();
6367
6368 switch (D->getKind()) {
6369 // Declaration kinds that don't really separate the notions of
6370 // declaration and definition.
6371 case Decl::Namespace:
6372 case Decl::Typedef:
6373 case Decl::TypeAlias:
6374 case Decl::TypeAliasTemplate:
6375 case Decl::TemplateTypeParm:
6376 case Decl::EnumConstant:
6377 case Decl::Field:
Richard Smithbdb84f32016-07-22 23:36:59 +00006378 case Decl::Binding:
John McCall5e77d762013-04-16 07:28:30 +00006379 case Decl::MSProperty:
Richard Smithbab6df82020-04-11 22:15:29 -07006380 case Decl::MSGuid:
Richard Smithba4768c2020-09-20 23:16:08 -07006381 case Decl::TemplateParamObject:
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 case Decl::IndirectField:
6383 case Decl::ObjCIvar:
6384 case Decl::ObjCAtDefsField:
6385 case Decl::ImplicitParam:
6386 case Decl::ParmVar:
6387 case Decl::NonTypeTemplateParm:
6388 case Decl::TemplateTemplateParm:
6389 case Decl::ObjCCategoryImpl:
6390 case Decl::ObjCImplementation:
6391 case Decl::AccessSpec:
6392 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006393 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006394 case Decl::ObjCPropertyImpl:
6395 case Decl::FileScopeAsm:
6396 case Decl::StaticAssert:
6397 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006398 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006399 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006400 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006401 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006402 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006403 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006404 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006405 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006406 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006407 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006408 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006409 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006410 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006411 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006412 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006413 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006414 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006415 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006416 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006417 return C;
6418
6419 // Declaration kinds that don't make any sense here, but are
6420 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006421 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006422 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006423 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006424 break;
6425
6426 // Declaration kinds for which the definition is not resolvable.
6427 case Decl::UnresolvedUsingTypename:
6428 case Decl::UnresolvedUsingValue:
6429 break;
6430
6431 case Decl::UsingDirective:
6432 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6433 TU);
6434
6435 case Decl::NamespaceAlias:
6436 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6437
6438 case Decl::Enum:
6439 case Decl::Record:
6440 case Decl::CXXRecord:
6441 case Decl::ClassTemplateSpecialization:
6442 case Decl::ClassTemplatePartialSpecialization:
6443 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6444 return MakeCXCursor(Def, TU);
6445 return clang_getNullCursor();
6446
6447 case Decl::Function:
6448 case Decl::CXXMethod:
6449 case Decl::CXXConstructor:
6450 case Decl::CXXDestructor:
6451 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006452 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006454 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006455 return clang_getNullCursor();
6456 }
6457
Larisse Voufo39a1e502013-08-06 01:03:05 +00006458 case Decl::Var:
6459 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006460 case Decl::VarTemplatePartialSpecialization:
6461 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006463 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006464 return MakeCXCursor(Def, TU);
6465 return clang_getNullCursor();
6466 }
6467
6468 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006469 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006470 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6471 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6472 return clang_getNullCursor();
6473 }
6474
6475 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006476 if (RecordDecl *Def =
6477 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006478 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6479 TU);
6480 return clang_getNullCursor();
6481 }
6482
Larisse Voufo39a1e502013-08-06 01:03:05 +00006483 case Decl::VarTemplate: {
6484 if (VarDecl *Def =
6485 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6486 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6487 return clang_getNullCursor();
6488 }
6489
Guy Benyei11169dd2012-12-18 14:30:41 +00006490 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006491 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6492 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006493
6494 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006495 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006496 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006497 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006498
6499 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006500 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006501 if (Method->isThisDeclarationADefinition())
6502 return C;
6503
6504 // Dig out the method definition in the associated
6505 // @implementation, if we have it.
6506 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006507 if (const ObjCInterfaceDecl *Class =
6508 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006509 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006510 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6511 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006512 if (Def->isThisDeclarationADefinition())
6513 return MakeCXCursor(Def, TU);
6514
6515 return clang_getNullCursor();
6516 }
6517
6518 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006519 if (ObjCCategoryImplDecl *Impl =
6520 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006521 return MakeCXCursor(Impl, TU);
6522 return clang_getNullCursor();
6523
6524 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006525 if (const ObjCProtocolDecl *Def =
6526 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006527 return MakeCXCursor(Def, TU);
6528 return clang_getNullCursor();
6529
6530 case Decl::ObjCInterface: {
6531 // There are two notions of a "definition" for an Objective-C
6532 // class: the interface and its implementation. When we resolved a
6533 // reference to an Objective-C class, produce the @interface as
6534 // the definition; when we were provided with the interface,
6535 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006536 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006537 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006538 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006539 return MakeCXCursor(Def, TU);
6540 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6541 return MakeCXCursor(Impl, TU);
6542 return clang_getNullCursor();
6543 }
6544
6545 case Decl::ObjCProperty:
6546 // FIXME: We don't really know where to find the
6547 // ObjCPropertyImplDecls that implement this property.
6548 return clang_getNullCursor();
6549
6550 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006551 if (const ObjCInterfaceDecl *Class =
6552 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006553 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006554 return MakeCXCursor(Def, TU);
6555
6556 return clang_getNullCursor();
6557
6558 case Decl::Friend:
6559 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6560 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6561 return clang_getNullCursor();
6562
6563 case Decl::FriendTemplate:
6564 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6565 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6566 return clang_getNullCursor();
6567 }
6568
6569 return clang_getNullCursor();
6570}
6571
6572unsigned clang_isCursorDefinition(CXCursor C) {
6573 if (!clang_isDeclaration(C.kind))
6574 return 0;
6575
6576 return clang_getCursorDefinition(C) == C;
6577}
6578
6579CXCursor clang_getCanonicalCursor(CXCursor C) {
6580 if (!clang_isDeclaration(C.kind))
6581 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006582
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006583 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006584 if (const ObjCCategoryImplDecl *CatImplD =
6585 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006586 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6587 return MakeCXCursor(CatD, getCursorTU(C));
6588
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006589 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6590 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006591 return MakeCXCursor(IFD, getCursorTU(C));
6592
6593 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6594 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006595
Guy Benyei11169dd2012-12-18 14:30:41 +00006596 return C;
6597}
6598
6599int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6600 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6601}
Michael Kruse7520cf02020-03-25 09:26:14 -05006602
Guy Benyei11169dd2012-12-18 14:30:41 +00006603unsigned clang_getNumOverloadedDecls(CXCursor C) {
6604 if (C.kind != CXCursor_OverloadedDeclRef)
6605 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006606
Guy Benyei11169dd2012-12-18 14:30:41 +00006607 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006608 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006609 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006610
6611 if (OverloadedTemplateStorage *S =
6612 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006613 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006614
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006615 const Decl *D = Storage.get<const Decl *>();
6616 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006617 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006618
Guy Benyei11169dd2012-12-18 14:30:41 +00006619 return 0;
6620}
6621
6622CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6623 if (cursor.kind != CXCursor_OverloadedDeclRef)
6624 return clang_getNullCursor();
6625
6626 if (index >= clang_getNumOverloadedDecls(cursor))
6627 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006628
Guy Benyei11169dd2012-12-18 14:30:41 +00006629 CXTranslationUnit TU = getCursorTU(cursor);
6630 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006631 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006632 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006633
6634 if (OverloadedTemplateStorage *S =
6635 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006636 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006637
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006638 const Decl *D = Storage.get<const Decl *>();
6639 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006640 // FIXME: This is, unfortunately, linear time.
6641 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6642 std::advance(Pos, index);
6643 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6644 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006645
Guy Benyei11169dd2012-12-18 14:30:41 +00006646 return clang_getNullCursor();
6647}
Michael Kruse7520cf02020-03-25 09:26:14 -05006648
6649void clang_getDefinitionSpellingAndExtent(
6650 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6651 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006652 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006653 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006654 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6655
6656 SourceManager &SM = FD->getASTContext().getSourceManager();
6657 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6658 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6659 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6660 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6661 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6662 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6663}
6664
Guy Benyei11169dd2012-12-18 14:30:41 +00006665CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6666 unsigned PieceIndex) {
6667 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006668
Guy Benyei11169dd2012-12-18 14:30:41 +00006669 switch (C.kind) {
6670 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006671 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006672 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6673 E->getQualifierLoc().getSourceRange());
6674 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006675
Guy Benyei11169dd2012-12-18 14:30:41 +00006676 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006677 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6678 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6679 Pieces =
6680 buildPieces(NameFlags, false, E->getNameInfo(),
6681 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6682 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006683 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006684
Guy Benyei11169dd2012-12-18 14:30:41 +00006685 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006686 if (const CXXOperatorCallExpr *OCE =
6687 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006688 const Expr *Callee = OCE->getCallee();
6689 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006690 Callee = ICE->getSubExpr();
6691
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006692 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006693 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6694 DRE->getQualifierLoc().getSourceRange());
6695 }
6696 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006697
Guy Benyei11169dd2012-12-18 14:30:41 +00006698 default:
6699 break;
6700 }
6701
6702 if (Pieces.empty()) {
6703 if (PieceIndex == 0)
6704 return clang_getCursorExtent(C);
6705 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006706 SourceRange R = Pieces[PieceIndex];
6707 if (R.isValid())
6708 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006709 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006710
Guy Benyei11169dd2012-12-18 14:30:41 +00006711 return clang_getNullRange();
6712}
6713
6714void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006715 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6716 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006717}
6718
Michael Kruse7520cf02020-03-25 09:26:14 -05006719void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006720 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006721 llvm::llvm_execute_on_thread(fn, user_data,
6722 stack_size == 0
6723 ? clang::DesiredStackSize
6724 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006725}
6726
Guy Benyei11169dd2012-12-18 14:30:41 +00006727//===----------------------------------------------------------------------===//
6728// Token-based Operations.
6729//===----------------------------------------------------------------------===//
6730
6731/* CXToken layout:
6732 * int_data[0]: a CXTokenKind
6733 * int_data[1]: starting token location
6734 * int_data[2]: token length
6735 * int_data[3]: reserved
6736 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6737 * otherwise unused.
6738 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006739CXTokenKind clang_getTokenKind(CXToken CXTok) {
6740 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6741}
6742
6743CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6744 switch (clang_getTokenKind(CXTok)) {
6745 case CXToken_Identifier:
6746 case CXToken_Keyword:
6747 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006748 return cxstring::createRef(
6749 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006750
6751 case CXToken_Literal: {
6752 // We have stashed the starting pointer in the ptr_data field. Use it.
6753 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006754 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006755 }
6756
6757 case CXToken_Punctuation:
6758 case CXToken_Comment:
6759 break;
6760 }
6761
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006762 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006763 LOG_BAD_TU(TU);
6764 return cxstring::createEmpty();
6765 }
6766
Guy Benyei11169dd2012-12-18 14:30:41 +00006767 // We have to find the starting buffer pointer the hard way, by
6768 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006769 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006770 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006771 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006772
6773 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006774 std::pair<FileID, unsigned> LocInfo =
6775 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006776 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006777 StringRef Buffer =
6778 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006779 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006780 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006781
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006782 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006783}
6784
6785CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006786 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006787 LOG_BAD_TU(TU);
6788 return clang_getNullLocation();
6789 }
6790
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006791 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006792 if (!CXXUnit)
6793 return clang_getNullLocation();
6794
Michael Kruse7520cf02020-03-25 09:26:14 -05006795 return cxloc::translateSourceLocation(
6796 CXXUnit->getASTContext(),
6797 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006798}
6799
6800CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006801 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006802 LOG_BAD_TU(TU);
6803 return clang_getNullRange();
6804 }
6805
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006806 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006807 if (!CXXUnit)
6808 return clang_getNullRange();
6809
Michael Kruse7520cf02020-03-25 09:26:14 -05006810 return cxloc::translateSourceRange(
6811 CXXUnit->getASTContext(),
6812 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006813}
6814
6815static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6816 SmallVectorImpl<CXToken> &CXTokens) {
6817 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006818 std::pair<FileID, unsigned> BeginLocInfo =
6819 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6820 std::pair<FileID, unsigned> EndLocInfo =
6821 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006822
6823 // Cannot tokenize across files.
6824 if (BeginLocInfo.first != EndLocInfo.first)
6825 return;
6826
6827 // Create a lexer
6828 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006829 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006830 if (Invalid)
6831 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006832
Guy Benyei11169dd2012-12-18 14:30:41 +00006833 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006834 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6835 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006836 Lex.SetCommentRetentionState(true);
6837
6838 // Lex tokens until we hit the end of the range.
6839 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6840 Token Tok;
6841 bool previousWasAt = false;
6842 do {
6843 // Lex the next token
6844 Lex.LexFromRawLexer(Tok);
6845 if (Tok.is(tok::eof))
6846 break;
6847
6848 // Initialize the CXToken.
6849 CXToken CXTok;
6850
6851 // - Common fields
6852 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6853 CXTok.int_data[2] = Tok.getLength();
6854 CXTok.int_data[3] = 0;
6855
6856 // - Kind-specific fields
6857 if (Tok.isLiteral()) {
6858 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006859 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006860 } else if (Tok.is(tok::raw_identifier)) {
6861 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006862 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006863
6864 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6865 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006866 } else {
6867 CXTok.int_data[0] =
6868 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006869 }
6870 CXTok.ptr_data = II;
6871 } else if (Tok.is(tok::comment)) {
6872 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006873 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006874 } else {
6875 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006876 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006877 }
6878 CXTokens.push_back(CXTok);
6879 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006880 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006881}
6882
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006883CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006884 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006885
6886 if (isNotUsableTU(TU)) {
6887 LOG_BAD_TU(TU);
6888 return NULL;
6889 }
6890
6891 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6892 if (!CXXUnit)
6893 return NULL;
6894
6895 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6896 if (Begin.isInvalid())
6897 return NULL;
6898 SourceManager &SM = CXXUnit->getSourceManager();
6899 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006900 DecomposedEnd.second +=
6901 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006902
Michael Kruse7520cf02020-03-25 09:26:14 -05006903 SourceLocation End =
6904 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006905
6906 SmallVector<CXToken, 32> CXTokens;
6907 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6908
6909 if (CXTokens.empty())
6910 return NULL;
6911
6912 CXTokens.resize(1);
6913 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6914
6915 memmove(Token, CXTokens.data(), sizeof(CXToken));
6916 return Token;
6917}
6918
Michael Kruse7520cf02020-03-25 09:26:14 -05006919void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6920 unsigned *NumTokens) {
6921 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006922
Guy Benyei11169dd2012-12-18 14:30:41 +00006923 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006924 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006925 if (NumTokens)
6926 *NumTokens = 0;
6927
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006928 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006929 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006930 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006931 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006932
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006933 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006934 if (!CXXUnit || !Tokens || !NumTokens)
6935 return;
6936
6937 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006938
Guy Benyei11169dd2012-12-18 14:30:41 +00006939 SourceRange R = cxloc::translateCXSourceRange(Range);
6940 if (R.isInvalid())
6941 return;
6942
6943 SmallVector<CXToken, 32> CXTokens;
6944 getTokens(CXXUnit, R, CXTokens);
6945
6946 if (CXTokens.empty())
6947 return;
6948
Serge Pavlov52525732018-02-21 02:02:39 +00006949 *Tokens = static_cast<CXToken *>(
6950 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006951 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6952 *NumTokens = CXTokens.size();
6953}
6954
Michael Kruse7520cf02020-03-25 09:26:14 -05006955void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6956 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006957 free(Tokens);
6958}
6959
Guy Benyei11169dd2012-12-18 14:30:41 +00006960//===----------------------------------------------------------------------===//
6961// Token annotation APIs.
6962//===----------------------------------------------------------------------===//
6963
Guy Benyei11169dd2012-12-18 14:30:41 +00006964static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6965 CXCursor parent,
6966 CXClientData client_data);
6967static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6968 CXClientData client_data);
6969
6970namespace {
6971class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006972 CXToken *Tokens;
6973 CXCursor *Cursors;
6974 unsigned NumTokens;
6975 unsigned TokIdx;
6976 unsigned PreprocessingTokIdx;
6977 CursorVisitor AnnotateVis;
6978 SourceManager &SrcMgr;
6979 bool HasContextSensitiveKeywords;
6980
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006981 struct PostChildrenAction {
6982 CXCursor cursor;
6983 enum Action { Invalid, Ignore, Postpone } action;
6984 };
6985 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6986
Guy Benyei11169dd2012-12-18 14:30:41 +00006987 struct PostChildrenInfo {
6988 CXCursor Cursor;
6989 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006990 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006991 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006992 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006993 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006994 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006995
6996 CXToken &getTok(unsigned Idx) {
6997 assert(Idx < NumTokens);
6998 return Tokens[Idx];
6999 }
7000 const CXToken &getTok(unsigned Idx) const {
7001 assert(Idx < NumTokens);
7002 return Tokens[Idx];
7003 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007004 bool MoreTokens() const { return TokIdx < NumTokens; }
7005 unsigned NextToken() const { return TokIdx; }
7006 void AdvanceToken() { ++TokIdx; }
7007 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007008 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007009 }
7010 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007011 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007012 }
7013 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007014 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007015 }
7016
7017 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007018 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00007019 SourceRange);
7020
7021public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007022 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007023 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05007024 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
7025 PreprocessingTokIdx(0),
7026 AnnotateVis(TU, AnnotateTokensVisitor, this,
7027 /*VisitPreprocessorLast=*/true,
7028 /*VisitIncludedEntities=*/false, RegionOfInterest,
7029 /*VisitDeclsOnly=*/false,
7030 AnnotateTokensPostChildrenVisitor),
7031 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
7032 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007033
7034 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
7035 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007036 bool IsIgnoredChildCursor(CXCursor cursor) const;
7037 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
7038
Guy Benyei11169dd2012-12-18 14:30:41 +00007039 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007040 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
7041 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
7042
Guy Benyei11169dd2012-12-18 14:30:41 +00007043 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05007044
7045 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00007046 /// context-sensitive keywords.
7047 bool hasContextSensitiveKeywords() const {
7048 return HasContextSensitiveKeywords;
7049 }
7050
Michael Kruse7520cf02020-03-25 09:26:14 -05007051 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00007052};
Michael Kruse7520cf02020-03-25 09:26:14 -05007053} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00007054
7055void AnnotateTokensWorker::AnnotateTokens() {
7056 // Walk the AST within the region of interest, annotating tokens
7057 // along the way.
7058 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007059}
Guy Benyei11169dd2012-12-18 14:30:41 +00007060
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007061bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7062 if (PostChildrenInfos.empty())
7063 return false;
7064
7065 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7066 if (ChildAction.cursor == cursor &&
7067 ChildAction.action == PostChildrenAction::Ignore) {
7068 return true;
7069 }
7070 }
7071
7072 return false;
7073}
7074
7075const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7076 if (!clang_isExpression(Cursor.kind))
7077 return nullptr;
7078
7079 const Expr *E = getCursorExpr(Cursor);
7080 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7081 const OverloadedOperatorKind Kind = OCE->getOperator();
7082 if (Kind == OO_Call || Kind == OO_Subscript)
7083 return OCE;
7084 }
7085
7086 return nullptr;
7087}
7088
7089AnnotateTokensWorker::PostChildrenActions
7090AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7091 PostChildrenActions actions;
7092
7093 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7094 // visited before the arguments to the operator call. For the Call and
7095 // Subscript operator the range of this DeclRefExpr includes the whole call
7096 // expression, so that all tokens in that range would be mapped to the
7097 // operator function, including the tokens of the arguments. To avoid that,
7098 // ensure to visit this DeclRefExpr as last node.
7099 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7100 const Expr *Callee = OCE->getCallee();
7101 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7102 const Expr *SubExpr = ICE->getSubExpr();
7103 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007104 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007105 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7106
7107 // Visit the DeclRefExpr as last.
7108 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7109 actions.push_back({cxChild, PostChildrenAction::Postpone});
7110
7111 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7112 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7113 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7114 actions.push_back({cxChild, PostChildrenAction::Ignore});
7115 }
7116 }
7117 }
7118
7119 return actions;
7120}
7121
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007122static inline void updateCursorAnnotation(CXCursor &Cursor,
7123 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007124 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007125 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007126 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007127}
7128
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007129/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007130//// between the cursor location and the source range is the same as
7131/// \arg compResult.
7132///
7133/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7134/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007135void AnnotateTokensWorker::annotateAndAdvanceTokens(
7136 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007137 while (MoreTokens()) {
7138 const unsigned I = NextToken();
7139 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007140 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7141 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007142
7143 SourceLocation TokLoc = GetTokenLoc(I);
7144 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007145 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007146 AdvanceToken();
7147 continue;
7148 }
7149 break;
7150 }
7151}
7152
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007153/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007154/// \returns true if it advanced beyond all macro tokens, false otherwise.
7155bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007156 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007157 assert(MoreTokens());
7158 assert(isFunctionMacroToken(NextToken()) &&
7159 "Should be called only for macro arg tokens");
7160
7161 // This works differently than annotateAndAdvanceTokens; because expanded
7162 // macro arguments can have arbitrary translation-unit source order, we do not
7163 // advance the token index one by one until a token fails the range test.
7164 // We only advance once past all of the macro arg tokens if all of them
7165 // pass the range test. If one of them fails we keep the token index pointing
7166 // at the start of the macro arg tokens so that the failing token will be
7167 // annotated by a subsequent annotation try.
7168
7169 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007170
Guy Benyei11169dd2012-12-18 14:30:41 +00007171 unsigned I = NextToken();
7172 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7173 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7174 if (TokLoc.isFileID())
7175 continue; // not macro arg token, it's parens or comma.
7176 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7177 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7178 Cursors[I] = updateC;
7179 } else
7180 atLeastOneCompFail = true;
7181 }
7182
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007183 if (atLeastOneCompFail)
7184 return false;
7185
7186 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7187 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007188}
7189
Michael Kruse7520cf02020-03-25 09:26:14 -05007190enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7191 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007192 SourceRange cursorRange = getRawCursorExtent(cursor);
7193 if (cursorRange.isInvalid())
7194 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007195
7196 if (IsIgnoredChildCursor(cursor))
7197 return CXChildVisit_Continue;
7198
Guy Benyei11169dd2012-12-18 14:30:41 +00007199 if (!HasContextSensitiveKeywords) {
7200 // Objective-C properties can have context-sensitive keywords.
7201 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007202 if (const ObjCPropertyDecl *Property =
7203 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7204 HasContextSensitiveKeywords =
7205 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007206 }
7207 // Objective-C methods can have context-sensitive keywords.
7208 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7209 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007210 if (const ObjCMethodDecl *Method =
7211 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007212 if (Method->getObjCDeclQualifier())
7213 HasContextSensitiveKeywords = true;
7214 else {
David Majnemer59f77922016-06-24 04:05:48 +00007215 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007216 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007217 HasContextSensitiveKeywords = true;
7218 break;
7219 }
7220 }
7221 }
7222 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007223 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007224 // C++ methods can have context-sensitive keywords.
7225 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007226 if (const CXXMethodDecl *Method =
7227 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007228 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7229 HasContextSensitiveKeywords = true;
7230 }
7231 }
7232 // C++ classes can have context-sensitive keywords.
7233 else if (cursor.kind == CXCursor_StructDecl ||
7234 cursor.kind == CXCursor_ClassDecl ||
7235 cursor.kind == CXCursor_ClassTemplate ||
7236 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007237 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007238 if (D->hasAttr<FinalAttr>())
7239 HasContextSensitiveKeywords = true;
7240 }
7241 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007242
7243 // Don't override a property annotation with its getter/setter method.
7244 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7245 parent.kind == CXCursor_ObjCPropertyDecl)
7246 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007247
7248 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007249 // Items in the preprocessing record are kept separate from items in
7250 // declarations, so we keep a separate token index.
7251 unsigned SavedTokIdx = TokIdx;
7252 TokIdx = PreprocessingTokIdx;
7253
7254 // Skip tokens up until we catch up to the beginning of the preprocessing
7255 // entry.
7256 while (MoreTokens()) {
7257 const unsigned I = NextToken();
7258 SourceLocation TokLoc = GetTokenLoc(I);
7259 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7260 case RangeBefore:
7261 AdvanceToken();
7262 continue;
7263 case RangeAfter:
7264 case RangeOverlap:
7265 break;
7266 }
7267 break;
7268 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007269
Guy Benyei11169dd2012-12-18 14:30:41 +00007270 // Look at all of the tokens within this range.
7271 while (MoreTokens()) {
7272 const unsigned I = NextToken();
7273 SourceLocation TokLoc = GetTokenLoc(I);
7274 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7275 case RangeBefore:
7276 llvm_unreachable("Infeasible");
7277 case RangeAfter:
7278 break;
7279 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007280 // For macro expansions, just note where the beginning of the macro
7281 // expansion occurs.
7282 if (cursor.kind == CXCursor_MacroExpansion) {
7283 if (TokLoc == cursorRange.getBegin())
7284 Cursors[I] = cursor;
7285 AdvanceToken();
7286 break;
7287 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007288 // We may have already annotated macro names inside macro definitions.
7289 if (Cursors[I].kind != CXCursor_MacroExpansion)
7290 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007291 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007292 continue;
7293 }
7294 break;
7295 }
7296
7297 // Save the preprocessing token index; restore the non-preprocessing
7298 // token index.
7299 PreprocessingTokIdx = TokIdx;
7300 TokIdx = SavedTokIdx;
7301 return CXChildVisit_Recurse;
7302 }
7303
7304 if (cursorRange.isInvalid())
7305 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007306
7307 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007308 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007309 const enum CXCursorKind K = clang_getCursorKind(parent);
7310 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007311 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7312 // Attributes are annotated out-of-order, skip tokens until we reach it.
7313 clang_isAttribute(cursor.kind))
7314 ? clang_getNullCursor()
7315 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007316
7317 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7318
7319 // Avoid having the cursor of an expression "overwrite" the annotation of the
7320 // variable declaration that it belongs to.
7321 // This can happen for C++ constructor expressions whose range generally
7322 // include the variable declaration, e.g.:
7323 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007324 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007325 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007326 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007327 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007328 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7329 E->getBeginLoc() == D->getLocation() &&
7330 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007331 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007332 AdvanceToken();
7333 }
7334 }
7335 }
7336
7337 // Before recursing into the children keep some state that we are going
7338 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7339 // extra work after the child nodes are visited.
7340 // Note that we don't call VisitChildren here to avoid traversing statements
7341 // code-recursively which can blow the stack.
7342
7343 PostChildrenInfo Info;
7344 Info.Cursor = cursor;
7345 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007346 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007347 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007348 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007349 PostChildrenInfos.push_back(Info);
7350
7351 return CXChildVisit_Recurse;
7352}
7353
7354bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7355 if (PostChildrenInfos.empty())
7356 return false;
7357 const PostChildrenInfo &Info = PostChildrenInfos.back();
7358 if (!clang_equalCursors(Info.Cursor, cursor))
7359 return false;
7360
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007361 HandlePostPonedChildCursors(Info);
7362
Guy Benyei11169dd2012-12-18 14:30:41 +00007363 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7364 const unsigned AfterChildren = NextToken();
7365 SourceRange cursorRange = Info.CursorRange;
7366
7367 // Scan the tokens that are at the end of the cursor, but are not captured
7368 // but the child cursors.
7369 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7370
7371 // Scan the tokens that are at the beginning of the cursor, but are not
7372 // capture by the child cursors.
7373 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7374 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7375 break;
7376
7377 Cursors[I] = cursor;
7378 }
7379
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007380 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7381 // encountered the attribute cursor.
7382 if (clang_isAttribute(cursor.kind))
7383 TokIdx = Info.BeforeReachingCursorIdx;
7384
Guy Benyei11169dd2012-12-18 14:30:41 +00007385 PostChildrenInfos.pop_back();
7386 return false;
7387}
7388
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007389void AnnotateTokensWorker::HandlePostPonedChildCursors(
7390 const PostChildrenInfo &Info) {
7391 for (const auto &ChildAction : Info.ChildActions) {
7392 if (ChildAction.action == PostChildrenAction::Postpone) {
7393 HandlePostPonedChildCursor(ChildAction.cursor,
7394 Info.BeforeChildrenTokenIdx);
7395 }
7396 }
7397}
7398
7399void AnnotateTokensWorker::HandlePostPonedChildCursor(
7400 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007401 unsigned I = StartTokenIndex;
7402
7403 // The bracket tokens of a Call or Subscript operator are mapped to
7404 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7405 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7406 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007407 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7408 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007409 if (clang_Range_isNull(CXRefNameRange))
7410 break; // All ranges handled.
7411
7412 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7413 while (I < NumTokens) {
7414 const SourceLocation TokenLocation = GetTokenLoc(I);
7415 if (!TokenLocation.isValid())
7416 break;
7417
7418 // Adapt the end range, because LocationCompare() reports
7419 // RangeOverlap even for the not-inclusive end location.
7420 const SourceLocation fixedEnd =
7421 RefNameRange.getEnd().getLocWithOffset(-1);
7422 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7423
7424 const RangeComparisonResult ComparisonResult =
7425 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7426
7427 if (ComparisonResult == RangeOverlap) {
7428 Cursors[I++] = Cursor;
7429 } else if (ComparisonResult == RangeBefore) {
7430 ++I; // Not relevant token, check next one.
7431 } else if (ComparisonResult == RangeAfter) {
7432 break; // All tokens updated for current range, check next.
7433 }
7434 }
7435 }
7436}
7437
Guy Benyei11169dd2012-12-18 14:30:41 +00007438static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7439 CXCursor parent,
7440 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007441 return static_cast<AnnotateTokensWorker *>(client_data)
7442 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007443}
7444
7445static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7446 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007447 return static_cast<AnnotateTokensWorker *>(client_data)
7448 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007449}
7450
7451namespace {
7452
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007453/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007454/// and mark tokens that are macro arguments. This info is used by the
7455/// AnnotateTokensWorker.
7456class MarkMacroArgTokensVisitor {
7457 SourceManager &SM;
7458 CXToken *Tokens;
7459 unsigned NumTokens;
7460 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007461
Guy Benyei11169dd2012-12-18 14:30:41 +00007462public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007463 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7464 unsigned numTokens)
7465 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007466
7467 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7468 if (cursor.kind != CXCursor_MacroExpansion)
7469 return CXChildVisit_Continue;
7470
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007471 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007472 if (macroRange.getBegin() == macroRange.getEnd())
7473 return CXChildVisit_Continue; // it's not a function macro.
7474
7475 for (; CurIdx < NumTokens; ++CurIdx) {
7476 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7477 macroRange.getBegin()))
7478 break;
7479 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007480
Guy Benyei11169dd2012-12-18 14:30:41 +00007481 if (CurIdx == NumTokens)
7482 return CXChildVisit_Break;
7483
7484 for (; CurIdx < NumTokens; ++CurIdx) {
7485 SourceLocation tokLoc = getTokenLoc(CurIdx);
7486 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7487 break;
7488
7489 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7490 }
7491
7492 if (CurIdx == NumTokens)
7493 return CXChildVisit_Break;
7494
7495 return CXChildVisit_Continue;
7496 }
7497
7498private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007499 CXToken &getTok(unsigned Idx) {
7500 assert(Idx < NumTokens);
7501 return Tokens[Idx];
7502 }
7503 const CXToken &getTok(unsigned Idx) const {
7504 assert(Idx < NumTokens);
7505 return Tokens[Idx];
7506 }
7507
Guy Benyei11169dd2012-12-18 14:30:41 +00007508 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007509 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007510 }
7511
7512 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7513 // The third field is reserved and currently not used. Use it here
7514 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007515 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007516 }
7517};
7518
7519} // end anonymous namespace
7520
7521static CXChildVisitResult
7522MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7523 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007524 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7525 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007526}
7527
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007528/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007529/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007530static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7531 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007532 if (NextIdx >= NumTokens)
7533 return true;
7534
7535 ++NextIdx;
7536 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007537 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007538}
7539
Guy Benyei11169dd2012-12-18 14:30:41 +00007540static void annotatePreprocessorTokens(CXTranslationUnit TU,
7541 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007542 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007543 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007544 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007545
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007546 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007547 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007548 std::pair<FileID, unsigned> BeginLocInfo =
7549 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7550 std::pair<FileID, unsigned> EndLocInfo =
7551 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007552
7553 if (BeginLocInfo.first != EndLocInfo.first)
7554 return;
7555
7556 StringRef Buffer;
7557 bool Invalid = false;
7558 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7559 if (Buffer.empty() || Invalid)
7560 return;
7561
7562 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007563 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7564 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007565 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007566
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007567 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007568 // Lex tokens in raw mode until we hit the end of the range, to avoid
7569 // entering #includes or expanding macros.
7570 while (true) {
7571 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007572 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7573 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007574 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007575 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007576 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7577
Guy Benyei11169dd2012-12-18 14:30:41 +00007578 reprocess:
7579 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007580 // We have found a preprocessing directive. Annotate the tokens
7581 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007582 //
7583 // FIXME: Some simple tests here could identify macro definitions and
7584 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007585
7586 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007587 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7588 break;
7589
Craig Topper69186e72014-06-08 08:38:04 +00007590 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007591 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007592 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7593 break;
7594
7595 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007596 IdentifierInfo &II =
7597 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007598 SourceLocation MappedTokLoc =
7599 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7600 MI = getMacroInfo(II, MappedTokLoc, TU);
7601 }
7602 }
7603
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007604 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007605 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007606 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7607 finished = true;
7608 break;
7609 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007610 // If we are in a macro definition, check if the token was ever a
7611 // macro name and annotate it if that's the case.
7612 if (MI) {
7613 SourceLocation SaveLoc = Tok.getLocation();
7614 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007615 MacroDefinitionRecord *MacroDef =
7616 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007617 Tok.setLocation(SaveLoc);
7618 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007619 Cursors[NextIdx - 1] =
7620 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007621 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007622 } while (!Tok.isAtStartOfLine());
7623
Michael Kruse7520cf02020-03-25 09:26:14 -05007624 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007625 assert(TokIdx <= LastIdx);
7626 SourceLocation EndLoc =
7627 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7628 CXCursor Cursor =
7629 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7630
7631 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007632 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007633
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007634 if (finished)
7635 break;
7636 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007637 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007638 }
7639}
7640
7641// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007642static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7643 CXToken *Tokens, unsigned NumTokens,
7644 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007645 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007646 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7647 setThreadBackgroundPriority();
7648
7649 // Determine the region of interest, which contains all of the tokens.
7650 SourceRange RegionOfInterest;
7651 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007652 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7653 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7654 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007655
Guy Benyei11169dd2012-12-18 14:30:41 +00007656 // Relex the tokens within the source range to look for preprocessing
7657 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007658 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007659
7660 // If begin location points inside a macro argument, set it to the expansion
7661 // location so we can have the full context when annotating semantically.
7662 {
7663 SourceManager &SM = CXXUnit->getSourceManager();
7664 SourceLocation Loc =
7665 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7666 if (Loc.isMacroID())
7667 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7668 }
7669
Guy Benyei11169dd2012-12-18 14:30:41 +00007670 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7671 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007672 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7673 NumTokens);
7674 CursorVisitor MacroArgMarker(
7675 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7676 /*VisitPreprocessorLast=*/true,
7677 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007678 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7679 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007680
Guy Benyei11169dd2012-12-18 14:30:41 +00007681 // Annotate all of the source locations in the region of interest that map to
7682 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007683 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007684
Guy Benyei11169dd2012-12-18 14:30:41 +00007685 // FIXME: We use a ridiculous stack size here because the data-recursion
7686 // algorithm uses a large stack frame than the non-data recursive version,
7687 // and AnnotationTokensWorker currently transforms the data-recursion
7688 // algorithm back into a traditional recursion by explicitly calling
7689 // VisitChildren(). We will need to remove this explicit recursive call.
7690 W.AnnotateTokens();
7691
7692 // If we ran into any entities that involve context-sensitive keywords,
7693 // take another pass through the tokens to mark them as such.
7694 if (W.hasContextSensitiveKeywords()) {
7695 for (unsigned I = 0; I != NumTokens; ++I) {
7696 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7697 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007698
Guy Benyei11169dd2012-12-18 14:30:41 +00007699 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7700 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007701 if (const ObjCPropertyDecl *Property =
7702 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007703 if (Property->getPropertyAttributesAsWritten() != 0 &&
7704 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007705 .Case("readonly", true)
7706 .Case("assign", true)
7707 .Case("unsafe_unretained", true)
7708 .Case("readwrite", true)
7709 .Case("retain", true)
7710 .Case("copy", true)
7711 .Case("nonatomic", true)
7712 .Case("atomic", true)
7713 .Case("getter", true)
7714 .Case("setter", true)
7715 .Case("strong", true)
7716 .Case("weak", true)
7717 .Case("class", true)
7718 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007719 Tokens[I].int_data[0] = CXToken_Keyword;
7720 }
7721 continue;
7722 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007723
Guy Benyei11169dd2012-12-18 14:30:41 +00007724 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7725 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7726 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7727 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007728 .Case("in", true)
7729 .Case("out", true)
7730 .Case("inout", true)
7731 .Case("oneway", true)
7732 .Case("bycopy", true)
7733 .Case("byref", true)
7734 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007735 Tokens[I].int_data[0] = CXToken_Keyword;
7736 continue;
7737 }
7738
7739 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7740 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7741 Tokens[I].int_data[0] = CXToken_Keyword;
7742 continue;
7743 }
7744 }
7745 }
7746}
7747
Michael Kruse7520cf02020-03-25 09:26:14 -05007748void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7749 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007750 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007751 LOG_BAD_TU(TU);
7752 return;
7753 }
7754 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007755 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007756 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007757 }
7758
7759 LOG_FUNC_SECTION {
7760 *Log << TU << ' ';
7761 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007762 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007763 *Log << clang_getRange(bloc, eloc);
7764 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007765
7766 // Any token we don't specifically annotate will have a NULL cursor.
7767 CXCursor C = clang_getNullCursor();
7768 for (unsigned I = 0; I != NumTokens; ++I)
7769 Cursors[I] = C;
7770
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007771 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007772 if (!CXXUnit)
7773 return;
7774
7775 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007776
7777 auto AnnotateTokensImpl = [=]() {
7778 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7779 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007780 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007781 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007782 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7783 }
7784}
7785
Guy Benyei11169dd2012-12-18 14:30:41 +00007786//===----------------------------------------------------------------------===//
7787// Operations for querying linkage of a cursor.
7788//===----------------------------------------------------------------------===//
7789
Guy Benyei11169dd2012-12-18 14:30:41 +00007790CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7791 if (!clang_isDeclaration(cursor.kind))
7792 return CXLinkage_Invalid;
7793
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007794 const Decl *D = cxcursor::getCursorDecl(cursor);
7795 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007796 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007797 case NoLinkage:
7798 case VisibleNoLinkage:
7799 return CXLinkage_NoLinkage;
7800 case ModuleInternalLinkage:
7801 case InternalLinkage:
7802 return CXLinkage_Internal;
7803 case UniqueExternalLinkage:
7804 return CXLinkage_UniqueExternal;
7805 case ModuleLinkage:
7806 case ExternalLinkage:
7807 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007808 };
7809
7810 return CXLinkage_Invalid;
7811}
Guy Benyei11169dd2012-12-18 14:30:41 +00007812
7813//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007814// Operations for querying visibility of a cursor.
7815//===----------------------------------------------------------------------===//
7816
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007817CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7818 if (!clang_isDeclaration(cursor.kind))
7819 return CXVisibility_Invalid;
7820
7821 const Decl *D = cxcursor::getCursorDecl(cursor);
7822 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7823 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007824 case HiddenVisibility:
7825 return CXVisibility_Hidden;
7826 case ProtectedVisibility:
7827 return CXVisibility_Protected;
7828 case DefaultVisibility:
7829 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007830 };
7831
7832 return CXVisibility_Invalid;
7833}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007834
7835//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007836// Operations for querying language of a cursor.
7837//===----------------------------------------------------------------------===//
7838
7839static CXLanguageKind getDeclLanguage(const Decl *D) {
7840 if (!D)
7841 return CXLanguage_C;
7842
7843 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007844 default:
7845 break;
7846 case Decl::ImplicitParam:
7847 case Decl::ObjCAtDefsField:
7848 case Decl::ObjCCategory:
7849 case Decl::ObjCCategoryImpl:
7850 case Decl::ObjCCompatibleAlias:
7851 case Decl::ObjCImplementation:
7852 case Decl::ObjCInterface:
7853 case Decl::ObjCIvar:
7854 case Decl::ObjCMethod:
7855 case Decl::ObjCProperty:
7856 case Decl::ObjCPropertyImpl:
7857 case Decl::ObjCProtocol:
7858 case Decl::ObjCTypeParam:
7859 return CXLanguage_ObjC;
7860 case Decl::CXXConstructor:
7861 case Decl::CXXConversion:
7862 case Decl::CXXDestructor:
7863 case Decl::CXXMethod:
7864 case Decl::CXXRecord:
7865 case Decl::ClassTemplate:
7866 case Decl::ClassTemplatePartialSpecialization:
7867 case Decl::ClassTemplateSpecialization:
7868 case Decl::Friend:
7869 case Decl::FriendTemplate:
7870 case Decl::FunctionTemplate:
7871 case Decl::LinkageSpec:
7872 case Decl::Namespace:
7873 case Decl::NamespaceAlias:
7874 case Decl::NonTypeTemplateParm:
7875 case Decl::StaticAssert:
7876 case Decl::TemplateTemplateParm:
7877 case Decl::TemplateTypeParm:
7878 case Decl::UnresolvedUsingTypename:
7879 case Decl::UnresolvedUsingValue:
7880 case Decl::Using:
7881 case Decl::UsingDirective:
7882 case Decl::UsingShadow:
7883 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007884 }
7885
7886 return CXLanguage_C;
7887}
7888
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007889static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7890 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007891 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007892
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007893 switch (D->getAvailability()) {
7894 case AR_Available:
7895 case AR_NotYetIntroduced:
7896 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007897 return getCursorAvailabilityForDecl(
7898 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007899 return CXAvailability_Available;
7900
7901 case AR_Deprecated:
7902 return CXAvailability_Deprecated;
7903
7904 case AR_Unavailable:
7905 return CXAvailability_NotAvailable;
7906 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007907
7908 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007909}
7910
Guy Benyei11169dd2012-12-18 14:30:41 +00007911enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7912 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007913 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7914 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007915
7916 return CXAvailability_Available;
7917}
7918
7919static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007920 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007921 if (In.empty())
7922 return Out;
7923
7924 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007925
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007926 Optional<unsigned> Minor = In.getMinor();
7927 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007928 Out.Minor = *Minor;
7929 else
7930 return Out;
7931
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007932 Optional<unsigned> Subminor = In.getSubminor();
7933 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007934 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007935
Guy Benyei11169dd2012-12-18 14:30:41 +00007936 return Out;
7937}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007938
Alex Lorenz1345ea22017-06-12 19:06:30 +00007939static void getCursorPlatformAvailabilityForDecl(
7940 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7941 int *always_unavailable, CXString *unavailable_message,
7942 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007943 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007944 for (auto A : D->attrs()) {
7945 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007946 HadAvailAttr = true;
7947 if (always_deprecated)
7948 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007949 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007950 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007951 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007952 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007953 continue;
7954 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007955
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007956 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007957 HadAvailAttr = true;
7958 if (always_unavailable)
7959 *always_unavailable = 1;
7960 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007961 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007962 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7963 }
7964 continue;
7965 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007966
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007967 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007968 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007969 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007970 }
7971 }
7972
7973 if (!HadAvailAttr)
7974 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7975 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007976 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7977 deprecated_message, always_unavailable, unavailable_message,
7978 AvailabilityAttrs);
7979
7980 if (AvailabilityAttrs.empty())
7981 return;
7982
Michael Kruse7520cf02020-03-25 09:26:14 -05007983 llvm::sort(
7984 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7985 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7986 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007987 ASTContext &Ctx = D->getASTContext();
7988 auto It = std::unique(
7989 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7990 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7991 if (LHS->getPlatform() != RHS->getPlatform())
7992 return false;
7993
7994 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7995 LHS->getDeprecated() == RHS->getDeprecated() &&
7996 LHS->getObsoleted() == RHS->getObsoleted() &&
7997 LHS->getMessage() == RHS->getMessage() &&
7998 LHS->getReplacement() == RHS->getReplacement())
7999 return true;
8000
8001 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
8002 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
8003 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
8004 return false;
8005
8006 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
8007 LHS->setIntroduced(Ctx, RHS->getIntroduced());
8008
8009 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
8010 LHS->setDeprecated(Ctx, RHS->getDeprecated());
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 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
8018 LHS->setObsoleted(Ctx, RHS->getObsoleted());
8019 if (LHS->getMessage().empty())
8020 LHS->setMessage(Ctx, RHS->getMessage());
8021 if (LHS->getReplacement().empty())
8022 LHS->setReplacement(Ctx, RHS->getReplacement());
8023 }
8024
8025 return true;
8026 });
8027 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008028}
8029
Alex Lorenz1345ea22017-06-12 19:06:30 +00008030int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00008031 CXString *deprecated_message,
8032 int *always_unavailable,
8033 CXString *unavailable_message,
8034 CXPlatformAvailability *availability,
8035 int availability_size) {
8036 if (always_deprecated)
8037 *always_deprecated = 0;
8038 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008039 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00008040 if (always_unavailable)
8041 *always_unavailable = 0;
8042 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008043 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008044
Guy Benyei11169dd2012-12-18 14:30:41 +00008045 if (!clang_isDeclaration(cursor.kind))
8046 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008047
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008048 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00008049 if (!D)
8050 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008051
Alex Lorenz1345ea22017-06-12 19:06:30 +00008052 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
8053 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8054 always_unavailable, unavailable_message,
8055 AvailabilityAttrs);
8056 for (const auto &Avail :
8057 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8058 .take_front(availability_size))) {
8059 availability[Avail.index()].Platform =
8060 cxstring::createDup(Avail.value()->getPlatform()->getName());
8061 availability[Avail.index()].Introduced =
8062 convertVersion(Avail.value()->getIntroduced());
8063 availability[Avail.index()].Deprecated =
8064 convertVersion(Avail.value()->getDeprecated());
8065 availability[Avail.index()].Obsoleted =
8066 convertVersion(Avail.value()->getObsoleted());
8067 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8068 availability[Avail.index()].Message =
8069 cxstring::createDup(Avail.value()->getMessage());
8070 }
8071
8072 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008073}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008074
Guy Benyei11169dd2012-12-18 14:30:41 +00008075void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8076 clang_disposeString(availability->Platform);
8077 clang_disposeString(availability->Message);
8078}
8079
8080CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8081 if (clang_isDeclaration(cursor.kind))
8082 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8083
8084 return CXLanguage_Invalid;
8085}
8086
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008087CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8088 const Decl *D = cxcursor::getCursorDecl(cursor);
8089 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8090 switch (VD->getTLSKind()) {
8091 case VarDecl::TLS_None:
8092 return CXTLS_None;
8093 case VarDecl::TLS_Dynamic:
8094 return CXTLS_Dynamic;
8095 case VarDecl::TLS_Static:
8096 return CXTLS_Static;
8097 }
8098 }
8099
8100 return CXTLS_None;
8101}
8102
Michael Kruse7520cf02020-03-25 09:26:14 -05008103/// If the given cursor is the "templated" declaration
8104/// describing a class or function template, return the class or
8105/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008106static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008107 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008108 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008109
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008110 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008111 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8112 return FunTmpl;
8113
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008114 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008115 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8116 return ClassTmpl;
8117
8118 return D;
8119}
8120
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008121enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8122 StorageClass sc = SC_None;
8123 const Decl *D = getCursorDecl(C);
8124 if (D) {
8125 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8126 sc = FD->getStorageClass();
8127 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8128 sc = VD->getStorageClass();
8129 } else {
8130 return CX_SC_Invalid;
8131 }
8132 } else {
8133 return CX_SC_Invalid;
8134 }
8135 switch (sc) {
8136 case SC_None:
8137 return CX_SC_None;
8138 case SC_Extern:
8139 return CX_SC_Extern;
8140 case SC_Static:
8141 return CX_SC_Static;
8142 case SC_PrivateExtern:
8143 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008144 case SC_Auto:
8145 return CX_SC_Auto;
8146 case SC_Register:
8147 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008148 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008149 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008150}
8151
Guy Benyei11169dd2012-12-18 14:30:41 +00008152CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8153 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008154 if (const Decl *D = getCursorDecl(cursor)) {
8155 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008156 if (!DC)
8157 return clang_getNullCursor();
8158
Michael Kruse7520cf02020-03-25 09:26:14 -05008159 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008160 getCursorTU(cursor));
8161 }
8162 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008163
Guy Benyei11169dd2012-12-18 14:30:41 +00008164 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008165 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008166 return MakeCXCursor(D, getCursorTU(cursor));
8167 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008168
Guy Benyei11169dd2012-12-18 14:30:41 +00008169 return clang_getNullCursor();
8170}
8171
8172CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8173 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008174 if (const Decl *D = getCursorDecl(cursor)) {
8175 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008176 if (!DC)
8177 return clang_getNullCursor();
8178
Michael Kruse7520cf02020-03-25 09:26:14 -05008179 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008180 getCursorTU(cursor));
8181 }
8182 }
8183
Michael Kruse7520cf02020-03-25 09:26:14 -05008184 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008185 // statement or expression, so we return nothing.
8186 return clang_getNullCursor();
8187}
8188
8189CXFile clang_getIncludedFile(CXCursor cursor) {
8190 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008191 return nullptr;
8192
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008193 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008194 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008195}
8196
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008197unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8198 if (C.kind != CXCursor_ObjCPropertyDecl)
8199 return CXObjCPropertyAttr_noattr;
8200
8201 unsigned Result = CXObjCPropertyAttr_noattr;
8202 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008203 ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008204
Michael Kruse7520cf02020-03-25 09:26:14 -05008205#define SET_CXOBJCPROP_ATTR(A) \
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008206 if (Attr & ObjCPropertyAttribute::kind_##A) \
Michael Kruse7520cf02020-03-25 09:26:14 -05008207 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008208 SET_CXOBJCPROP_ATTR(readonly);
8209 SET_CXOBJCPROP_ATTR(getter);
8210 SET_CXOBJCPROP_ATTR(assign);
8211 SET_CXOBJCPROP_ATTR(readwrite);
8212 SET_CXOBJCPROP_ATTR(retain);
8213 SET_CXOBJCPROP_ATTR(copy);
8214 SET_CXOBJCPROP_ATTR(nonatomic);
8215 SET_CXOBJCPROP_ATTR(setter);
8216 SET_CXOBJCPROP_ATTR(atomic);
8217 SET_CXOBJCPROP_ATTR(weak);
8218 SET_CXOBJCPROP_ATTR(strong);
8219 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008220 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008221#undef SET_CXOBJCPROP_ATTR
8222
8223 return Result;
8224}
8225
Michael Wu6e88f532018-08-03 05:38:29 +00008226CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8227 if (C.kind != CXCursor_ObjCPropertyDecl)
8228 return cxstring::createNull();
8229
8230 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8231 Selector sel = PD->getGetterName();
8232 if (sel.isNull())
8233 return cxstring::createNull();
8234
8235 return cxstring::createDup(sel.getAsString());
8236}
8237
8238CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8239 if (C.kind != CXCursor_ObjCPropertyDecl)
8240 return cxstring::createNull();
8241
8242 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8243 Selector sel = PD->getSetterName();
8244 if (sel.isNull())
8245 return cxstring::createNull();
8246
8247 return cxstring::createDup(sel.getAsString());
8248}
8249
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008250unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8251 if (!clang_isDeclaration(C.kind))
8252 return CXObjCDeclQualifier_None;
8253
8254 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8255 const Decl *D = getCursorDecl(C);
8256 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8257 QT = MD->getObjCDeclQualifier();
8258 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8259 QT = PD->getObjCDeclQualifier();
8260 if (QT == Decl::OBJC_TQ_None)
8261 return CXObjCDeclQualifier_None;
8262
8263 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008264 if (QT & Decl::OBJC_TQ_In)
8265 Result |= CXObjCDeclQualifier_In;
8266 if (QT & Decl::OBJC_TQ_Inout)
8267 Result |= CXObjCDeclQualifier_Inout;
8268 if (QT & Decl::OBJC_TQ_Out)
8269 Result |= CXObjCDeclQualifier_Out;
8270 if (QT & Decl::OBJC_TQ_Bycopy)
8271 Result |= CXObjCDeclQualifier_Bycopy;
8272 if (QT & Decl::OBJC_TQ_Byref)
8273 Result |= CXObjCDeclQualifier_Byref;
8274 if (QT & Decl::OBJC_TQ_Oneway)
8275 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008276
8277 return Result;
8278}
8279
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008280unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8281 if (!clang_isDeclaration(C.kind))
8282 return 0;
8283
8284 const Decl *D = getCursorDecl(C);
8285 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8286 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8287 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8288 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8289
8290 return 0;
8291}
8292
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008293unsigned clang_Cursor_isVariadic(CXCursor C) {
8294 if (!clang_isDeclaration(C.kind))
8295 return 0;
8296
8297 const Decl *D = getCursorDecl(C);
8298 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8299 return FD->isVariadic();
8300 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8301 return MD->isVariadic();
8302
8303 return 0;
8304}
8305
Michael Kruse7520cf02020-03-25 09:26:14 -05008306unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8307 CXString *definedIn,
8308 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008309 if (!clang_isDeclaration(C.kind))
8310 return 0;
8311
8312 const Decl *D = getCursorDecl(C);
8313
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008314 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008315 if (language)
8316 *language = cxstring::createDup(attr->getLanguage());
8317 if (definedIn)
8318 *definedIn = cxstring::createDup(attr->getDefinedIn());
8319 if (isGenerated)
8320 *isGenerated = attr->getGeneratedDeclaration();
8321 return 1;
8322 }
8323 return 0;
8324}
8325
Guy Benyei11169dd2012-12-18 14:30:41 +00008326CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8327 if (!clang_isDeclaration(C.kind))
8328 return clang_getNullRange();
8329
8330 const Decl *D = getCursorDecl(C);
8331 ASTContext &Context = getCursorContext(C);
8332 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8333 if (!RC)
8334 return clang_getNullRange();
8335
8336 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8337}
8338
8339CXString clang_Cursor_getRawCommentText(CXCursor C) {
8340 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008341 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008342
8343 const Decl *D = getCursorDecl(C);
8344 ASTContext &Context = getCursorContext(C);
8345 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008346 StringRef RawText =
8347 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008348
8349 // Don't duplicate the string because RawText points directly into source
8350 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008351 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008352}
8353
8354CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8355 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008356 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008357
8358 const Decl *D = getCursorDecl(C);
8359 const ASTContext &Context = getCursorContext(C);
8360 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8361
8362 if (RC) {
8363 StringRef BriefText = RC->getBriefText(Context);
8364
8365 // Don't duplicate the string because RawComment ensures that this memory
8366 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008367 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008368 }
8369
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008370 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008371}
8372
Guy Benyei11169dd2012-12-18 14:30:41 +00008373CXModule clang_Cursor_getModule(CXCursor C) {
8374 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008375 if (const ImportDecl *ImportD =
8376 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008377 return ImportD->getImportedModule();
8378 }
8379
Craig Topper69186e72014-06-08 08:38:04 +00008380 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008381}
8382
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008383CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8384 if (isNotUsableTU(TU)) {
8385 LOG_BAD_TU(TU);
8386 return nullptr;
8387 }
8388 if (!File)
8389 return nullptr;
8390 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008391
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008392 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8393 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8394 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008395
Richard Smithfeb54b62014-10-23 02:01:19 +00008396 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008397}
8398
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008399CXFile clang_Module_getASTFile(CXModule CXMod) {
8400 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008401 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008402 Module *Mod = static_cast<Module *>(CXMod);
Duncan P. N. Exon Smith9f151df2020-10-20 18:11:52 -04008403 if (auto File = Mod->getASTFile())
8404 return const_cast<FileEntry *>(&File->getFileEntry());
8405 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008406}
8407
Guy Benyei11169dd2012-12-18 14:30:41 +00008408CXModule clang_Module_getParent(CXModule CXMod) {
8409 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008410 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008411 Module *Mod = static_cast<Module *>(CXMod);
Guy Benyei11169dd2012-12-18 14:30:41 +00008412 return Mod->Parent;
8413}
8414
8415CXString clang_Module_getName(CXModule CXMod) {
8416 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008417 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008418 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008419 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008420}
8421
8422CXString clang_Module_getFullName(CXModule CXMod) {
8423 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008424 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008425 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008426 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008427}
8428
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008429int clang_Module_isSystem(CXModule CXMod) {
8430 if (!CXMod)
8431 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008432 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008433 return Mod->IsSystem;
8434}
8435
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008436unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8437 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008438 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008439 LOG_BAD_TU(TU);
8440 return 0;
8441 }
8442 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008443 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008444 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008445 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8446 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8447 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008448}
8449
Michael Kruse7520cf02020-03-25 09:26:14 -05008450CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8451 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008452 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008453 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008454 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008455 }
8456 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008457 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008458 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008459 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008460
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008461 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8462 if (Index < TopHeaders.size())
8463 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008464
Craig Topper69186e72014-06-08 08:38:04 +00008465 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008466}
8467
Guy Benyei11169dd2012-12-18 14:30:41 +00008468//===----------------------------------------------------------------------===//
8469// C++ AST instrospection.
8470//===----------------------------------------------------------------------===//
8471
Jonathan Coe29565352016-04-27 12:48:25 +00008472unsigned clang_CXXConstructor_isDefaultConstructor(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->isDefaultConstructor()) ? 1 : 0;
8480}
8481
8482unsigned clang_CXXConstructor_isCopyConstructor(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->isCopyConstructor()) ? 1 : 0;
8490}
8491
8492unsigned clang_CXXConstructor_isMoveConstructor(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 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8500}
8501
8502unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8503 if (!clang_isDeclaration(C.kind))
8504 return 0;
8505
8506 const Decl *D = cxcursor::getCursorDecl(C);
8507 const CXXConstructorDecl *Constructor =
8508 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8509 // Passing 'false' excludes constructors marked 'explicit'.
8510 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8511}
8512
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008513unsigned clang_CXXField_isMutable(CXCursor C) {
8514 if (!clang_isDeclaration(C.kind))
8515 return 0;
8516
8517 if (const auto D = cxcursor::getCursorDecl(C))
8518 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8519 return FD->isMutable() ? 1 : 0;
8520 return 0;
8521}
8522
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008523unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8524 if (!clang_isDeclaration(C.kind))
8525 return 0;
8526
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008527 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008528 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008529 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008530 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8531}
8532
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008533unsigned clang_CXXMethod_isConst(CXCursor C) {
8534 if (!clang_isDeclaration(C.kind))
8535 return 0;
8536
8537 const Decl *D = cxcursor::getCursorDecl(C);
8538 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008539 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008540 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008541}
8542
Jonathan Coe29565352016-04-27 12:48:25 +00008543unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8544 if (!clang_isDeclaration(C.kind))
8545 return 0;
8546
8547 const Decl *D = cxcursor::getCursorDecl(C);
8548 const CXXMethodDecl *Method =
8549 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8550 return (Method && Method->isDefaulted()) ? 1 : 0;
8551}
8552
Guy Benyei11169dd2012-12-18 14:30:41 +00008553unsigned clang_CXXMethod_isStatic(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->isStatic()) ? 1 : 0;
8561}
8562
8563unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8564 if (!clang_isDeclaration(C.kind))
8565 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008566
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008567 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008568 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008569 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008570 return (Method && Method->isVirtual()) ? 1 : 0;
8571}
Guy Benyei11169dd2012-12-18 14:30:41 +00008572
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008573unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8574 if (!clang_isDeclaration(C.kind))
8575 return 0;
8576
8577 const auto *D = cxcursor::getCursorDecl(C);
8578 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8579 if (RD)
8580 RD = RD->getDefinition();
8581 return (RD && RD->isAbstract()) ? 1 : 0;
8582}
8583
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008584unsigned clang_EnumDecl_isScoped(CXCursor C) {
8585 if (!clang_isDeclaration(C.kind))
8586 return 0;
8587
8588 const Decl *D = cxcursor::getCursorDecl(C);
8589 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8590 return (Enum && Enum->isScoped()) ? 1 : 0;
8591}
8592
Guy Benyei11169dd2012-12-18 14:30:41 +00008593//===----------------------------------------------------------------------===//
8594// Attribute introspection.
8595//===----------------------------------------------------------------------===//
8596
Guy Benyei11169dd2012-12-18 14:30:41 +00008597CXType clang_getIBOutletCollectionType(CXCursor C) {
8598 if (C.kind != CXCursor_IBOutletCollectionAttr)
8599 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008600
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008601 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008602 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8603
8604 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008605}
Guy Benyei11169dd2012-12-18 14:30:41 +00008606
8607//===----------------------------------------------------------------------===//
8608// Inspecting memory usage.
8609//===----------------------------------------------------------------------===//
8610
8611typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8612
8613static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008614 enum CXTUResourceUsageKind k,
8615 unsigned long amount) {
8616 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008617 entries.push_back(entry);
8618}
8619
Guy Benyei11169dd2012-12-18 14:30:41 +00008620const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8621 const char *str = "";
8622 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008623 case CXTUResourceUsage_AST:
8624 str = "ASTContext: expressions, declarations, and types";
8625 break;
8626 case CXTUResourceUsage_Identifiers:
8627 str = "ASTContext: identifiers";
8628 break;
8629 case CXTUResourceUsage_Selectors:
8630 str = "ASTContext: selectors";
8631 break;
8632 case CXTUResourceUsage_GlobalCompletionResults:
8633 str = "Code completion: cached global results";
8634 break;
8635 case CXTUResourceUsage_SourceManagerContentCache:
8636 str = "SourceManager: content cache allocator";
8637 break;
8638 case CXTUResourceUsage_AST_SideTables:
8639 str = "ASTContext: side tables";
8640 break;
8641 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8642 str = "SourceManager: malloc'ed memory buffers";
8643 break;
8644 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8645 str = "SourceManager: mmap'ed memory buffers";
8646 break;
8647 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8648 str = "ExternalASTSource: malloc'ed memory buffers";
8649 break;
8650 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8651 str = "ExternalASTSource: mmap'ed memory buffers";
8652 break;
8653 case CXTUResourceUsage_Preprocessor:
8654 str = "Preprocessor: malloc'ed memory";
8655 break;
8656 case CXTUResourceUsage_PreprocessingRecord:
8657 str = "Preprocessor: PreprocessingRecord";
8658 break;
8659 case CXTUResourceUsage_SourceManager_DataStructures:
8660 str = "SourceManager: data structures and tables";
8661 break;
8662 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8663 str = "Preprocessor: header search tables";
8664 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008665 }
8666 return str;
8667}
8668
8669CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008670 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008671 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008672 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008673 return usage;
8674 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008675
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008676 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008677 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008678 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008679
Guy Benyei11169dd2012-12-18 14:30:41 +00008680 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008681 createCXTUResourceUsageEntry(
8682 *entries, CXTUResourceUsage_AST,
8683 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008684
8685 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008686 createCXTUResourceUsageEntry(
8687 *entries, CXTUResourceUsage_Identifiers,
8688 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008689
8690 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008691 createCXTUResourceUsageEntry(
8692 *entries, CXTUResourceUsage_Selectors,
8693 (unsigned long)astContext.Selectors.getTotalMemory());
8694
Guy Benyei11169dd2012-12-18 14:30:41 +00008695 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008696 createCXTUResourceUsageEntry(
8697 *entries, CXTUResourceUsage_AST_SideTables,
8698 (unsigned long)astContext.getSideTableAllocatedMemory());
8699
Guy Benyei11169dd2012-12-18 14:30:41 +00008700 // How much memory is used for caching global code completion results?
8701 unsigned long completionBytes = 0;
8702 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008703 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008704 completionBytes = completionAllocator->getTotalMemory();
8705 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008706 createCXTUResourceUsageEntry(
8707 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8708
Guy Benyei11169dd2012-12-18 14:30:41 +00008709 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008710 createCXTUResourceUsageEntry(
8711 *entries, CXTUResourceUsage_SourceManagerContentCache,
8712 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8713
Guy Benyei11169dd2012-12-18 14:30:41 +00008714 // How much memory is being used by the MemoryBuffer's in SourceManager?
8715 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008716 astUnit->getSourceManager().getMemoryBufferSizes();
8717
Guy Benyei11169dd2012-12-18 14:30:41 +00008718 createCXTUResourceUsageEntry(*entries,
8719 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008720 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008721 createCXTUResourceUsageEntry(*entries,
8722 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008723 (unsigned long)srcBufs.mmap_bytes);
8724 createCXTUResourceUsageEntry(
8725 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8726 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8727
Guy Benyei11169dd2012-12-18 14:30:41 +00008728 // How much memory is being used by the ExternalASTSource?
8729 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8730 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008731 esrc->getMemoryBufferSizes();
8732
8733 createCXTUResourceUsageEntry(
8734 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8735 (unsigned long)sizes.malloc_bytes);
8736 createCXTUResourceUsageEntry(
8737 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8738 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008739 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008740
Guy Benyei11169dd2012-12-18 14:30:41 +00008741 // How much memory is being used by the Preprocessor?
8742 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008743 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008744 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008745
Guy Benyei11169dd2012-12-18 14:30:41 +00008746 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8747 createCXTUResourceUsageEntry(*entries,
8748 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008749 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008750 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008751
Guy Benyei11169dd2012-12-18 14:30:41 +00008752 createCXTUResourceUsageEntry(*entries,
8753 CXTUResourceUsage_Preprocessor_HeaderSearch,
8754 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008755
Michael Kruse7520cf02020-03-25 09:26:14 -05008756 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8757 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008758 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008759 return usage;
8760}
8761
8762void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8763 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008764 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008765}
8766
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008767CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8768 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008769 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008770 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008771
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008772 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008773 LOG_BAD_TU(TU);
8774 return skipped;
8775 }
8776
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008777 if (!file)
8778 return skipped;
8779
8780 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008781 PreprocessingRecord *ppRec =
8782 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008783 if (!ppRec)
8784 return skipped;
8785
8786 ASTContext &Ctx = astUnit->getASTContext();
8787 SourceManager &sm = Ctx.getSourceManager();
8788 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8789 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008790 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008791
8792 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8793 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008794 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8795 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008796 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008797 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8798 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008799 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008800 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8801 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008802 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008803 }
8804
8805 skipped->count = wantedRanges.size();
8806 skipped->ranges = new CXSourceRange[skipped->count];
8807 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8808 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8809
8810 return skipped;
8811}
8812
Cameron Desrochersd8091282016-08-18 15:43:55 +00008813CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8814 CXSourceRangeList *skipped = new CXSourceRangeList;
8815 skipped->count = 0;
8816 skipped->ranges = nullptr;
8817
8818 if (isNotUsableTU(TU)) {
8819 LOG_BAD_TU(TU);
8820 return skipped;
8821 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008822
Cameron Desrochersd8091282016-08-18 15:43:55 +00008823 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008824 PreprocessingRecord *ppRec =
8825 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008826 if (!ppRec)
8827 return skipped;
8828
8829 ASTContext &Ctx = astUnit->getASTContext();
8830
8831 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8832
8833 skipped->count = SkippedRanges.size();
8834 skipped->ranges = new CXSourceRange[skipped->count];
8835 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8836 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8837
8838 return skipped;
8839}
8840
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008841void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8842 if (ranges) {
8843 delete[] ranges->ranges;
8844 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008845 }
8846}
8847
Guy Benyei11169dd2012-12-18 14:30:41 +00008848void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8849 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8850 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008851 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008852 clang_getTUResourceUsageName(Usage.entries[I].kind),
8853 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008854
Guy Benyei11169dd2012-12-18 14:30:41 +00008855 clang_disposeCXTUResourceUsage(Usage);
8856}
8857
Jan Korous052f8382020-09-01 16:29:36 -07008858CXCursor clang_Cursor_getVarDeclInitializer(CXCursor cursor) {
8859 const Decl *const D = getCursorDecl(cursor);
8860 if (!D)
8861 return clang_getNullCursor();
8862 const auto *const VD = dyn_cast<VarDecl>(D);
8863 if (!VD)
8864 return clang_getNullCursor();
8865 const Expr *const Init = VD->getInit();
8866 if (!Init)
8867 return clang_getNullCursor();
8868
8869 return cxcursor::MakeCXCursor(Init, VD, cxcursor::getCursorTU(cursor));
8870}
8871
8872int clang_Cursor_hasVarDeclGlobalStorage(CXCursor cursor) {
8873 const Decl *const D = getCursorDecl(cursor);
8874 if (!D)
8875 return -1;
8876 const auto *const VD = dyn_cast<VarDecl>(D);
8877 if (!VD)
8878 return -1;
8879
8880 return VD->hasGlobalStorage();
8881}
8882
8883int clang_Cursor_hasVarDeclExternalStorage(CXCursor cursor) {
8884 const Decl *const D = getCursorDecl(cursor);
8885 if (!D)
8886 return -1;
8887 const auto *const VD = dyn_cast<VarDecl>(D);
8888 if (!VD)
8889 return -1;
8890
8891 return VD->hasExternalStorage();
8892}
8893
Guy Benyei11169dd2012-12-18 14:30:41 +00008894//===----------------------------------------------------------------------===//
8895// Misc. utility functions.
8896//===----------------------------------------------------------------------===//
8897
Richard Smith0a7b2972018-07-03 21:34:13 +00008898/// Default to using our desired 8 MB stack size on "safety" threads.
8899static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008900
8901namespace clang {
8902
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008903bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008904 unsigned Size) {
8905 if (!Size)
8906 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008907 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008908 return CRC.RunSafelyOnThread(Fn, Size);
8909 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008910}
8911
Michael Kruse7520cf02020-03-25 09:26:14 -05008912unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008913
Michael Kruse7520cf02020-03-25 09:26:14 -05008914void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008915
Michael Kruse7520cf02020-03-25 09:26:14 -05008916} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008917
8918void clang::setThreadBackgroundPriority() {
8919 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8920 return;
8921
Nico Weber18cfd9f2019-04-21 19:18:41 +00008922#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008923 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008924#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008925}
8926
8927void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8928 if (!Unit)
8929 return;
8930
Michael Kruse7520cf02020-03-25 09:26:14 -05008931 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8932 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008933 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008934 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008935 CXString Msg =
8936 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008937 fprintf(stderr, "%s\n", clang_getCString(Msg));
8938 clang_disposeString(Msg);
8939 }
Nico Weber1865df42018-04-27 19:11:14 +00008940#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008941 // On Windows, force a flush, since there may be multiple copies of
8942 // stderr and stdout in the file system, all with different buffers
8943 // but writing to the same device.
8944 fflush(stderr);
8945#endif
8946}
8947
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008948MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8949 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008950 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008951 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008952 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008953 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008954 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008955
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008956 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008957 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008958 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008959 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008960 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8961 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008962 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8963 return Def.getMacroInfo();
8964 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008965 }
8966
Craig Topper69186e72014-06-08 08:38:04 +00008967 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008968}
8969
Richard Smith66a81862015-05-04 02:25:31 +00008970const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008971 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008972 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008973 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008974 const IdentifierInfo *II = MacroDef->getName();
8975 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008976 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008977
8978 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8979}
8980
Richard Smith66a81862015-05-04 02:25:31 +00008981MacroDefinitionRecord *
8982cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8983 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008984 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008985 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008986 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008987 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008988
8989 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008990 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008991 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8992 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008993 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008994
8995 // Check that the token is inside the definition and not its argument list.
8996 SourceManager &SM = Unit->getSourceManager();
8997 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008998 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008999 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00009000 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009001
9002 Preprocessor &PP = Unit->getPreprocessor();
9003 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
9004 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00009005 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009006
Alp Toker2d57cea2014-05-17 04:53:25 +00009007 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009008 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00009009 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009010
9011 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00009012 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00009013 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009014
Richard Smith20e883e2015-04-29 23:20:19 +00009015 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00009016 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00009017 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009018
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00009019 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009020}
9021
Richard Smith66a81862015-05-04 02:25:31 +00009022MacroDefinitionRecord *
9023cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
9024 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009025 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00009026 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009027
9028 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00009029 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00009030 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009031 Preprocessor &PP = Unit->getPreprocessor();
9032 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00009033 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009034 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
9035 Token Tok;
9036 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00009037 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00009038
9039 return checkForMacroInMacroDefinition(MI, Tok, TU);
9040}
9041
Guy Benyei11169dd2012-12-18 14:30:41 +00009042CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00009043 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00009044}
9045
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009046Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
9047 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00009048 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009049 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00009050 if (Unit->isMainFileAST())
9051 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009052 return *this;
9053 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00009054 } else {
9055 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009056 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009057 return *this;
9058}
9059
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00009060Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
9061 *this << FE->getName();
9062 return *this;
9063}
9064
9065Logger &cxindex::Logger::operator<<(CXCursor cursor) {
9066 CXString cursorName = clang_getCursorDisplayName(cursor);
9067 *this << cursorName << "@" << clang_getCursorLocation(cursor);
9068 clang_disposeString(cursorName);
9069 return *this;
9070}
9071
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009072Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
9073 CXFile File;
9074 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00009075 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009076 CXString FileName = clang_getFileName(File);
9077 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
9078 clang_disposeString(FileName);
9079 return *this;
9080}
9081
9082Logger &cxindex::Logger::operator<<(CXSourceRange range) {
9083 CXSourceLocation BLoc = clang_getRangeStart(range);
9084 CXSourceLocation ELoc = clang_getRangeEnd(range);
9085
9086 CXFile BFile;
9087 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009088 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009089
9090 CXFile EFile;
9091 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009092 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009093
9094 CXString BFileName = clang_getFileName(BFile);
9095 if (BFile == EFile) {
9096 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05009097 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009098 } else {
9099 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009100 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9101 BColumn)
9102 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9103 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009104 clang_disposeString(EFileName);
9105 }
9106 clang_disposeString(BFileName);
9107 return *this;
9108}
9109
9110Logger &cxindex::Logger::operator<<(CXString Str) {
9111 *this << clang_getCString(Str);
9112 return *this;
9113}
9114
9115Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9116 LogOS << Fmt;
9117 return *this;
9118}
9119
Benjamin Kramer762bc332019-08-07 14:44:40 +00009120static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009121
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009122cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009123 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009124
9125 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9126
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009127 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009128 OS << "[libclang:" << Name << ':';
9129
Alp Toker1a86ad22014-07-06 06:24:00 +00009130#ifdef USE_DARWIN_THREADS
9131 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009132 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9133 OS << tid << ':';
9134#endif
9135
9136 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9137 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009138 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009139
9140 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009141 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009142 OS << "--------------------------------------------------\n";
9143 }
9144}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009145
9146#ifdef CLANG_TOOL_EXTRA_BUILD
9147// This anchor is used to force the linker to link the clang-tidy plugin.
9148extern volatile int ClangTidyPluginAnchorSource;
9149static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9150 ClangTidyPluginAnchorSource;
9151
9152// This anchor is used to force the linker to link the clang-include-fixer
9153// plugin.
9154extern volatile int ClangIncludeFixerPluginAnchorSource;
9155static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9156 ClangIncludeFixerPluginAnchorSource;
9157#endif