blob: 683b517d79fda223c9bba5b4738fc0811807f069 [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"
Guy Benyei11169dd2012-12-18 14:30:41 +00001549#define BUILTIN_TYPE(Id, SingletonId)
1550#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1551#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1552#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1553#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1554#include "clang/AST/BuiltinTypes.def"
1555 break;
1556
1557 case BuiltinType::ObjCId:
1558 VisitType = Context.getObjCIdType();
1559 break;
1560
1561 case BuiltinType::ObjCClass:
1562 VisitType = Context.getObjCClassType();
1563 break;
1564
1565 case BuiltinType::ObjCSel:
1566 VisitType = Context.getObjCSelType();
1567 break;
1568 }
1569
1570 if (!VisitType.isNull()) {
1571 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
Michael Kruse7520cf02020-03-25 09:26:14 -05001572 return Visit(
1573 MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001574 }
1575
1576 return false;
1577}
1578
1579bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1580 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1581}
1582
1583bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1584 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1585}
1586
1587bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1588 if (TL.isDefinition())
1589 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1590
1591 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1592}
1593
1594bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1595 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1596}
1597
1598bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001599 return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00001600}
1601
Manman Rene6be26c2016-09-13 17:25:08 +00001602bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
Stephen Kellyf2ceec42018-08-09 21:08:08 +00001603 if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
Manman Rene6be26c2016-09-13 17:25:08 +00001604 return true;
1605 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1606 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1607 TU)))
1608 return true;
1609 }
1610
1611 return false;
1612}
1613
Guy Benyei11169dd2012-12-18 14:30:41 +00001614bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1615 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1616 return true;
1617
Douglas Gregore9d95f12015-07-07 03:57:35 +00001618 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1619 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1620 return true;
1621 }
1622
Guy Benyei11169dd2012-12-18 14:30:41 +00001623 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1624 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1625 TU)))
1626 return true;
1627 }
1628
1629 return false;
1630}
1631
1632bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1633 return Visit(TL.getPointeeLoc());
1634}
1635
1636bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1637 return Visit(TL.getInnerLoc());
1638}
1639
Leonard Chanc72aaf62019-05-07 03:20:17 +00001640bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
1641 return Visit(TL.getInnerLoc());
1642}
1643
Guy Benyei11169dd2012-12-18 14:30:41 +00001644bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1645 return Visit(TL.getPointeeLoc());
1646}
1647
1648bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1649 return Visit(TL.getPointeeLoc());
1650}
1651
1652bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1653 return Visit(TL.getPointeeLoc());
1654}
1655
1656bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1657 return Visit(TL.getPointeeLoc());
1658}
1659
1660bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1661 return Visit(TL.getPointeeLoc());
1662}
1663
1664bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1665 return Visit(TL.getModifiedLoc());
1666}
1667
Michael Kruse7520cf02020-03-25 09:26:14 -05001668bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
Guy Benyei11169dd2012-12-18 14:30:41 +00001669 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001670 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001671 return true;
1672
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001673 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1674 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001675 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1676 return true;
1677
1678 return false;
1679}
1680
1681bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1682 if (Visit(TL.getElementLoc()))
1683 return true;
1684
1685 if (Expr *Size = TL.getSizeExpr())
1686 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1687
1688 return false;
1689}
1690
Reid Kleckner8a365022013-06-24 17:51:48 +00001691bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1692 return Visit(TL.getOriginalLoc());
1693}
1694
Reid Kleckner0503a872013-12-05 01:23:43 +00001695bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1696 return Visit(TL.getOriginalLoc());
1697}
1698
Richard Smith600b5262017-01-26 20:40:47 +00001699bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
1700 DeducedTemplateSpecializationTypeLoc TL) {
Michael Kruse7520cf02020-03-25 09:26:14 -05001701 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Richard Smith600b5262017-01-26 20:40:47 +00001702 TL.getTemplateNameLoc()))
1703 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001704
Richard Smith600b5262017-01-26 20:40:47 +00001705 return false;
1706}
1707
Guy Benyei11169dd2012-12-18 14:30:41 +00001708bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001709 TemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 // Visit the template name.
Michael Kruse7520cf02020-03-25 09:26:14 -05001711 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 TL.getTemplateNameLoc()))
1713 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001714
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 // Visit the template arguments.
1716 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1717 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1718 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001719
Guy Benyei11169dd2012-12-18 14:30:41 +00001720 return false;
1721}
1722
1723bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1724 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1725}
1726
1727bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1728 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1729 return Visit(TSInfo->getTypeLoc());
1730
1731 return false;
1732}
1733
1734bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1735 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1736 return Visit(TSInfo->getTypeLoc());
1737
1738 return false;
1739}
1740
1741bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
Hans Wennborg59dbe862015-09-29 20:56:43 +00001742 return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00001743}
1744
1745bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001746 DependentTemplateSpecializationTypeLoc TL) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001747 // Visit the nested-name-specifier, if there is one.
Michael Kruse7520cf02020-03-25 09:26:14 -05001748 if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001749 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001750
Guy Benyei11169dd2012-12-18 14:30:41 +00001751 // Visit the template arguments.
1752 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1753 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1754 return true;
1755
1756 return false;
1757}
1758
1759bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1760 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1761 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05001762
Guy Benyei11169dd2012-12-18 14:30:41 +00001763 return Visit(TL.getNamedTypeLoc());
1764}
1765
1766bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1767 return Visit(TL.getPatternLoc());
1768}
1769
1770bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1771 if (Expr *E = TL.getUnderlyingExpr())
1772 return Visit(MakeCXCursor(E, StmtParent, TU));
1773
1774 return false;
1775}
1776
1777bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1778 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1779}
1780
1781bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1782 return Visit(TL.getValueLoc());
1783}
1784
Xiuli Pan9c14e282016-01-09 12:53:17 +00001785bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
1786 return Visit(TL.getValueLoc());
1787}
1788
Michael Kruse7520cf02020-03-25 09:26:14 -05001789#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1790 bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1791 return Visit##PARENT##Loc(TL); \
1792 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001793
1794DEFAULT_TYPELOC_IMPL(Complex, Type)
1795DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1796DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1797DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1798DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
Andrew Gozillon572bbb02017-10-02 06:25:51 +00001799DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
Erich Keanef702b022018-07-13 19:46:04 +00001800DEFAULT_TYPELOC_IMPL(DependentVector, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001801DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1802DEFAULT_TYPELOC_IMPL(Vector, Type)
1803DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
Florian Hahn10658692020-05-11 17:45:51 +01001804DEFAULT_TYPELOC_IMPL(ConstantMatrix, MatrixType)
1805DEFAULT_TYPELOC_IMPL(DependentSizedMatrix, MatrixType)
Guy Benyei11169dd2012-12-18 14:30:41 +00001806DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1807DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1808DEFAULT_TYPELOC_IMPL(Record, TagType)
1809DEFAULT_TYPELOC_IMPL(Enum, TagType)
1810DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1811DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1812DEFAULT_TYPELOC_IMPL(Auto, Type)
Erich Keane5f0903e2020-04-17 10:44:19 -07001813DEFAULT_TYPELOC_IMPL(ExtInt, Type)
1814DEFAULT_TYPELOC_IMPL(DependentExtInt, Type)
Guy Benyei11169dd2012-12-18 14:30:41 +00001815
1816bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1817 // Visit the nested-name-specifier, if present.
1818 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1819 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1820 return true;
1821
1822 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001823 for (const auto &I : D->bases()) {
1824 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001825 return true;
1826 }
1827 }
1828
1829 return VisitTagDecl(D);
1830}
1831
1832bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001833 for (const auto *I : D->attrs())
Michael Wu40ff1052018-08-03 05:20:23 +00001834 if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
1835 !I->isImplicit()) &&
1836 Visit(MakeCXCursor(I, D, TU)))
Michael Kruse7520cf02020-03-25 09:26:14 -05001837 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00001838
1839 return false;
1840}
1841
1842//===----------------------------------------------------------------------===//
1843// Data-recursive visitor methods.
1844//===----------------------------------------------------------------------===//
1845
1846namespace {
Michael Kruse7520cf02020-03-25 09:26:14 -05001847#define DEF_JOB(NAME, DATA, KIND) \
1848 class NAME : public VisitorJob { \
1849 public: \
1850 NAME(const DATA *d, CXCursor parent) \
1851 : VisitorJob(parent, VisitorJob::KIND, d) {} \
1852 static bool classof(const VisitorJob *VJ) { \
1853 return VJ->getKind() == KIND; \
1854 } \
1855 const DATA *get() const { return static_cast<const DATA *>(data[0]); } \
1856 };
Guy Benyei11169dd2012-12-18 14:30:41 +00001857
1858DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1859DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1860DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1861DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
Guy Benyei11169dd2012-12-18 14:30:41 +00001862DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1863DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1864DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1865#undef DEF_JOB
1866
James Y Knight04ec5bf2015-12-24 02:59:37 +00001867class ExplicitTemplateArgsVisit : public VisitorJob {
1868public:
1869 ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
1870 const TemplateArgumentLoc *End, CXCursor parent)
1871 : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
1872 End) {}
1873 static bool classof(const VisitorJob *VJ) {
1874 return VJ->getKind() == ExplicitTemplateArgsVisitKind;
1875 }
1876 const TemplateArgumentLoc *begin() const {
1877 return static_cast<const TemplateArgumentLoc *>(data[0]);
1878 }
1879 const TemplateArgumentLoc *end() {
1880 return static_cast<const TemplateArgumentLoc *>(data[1]);
1881 }
1882};
Guy Benyei11169dd2012-12-18 14:30:41 +00001883class DeclVisit : public VisitorJob {
1884public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001885 DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
1886 : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
1887 isFirst ? (void *)1 : (void *)nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001888 static bool classof(const VisitorJob *VJ) {
1889 return VJ->getKind() == DeclVisitKind;
1890 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001892 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001893};
1894class TypeLocVisit : public VisitorJob {
1895public:
Michael Kruse7520cf02020-03-25 09:26:14 -05001896 TypeLocVisit(TypeLoc tl, CXCursor parent)
1897 : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1898 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001899
1900 static bool classof(const VisitorJob *VJ) {
1901 return VJ->getKind() == TypeLocVisitKind;
1902 }
1903
Michael Kruse7520cf02020-03-25 09:26:14 -05001904 TypeLoc get() const {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 }
1908};
1909
1910class LabelRefVisit : public VisitorJob {
1911public:
1912 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001913 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1914 labelLoc.getPtrEncoding()) {}
1915
Guy Benyei11169dd2012-12-18 14:30:41 +00001916 static bool classof(const VisitorJob *VJ) {
1917 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1918 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001919 const LabelDecl *get() const {
1920 return static_cast<const LabelDecl *>(data[0]);
1921 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001922 SourceLocation getLoc() const {
1923 return SourceLocation::getFromPtrEncoding(data[1]);
1924 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001925};
Michael Kruse7520cf02020-03-25 09:26:14 -05001926
Guy Benyei11169dd2012-12-18 14:30:41 +00001927class NestedNameSpecifierLocVisit : public VisitorJob {
1928public:
1929 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001930 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1931 Qualifier.getNestedNameSpecifier(),
1932 Qualifier.getOpaqueData()) {}
1933
Guy Benyei11169dd2012-12-18 14:30:41 +00001934 static bool classof(const VisitorJob *VJ) {
1935 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1936 }
Michael Kruse7520cf02020-03-25 09:26:14 -05001937
Guy Benyei11169dd2012-12-18 14:30:41 +00001938 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001939 return NestedNameSpecifierLoc(
Michael Kruse7520cf02020-03-25 09:26:14 -05001940 const_cast<NestedNameSpecifier *>(
1941 static_cast<const NestedNameSpecifier *>(data[0])),
1942 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001943 }
1944};
Michael Kruse7520cf02020-03-25 09:26:14 -05001945
Guy Benyei11169dd2012-12-18 14:30:41 +00001946class DeclarationNameInfoVisit : public VisitorJob {
1947public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001948 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001949 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001950 static bool classof(const VisitorJob *VJ) {
1951 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1952 }
1953 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001954 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001955 switch (S->getStmtClass()) {
1956 default:
1957 llvm_unreachable("Unhandled Stmt");
1958 case clang::Stmt::MSDependentExistsStmtClass:
1959 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1960 case Stmt::CXXDependentScopeMemberExprClass:
1961 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1962 case Stmt::DependentScopeDeclRefExprClass:
1963 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001964 case Stmt::OMPCriticalDirectiveClass:
1965 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001966 }
1967 }
1968};
1969class MemberRefVisit : public VisitorJob {
1970public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001972 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1973 L.getPtrEncoding()) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 static bool classof(const VisitorJob *VJ) {
1975 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1976 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977 const FieldDecl *get() const {
1978 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 }
1980 SourceLocation getLoc() const {
Michael Kruse7520cf02020-03-25 09:26:14 -05001981 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 }
1983};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001984class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001985 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 VisitorWorkList &WL;
1987 CXCursor Parent;
Michael Kruse7520cf02020-03-25 09:26:14 -05001988
Guy Benyei11169dd2012-12-18 14:30:41 +00001989public:
1990 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
Michael Kruse7520cf02020-03-25 09:26:14 -05001991 : WL(wl), Parent(parent) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001992
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1994 void VisitBlockExpr(const BlockExpr *B);
1995 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1996 void VisitCompoundStmt(const CompoundStmt *S);
Michael Kruse7520cf02020-03-25 09:26:14 -05001997 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
1998 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001999 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
2000 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
2001 void VisitCXXNewExpr(const CXXNewExpr *E);
2002 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
2003 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
2004 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
2005 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
2006 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
2007 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
2008 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
2009 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002010 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002011 void VisitDeclRefExpr(const DeclRefExpr *D);
2012 void VisitDeclStmt(const DeclStmt *S);
2013 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
2014 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
2015 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
2016 void VisitForStmt(const ForStmt *FS);
2017 void VisitGotoStmt(const GotoStmt *GS);
2018 void VisitIfStmt(const IfStmt *If);
2019 void VisitInitListExpr(const InitListExpr *IE);
2020 void VisitMemberExpr(const MemberExpr *M);
2021 void VisitOffsetOfExpr(const OffsetOfExpr *E);
2022 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
2023 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
2024 void VisitOverloadExpr(const OverloadExpr *E);
2025 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
2026 void VisitStmt(const Stmt *S);
2027 void VisitSwitchStmt(const SwitchStmt *S);
2028 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002029 void VisitTypeTraitExpr(const TypeTraitExpr *E);
2030 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
2031 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
2032 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
2033 void VisitVAArgExpr(const VAArgExpr *E);
2034 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
2035 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
2036 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
2037 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002038 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00002039 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002040 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002041 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002042 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00002043 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002044 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002045 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002046 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00002047 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002048 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002049 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00002050 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
cchen47d60942019-12-05 13:43:48 -05002051 void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002052 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002053 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00002054 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002055 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00002056 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002057 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002058 void
2059 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00002060 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00002061 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataevc112e942020-02-28 09:52:15 -05002062 void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002063 void VisitOMPScanDirective(const OMPScanDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002064 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00002065 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002066 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00002067 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Samuel Antaodf67fc42016-01-19 19:15:56 +00002068 void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
Samuel Antao72590762016-01-19 20:04:50 +00002069 void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002070 void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002071 void
2072 VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00002073 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Alexey Bataev49f6e782015-12-01 04:18:41 +00002074 void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002075 void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
Alexey Bataev60e51c42019-10-10 20:13:02 +00002076 void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
Alexey Bataevb8552ab2019-10-18 16:47:35 +00002077 void
2078 VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
Alexey Bataev5bbcead2019-10-14 17:17:41 +00002079 void VisitOMPParallelMasterTaskLoopDirective(
2080 const OMPParallelMasterTaskLoopDirective *D);
Alexey Bataev14a388f2019-10-25 10:27:13 -04002081 void VisitOMPParallelMasterTaskLoopSimdDirective(
2082 const OMPParallelMasterTaskLoopSimdDirective *D);
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00002083 void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
Carlo Bertolli9925f152016-06-27 14:55:37 +00002084 void VisitOMPDistributeParallelForDirective(
2085 const OMPDistributeParallelForDirective *D);
Kelvin Li4a39add2016-07-05 05:00:15 +00002086 void VisitOMPDistributeParallelForSimdDirective(
2087 const OMPDistributeParallelForSimdDirective *D);
Kelvin Li787f3fc2016-07-06 04:45:38 +00002088 void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
Kelvin Lia579b912016-07-14 02:54:56 +00002089 void VisitOMPTargetParallelForSimdDirective(
2090 const OMPTargetParallelForSimdDirective *D);
Kelvin Li986330c2016-07-20 22:57:10 +00002091 void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
Kelvin Li02532872016-08-05 14:37:37 +00002092 void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
Kelvin Li4e325f72016-10-25 12:50:55 +00002093 void VisitOMPTeamsDistributeSimdDirective(
2094 const OMPTeamsDistributeSimdDirective *D);
Kelvin Li579e41c2016-11-30 23:51:03 +00002095 void VisitOMPTeamsDistributeParallelForSimdDirective(
2096 const OMPTeamsDistributeParallelForSimdDirective *D);
Kelvin Li7ade93f2016-12-09 03:24:30 +00002097 void VisitOMPTeamsDistributeParallelForDirective(
2098 const OMPTeamsDistributeParallelForDirective *D);
Kelvin Libf594a52016-12-17 05:48:59 +00002099 void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
Kelvin Li83c451e2016-12-25 04:52:54 +00002100 void VisitOMPTargetTeamsDistributeDirective(
2101 const OMPTargetTeamsDistributeDirective *D);
Kelvin Li80e8f562016-12-29 22:16:30 +00002102 void VisitOMPTargetTeamsDistributeParallelForDirective(
2103 const OMPTargetTeamsDistributeParallelForDirective *D);
Kelvin Li1851df52017-01-03 05:23:48 +00002104 void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
2105 const OMPTargetTeamsDistributeParallelForSimdDirective *D);
Kelvin Lida681182017-01-10 18:08:18 +00002106 void VisitOMPTargetTeamsDistributeSimdDirective(
2107 const OMPTargetTeamsDistributeSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108
Guy Benyei11169dd2012-12-18 14:30:41 +00002109private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
James Y Knight04ec5bf2015-12-24 02:59:37 +00002112 void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2113 unsigned NumTemplateArgs);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002114 void AddMemberRef(const FieldDecl *D, SourceLocation L);
2115 void AddStmt(const Stmt *S);
2116 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002119 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00002120};
Michael Kruse7520cf02020-03-25 09:26:14 -05002121} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00002122
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 // 'S' should always be non-null, since it comes from the
2125 // statement we are visiting.
2126 WL.push_back(DeclarationNameInfoVisit(S, Parent));
2127}
2128
Michael Kruse7520cf02020-03-25 09:26:14 -05002129void EnqueueVisitor::AddNestedNameSpecifierLoc(
2130 NestedNameSpecifierLoc Qualifier) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 if (Qualifier)
2132 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
2133}
2134
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 if (S)
2137 WL.push_back(StmtVisit(S, Parent));
2138}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002139void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 if (D)
2141 WL.push_back(DeclVisit(D, Parent, isFirst));
2142}
James Y Knight04ec5bf2015-12-24 02:59:37 +00002143void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
2144 unsigned NumTemplateArgs) {
2145 WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00002146}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 if (D)
2149 WL.push_back(MemberRefVisit(D, L, Parent));
2150}
2151void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
2152 if (TI)
2153 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00002157 for (const Stmt *SubStmt : S->children()) {
2158 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 }
2160 if (size == WL.size())
2161 return;
2162 // Now reverse the entries we just added. This will match the DFS
2163 // ordering performed by the worklist.
2164 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2165 std::reverse(I, E);
2166}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002167namespace {
2168class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2169 EnqueueVisitor *Visitor;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00002170 /// Process clauses with list of variables.
Michael Kruse7520cf02020-03-25 09:26:14 -05002171 template <typename T> void VisitOMPClauseList(T *Node);
2172
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002173public:
Michael Kruse7520cf02020-03-25 09:26:14 -05002174 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
Johannes Doerfert419a5592020-03-30 19:58:40 -05002175#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
2176#include "llvm/Frontend/OpenMP/OMPKinds.def"
Alexey Bataev3392d762016-02-16 11:18:12 +00002177 void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002178 void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002179};
2180
Alexey Bataev3392d762016-02-16 11:18:12 +00002181void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
2182 const OMPClauseWithPreInit *C) {
2183 Visitor->AddStmt(C->getPreInitStmt());
2184}
2185
Alexey Bataev005248a2016-02-25 05:25:57 +00002186void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
2187 const OMPClauseWithPostUpdate *C) {
Alexey Bataev37e594c2016-03-04 07:21:16 +00002188 VisitOMPClauseWithPreInit(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002189 Visitor->AddStmt(C->getPostUpdateExpr());
2190}
2191
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002192void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
Arpith Chacko Jacobfe4890a2017-01-18 20:40:48 +00002193 VisitOMPClauseWithPreInit(C);
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002194 Visitor->AddStmt(C->getCondition());
2195}
2196
Alexey Bataev3778b602014-07-17 07:32:53 +00002197void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2198 Visitor->AddStmt(C->getCondition());
2199}
2200
Alexey Bataev568a8332014-03-06 06:15:19 +00002201void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
Arpith Chacko Jacob33c849a2017-01-25 00:57:16 +00002202 VisitOMPClauseWithPreInit(C);
Alexey Bataev568a8332014-03-06 06:15:19 +00002203 Visitor->AddStmt(C->getNumThreads());
2204}
2205
Alexey Bataev62c87d22014-03-21 04:51:18 +00002206void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2207 Visitor->AddStmt(C->getSafelen());
2208}
2209
Alexey Bataev66b15b52015-08-21 11:14:16 +00002210void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2211 Visitor->AddStmt(C->getSimdlen());
2212}
2213
Alexey Bataev9cc10fc2019-03-12 18:52:33 +00002214void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
2215 Visitor->AddStmt(C->getAllocator());
2216}
2217
Alexander Musman8bd31e62014-05-27 15:12:19 +00002218void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2219 Visitor->AddStmt(C->getNumForLoops());
2220}
2221
Michael Kruse7520cf02020-03-25 09:26:14 -05002222void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}
Alexey Bataev756c1962013-09-24 03:17:45 +00002223
Michael Kruse7520cf02020-03-25 09:26:14 -05002224void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002225
Alexey Bataev56dafe82014-06-20 07:16:17 +00002226void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002227 VisitOMPClauseWithPreInit(C);
Alexey Bataev56dafe82014-06-20 07:16:17 +00002228 Visitor->AddStmt(C->getChunkSize());
2229}
2230
Alexey Bataev10e775f2015-07-30 11:36:16 +00002231void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2232 Visitor->AddStmt(C->getNumForLoops());
2233}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002234
Alexey Bataev0f0564b2020-03-17 09:17:42 -04002235void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
2236 Visitor->AddStmt(C->getEventHandler());
2237}
2238
Alexey Bataev236070f2014-06-20 11:19:47 +00002239void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2240
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002241void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2242
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002243void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2244
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002245void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2246
Alexey Bataevdea47612014-07-23 07:46:59 +00002247void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2248
Alexey Bataev67a4f222014-07-23 10:25:33 +00002249void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2250
Alexey Bataev459dec02014-07-24 06:46:57 +00002251void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2252
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002253void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2254
Alexey Bataevea9166b2020-02-06 16:30:23 -05002255void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}
2256
Alexey Bataev04a830f2020-02-10 14:30:39 -05002257void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}
2258
Alexey Bataev95598342020-02-10 15:49:05 -05002259void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}
2260
Alexey Bataev9a8defc2020-02-11 11:10:43 -05002261void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}
2262
Alexey Bataev346265e2015-09-25 10:37:12 +00002263void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2264
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002265void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2266
Alexey Bataevb825de12015-12-07 10:51:44 +00002267void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}
2268
Alexey Bataev375437a2020-03-02 14:21:20 -05002269void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {}
2270
Kelvin Li1408f912018-09-26 04:28:39 +00002271void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
2272 const OMPUnifiedAddressClause *) {}
2273
Patrick Lyster4a370b92018-10-01 13:47:43 +00002274void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
2275 const OMPUnifiedSharedMemoryClause *) {}
2276
Patrick Lyster6bdf63b2018-10-03 20:07:58 +00002277void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
2278 const OMPReverseOffloadClause *) {}
2279
Patrick Lyster3fe9e392018-10-11 14:41:10 +00002280void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
2281 const OMPDynamicAllocatorsClause *) {}
2282
Patrick Lyster7a2a27c2018-11-02 12:18:11 +00002283void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
2284 const OMPAtomicDefaultMemOrderClause *) {}
2285
Michael Wonge710d542015-08-07 16:16:36 +00002286void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2287 Visitor->AddStmt(C->getDevice());
2288}
2289
Kelvin Li099bb8c2015-11-24 20:50:12 +00002290void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
Arpith Chacko Jacobbc126342017-01-25 11:28:18 +00002291 VisitOMPClauseWithPreInit(C);
Kelvin Li099bb8c2015-11-24 20:50:12 +00002292 Visitor->AddStmt(C->getNumTeams());
2293}
2294
Michael Kruse7520cf02020-03-25 09:26:14 -05002295void OMPClauseEnqueue::VisitOMPThreadLimitClause(
2296 const OMPThreadLimitClause *C) {
Arpith Chacko Jacob7ecc0b72017-01-25 11:44:35 +00002297 VisitOMPClauseWithPreInit(C);
Kelvin Lia15fb1a2015-11-27 18:47:36 +00002298 Visitor->AddStmt(C->getThreadLimit());
2299}
2300
Alexey Bataeva0569352015-12-01 10:17:31 +00002301void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
2302 Visitor->AddStmt(C->getPriority());
2303}
2304
Alexey Bataev1fd4aed2015-12-07 12:52:51 +00002305void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
2306 Visitor->AddStmt(C->getGrainsize());
2307}
2308
Alexey Bataev382967a2015-12-08 12:06:20 +00002309void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
2310 Visitor->AddStmt(C->getNumTasks());
2311}
2312
Alexey Bataev28c75412015-12-15 08:19:24 +00002313void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
2314 Visitor->AddStmt(C->getHint());
2315}
2316
Michael Kruse7520cf02020-03-25 09:26:14 -05002317template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002318 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002319 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002320 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002321}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002322
Alexey Bataev06dea732020-03-20 09:41:22 -04002323void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
2324 VisitOMPClauseList(C);
2325}
Alexey Bataev63828a32020-03-23 10:41:08 -04002326void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
2327 VisitOMPClauseList(C);
2328}
Alexey Bataeve04483e2019-03-27 14:14:31 +00002329void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
2330 VisitOMPClauseList(C);
2331 Visitor->AddStmt(C->getAllocator());
2332}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002333void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002334 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002335 for (const auto *E : C->private_copies()) {
2336 Visitor->AddStmt(E);
2337 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002338}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002339void OMPClauseEnqueue::VisitOMPFirstprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002340 const OMPFirstprivateClause *C) {
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002341 VisitOMPClauseList(C);
Alexey Bataev417089f2016-02-17 13:19:37 +00002342 VisitOMPClauseWithPreInit(C);
2343 for (const auto *E : C->private_copies()) {
2344 Visitor->AddStmt(E);
2345 }
2346 for (const auto *E : C->inits()) {
2347 Visitor->AddStmt(E);
2348 }
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002349}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002350void OMPClauseEnqueue::VisitOMPLastprivateClause(
Michael Kruse7520cf02020-03-25 09:26:14 -05002351 const OMPLastprivateClause *C) {
Alexander Musman1bb328c2014-06-04 13:06:39 +00002352 VisitOMPClauseList(C);
Alexey Bataev005248a2016-02-25 05:25:57 +00002353 VisitOMPClauseWithPostUpdate(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002354 for (auto *E : C->private_copies()) {
2355 Visitor->AddStmt(E);
2356 }
2357 for (auto *E : C->source_exprs()) {
2358 Visitor->AddStmt(E);
2359 }
2360 for (auto *E : C->destination_exprs()) {
2361 Visitor->AddStmt(E);
2362 }
2363 for (auto *E : C->assignment_ops()) {
2364 Visitor->AddStmt(E);
2365 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002366}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002367void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002368 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002369}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002370void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2371 VisitOMPClauseList(C);
Alexey Bataev61205072016-03-02 04:57:40 +00002372 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevf24e7b12015-10-08 09:10:53 +00002373 for (auto *E : C->privates()) {
2374 Visitor->AddStmt(E);
2375 }
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002376 for (auto *E : C->lhs_exprs()) {
2377 Visitor->AddStmt(E);
2378 }
2379 for (auto *E : C->rhs_exprs()) {
2380 Visitor->AddStmt(E);
2381 }
2382 for (auto *E : C->reduction_ops()) {
2383 Visitor->AddStmt(E);
2384 }
Alexey Bataevbd1c03d2020-05-04 16:19:31 -04002385 if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
2386 for (auto *E : C->copy_ops()) {
2387 Visitor->AddStmt(E);
2388 }
2389 for (auto *E : C->copy_array_temps()) {
2390 Visitor->AddStmt(E);
2391 }
2392 for (auto *E : C->copy_array_elems()) {
2393 Visitor->AddStmt(E);
2394 }
2395 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002396}
Alexey Bataev169d96a2017-07-18 20:17:46 +00002397void OMPClauseEnqueue::VisitOMPTaskReductionClause(
2398 const OMPTaskReductionClause *C) {
2399 VisitOMPClauseList(C);
2400 VisitOMPClauseWithPostUpdate(C);
2401 for (auto *E : C->privates()) {
2402 Visitor->AddStmt(E);
2403 }
2404 for (auto *E : C->lhs_exprs()) {
2405 Visitor->AddStmt(E);
2406 }
2407 for (auto *E : C->rhs_exprs()) {
2408 Visitor->AddStmt(E);
2409 }
2410 for (auto *E : C->reduction_ops()) {
2411 Visitor->AddStmt(E);
2412 }
2413}
Alexey Bataevfa312f32017-07-21 18:48:21 +00002414void OMPClauseEnqueue::VisitOMPInReductionClause(
2415 const OMPInReductionClause *C) {
2416 VisitOMPClauseList(C);
2417 VisitOMPClauseWithPostUpdate(C);
2418 for (auto *E : C->privates()) {
2419 Visitor->AddStmt(E);
2420 }
2421 for (auto *E : C->lhs_exprs()) {
2422 Visitor->AddStmt(E);
2423 }
2424 for (auto *E : C->rhs_exprs()) {
2425 Visitor->AddStmt(E);
2426 }
2427 for (auto *E : C->reduction_ops()) {
2428 Visitor->AddStmt(E);
2429 }
Alexey Bataev88202be2017-07-27 13:20:36 +00002430 for (auto *E : C->taskgroup_descriptors())
2431 Visitor->AddStmt(E);
Alexey Bataevfa312f32017-07-21 18:48:21 +00002432}
Alexander Musman8dba6642014-04-22 13:09:42 +00002433void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2434 VisitOMPClauseList(C);
Alexey Bataev78849fb2016-03-09 09:49:00 +00002435 VisitOMPClauseWithPostUpdate(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002436 for (const auto *E : C->privates()) {
2437 Visitor->AddStmt(E);
2438 }
Alexander Musman3276a272015-03-21 10:12:56 +00002439 for (const auto *E : C->inits()) {
2440 Visitor->AddStmt(E);
2441 }
2442 for (const auto *E : C->updates()) {
2443 Visitor->AddStmt(E);
2444 }
2445 for (const auto *E : C->finals()) {
2446 Visitor->AddStmt(E);
2447 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002448 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002449 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002450}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002451void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2452 VisitOMPClauseList(C);
2453 Visitor->AddStmt(C->getAlignment());
2454}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002455void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2456 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002457 for (auto *E : C->source_exprs()) {
2458 Visitor->AddStmt(E);
2459 }
2460 for (auto *E : C->destination_exprs()) {
2461 Visitor->AddStmt(E);
2462 }
2463 for (auto *E : C->assignment_ops()) {
2464 Visitor->AddStmt(E);
2465 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002466}
Michael Kruse7520cf02020-03-25 09:26:14 -05002467void OMPClauseEnqueue::VisitOMPCopyprivateClause(
2468 const OMPCopyprivateClause *C) {
Alexey Bataevbae9a792014-06-27 10:37:06 +00002469 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002470 for (auto *E : C->source_exprs()) {
2471 Visitor->AddStmt(E);
2472 }
2473 for (auto *E : C->destination_exprs()) {
2474 Visitor->AddStmt(E);
2475 }
2476 for (auto *E : C->assignment_ops()) {
2477 Visitor->AddStmt(E);
2478 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002479}
Alexey Bataev6125da92014-07-21 11:26:11 +00002480void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2481 VisitOMPClauseList(C);
2482}
Alexey Bataevc112e942020-02-28 09:52:15 -05002483void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
2484 Visitor->AddStmt(C->getDepobj());
2485}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002486void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2487 VisitOMPClauseList(C);
2488}
Kelvin Li0bff7af2015-11-23 05:32:03 +00002489void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
2490 VisitOMPClauseList(C);
2491}
Carlo Bertollib4adf552016-01-15 18:50:31 +00002492void OMPClauseEnqueue::VisitOMPDistScheduleClause(
2493 const OMPDistScheduleClause *C) {
Alexey Bataev3392d762016-02-16 11:18:12 +00002494 VisitOMPClauseWithPreInit(C);
Carlo Bertollib4adf552016-01-15 18:50:31 +00002495 Visitor->AddStmt(C->getChunkSize());
Carlo Bertollib4adf552016-01-15 18:50:31 +00002496}
Alexey Bataev3392d762016-02-16 11:18:12 +00002497void OMPClauseEnqueue::VisitOMPDefaultmapClause(
2498 const OMPDefaultmapClause * /*C*/) {}
Samuel Antao661c0902016-05-26 17:39:58 +00002499void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
2500 VisitOMPClauseList(C);
2501}
Samuel Antaoec172c62016-05-26 17:49:04 +00002502void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
2503 VisitOMPClauseList(C);
2504}
Michael Kruse7520cf02020-03-25 09:26:14 -05002505void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
2506 const OMPUseDevicePtrClause *C) {
Carlo Bertolli2404b172016-07-13 15:37:16 +00002507 VisitOMPClauseList(C);
2508}
Alexey Bataeva888fc62020-05-21 08:30:23 -04002509void OMPClauseEnqueue::VisitOMPUseDeviceAddrClause(
2510 const OMPUseDeviceAddrClause *C) {
2511 VisitOMPClauseList(C);
2512}
Michael Kruse7520cf02020-03-25 09:26:14 -05002513void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
2514 const OMPIsDevicePtrClause *C) {
Carlo Bertolli70594e92016-07-13 17:16:49 +00002515 VisitOMPClauseList(C);
2516}
Alexey Bataevb6e70842019-12-16 15:54:17 -05002517void OMPClauseEnqueue::VisitOMPNontemporalClause(
2518 const OMPNontemporalClause *C) {
2519 VisitOMPClauseList(C);
Alexey Bataev0860db92019-12-19 10:01:10 -05002520 for (const auto *E : C->private_refs())
2521 Visitor->AddStmt(E);
Alexey Bataevb6e70842019-12-16 15:54:17 -05002522}
Alexey Bataevcb8e6912020-01-31 16:09:26 -05002523void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
Alexey Bataevb5be1c52020-04-21 13:21:00 -04002524void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
2525 const OMPUsesAllocatorsClause *C) {
2526 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
2527 const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);
2528 Visitor->AddStmt(D.Allocator);
2529 Visitor->AddStmt(D.AllocatorTraits);
2530 }
2531}
Alexey Bataev2e499ee2020-05-18 13:37:53 -04002532void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) {
2533 Visitor->AddStmt(C->getModifier());
2534 for (const Expr *E : C->varlists())
2535 Visitor->AddStmt(E);
2536}
Michael Kruse7520cf02020-03-25 09:26:14 -05002537} // namespace
Alexey Bataev756c1962013-09-24 03:17:45 +00002538
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002539void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2540 unsigned size = WL.size();
2541 OMPClauseEnqueue Visitor(this);
2542 Visitor.Visit(S);
2543 if (size == WL.size())
2544 return;
2545 // Now reverse the entries we just added. This will match the DFS
2546 // ordering performed by the worklist.
2547 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2548 std::reverse(I, E);
2549}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002550void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002551 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2552}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002553void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002554 AddDecl(B->getBlockDecl());
2555}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002556void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002557 EnqueueChildren(E);
2558 AddTypeLoc(E->getTypeSourceInfo());
2559}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002560void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002561 for (auto &I : llvm::reverse(S->body()))
2562 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002563}
Michael Kruse7520cf02020-03-25 09:26:14 -05002564void EnqueueVisitor::VisitMSDependentExistsStmt(
2565 const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002566 AddStmt(S->getSubStmt());
2567 AddDeclarationNameInfo(S);
2568 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2569 AddNestedNameSpecifierLoc(QualifierLoc);
2570}
2571
Michael Kruse7520cf02020-03-25 09:26:14 -05002572void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
2573 const CXXDependentScopeMemberExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002574 if (E->hasExplicitTemplateArgs())
2575 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002576 AddDeclarationNameInfo(E);
2577 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2578 AddNestedNameSpecifierLoc(QualifierLoc);
2579 if (!E->isImplicitAccess())
2580 AddStmt(E->getBase());
2581}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002582void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002583 // Enqueue the initializer , if any.
2584 AddStmt(E->getInitializer());
2585 // Enqueue the array size, if any.
Richard Smithb9fb1212019-05-06 03:47:15 +00002586 AddStmt(E->getArraySize().getValueOr(nullptr));
Guy Benyei11169dd2012-12-18 14:30:41 +00002587 // Enqueue the allocated type.
2588 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2589 // Enqueue the placement arguments.
2590 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002591 AddStmt(E->getPlacementArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002592}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002593void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002594 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002595 AddStmt(CE->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002596 AddStmt(CE->getCallee());
2597 AddStmt(CE->getArg(0));
2598}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002599void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002600 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002601 // Visit the name of the type being destroyed.
2602 AddTypeLoc(E->getDestroyedTypeInfo());
2603 // Visit the scope type that looks disturbingly like the nested-name-specifier
2604 // but isn't.
2605 AddTypeLoc(E->getScopeTypeInfo());
2606 // Visit the nested-name-specifier.
2607 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2608 AddNestedNameSpecifierLoc(QualifierLoc);
2609 // Visit base expression.
2610 AddStmt(E->getBase());
2611}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002612void EnqueueVisitor::VisitCXXScalarValueInitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002613 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002614 AddTypeLoc(E->getTypeSourceInfo());
2615}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002616void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002617 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002618 EnqueueChildren(E);
2619 AddTypeLoc(E->getTypeSourceInfo());
2620}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002621void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002622 EnqueueChildren(E);
2623 if (E->isTypeOperand())
2624 AddTypeLoc(E->getTypeOperandSourceInfo());
2625}
2626
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002627void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002628 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002629 EnqueueChildren(E);
2630 AddTypeLoc(E->getTypeSourceInfo());
2631}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002632void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002633 EnqueueChildren(E);
2634 if (E->isTypeOperand())
2635 AddTypeLoc(E->getTypeOperandSourceInfo());
2636}
2637
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002638void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002639 EnqueueChildren(S);
2640 AddDecl(S->getExceptionDecl());
2641}
2642
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002643void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002644 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002645 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002646 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002647}
2648
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002649void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002650 if (DR->hasExplicitTemplateArgs())
2651 AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002652 WL.push_back(DeclRefExprParts(DR, Parent));
2653}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002654void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002655 const DependentScopeDeclRefExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002656 if (E->hasExplicitTemplateArgs())
2657 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002658 AddDeclarationNameInfo(E);
2659 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2660}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002661void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002662 unsigned size = WL.size();
2663 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002664 for (const auto *D : S->decls()) {
2665 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002666 isFirst = false;
2667 }
2668 if (size == WL.size())
2669 return;
2670 // Now reverse the entries we just added. This will match the DFS
2671 // ordering performed by the worklist.
2672 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2673 std::reverse(I, E);
2674}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002675void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002676 AddStmt(E->getInit());
David Majnemerf7e36092016-06-23 00:15:04 +00002677 for (const DesignatedInitExpr::Designator &D :
2678 llvm::reverse(E->designators())) {
2679 if (D.isFieldDesignator()) {
2680 if (FieldDecl *Field = D.getField())
2681 AddMemberRef(Field, D.getFieldLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00002682 continue;
2683 }
David Majnemerf7e36092016-06-23 00:15:04 +00002684 if (D.isArrayDesignator()) {
2685 AddStmt(E->getArrayIndex(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002686 continue;
2687 }
David Majnemerf7e36092016-06-23 00:15:04 +00002688 assert(D.isArrayRangeDesignator() && "Unknown designator kind");
2689 AddStmt(E->getArrayRangeEnd(D));
2690 AddStmt(E->getArrayRangeStart(D));
Guy Benyei11169dd2012-12-18 14:30:41 +00002691 }
2692}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002693void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002694 EnqueueChildren(E);
2695 AddTypeLoc(E->getTypeInfoAsWritten());
2696}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002697void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 AddStmt(FS->getBody());
2699 AddStmt(FS->getInc());
2700 AddStmt(FS->getCond());
2701 AddDecl(FS->getConditionVariable());
2702 AddStmt(FS->getInit());
2703}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002704void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002705 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2706}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002707void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002708 AddStmt(If->getElse());
2709 AddStmt(If->getThen());
2710 AddStmt(If->getCond());
Milian Wolff08e18122020-05-02 22:18:09 +02002711 AddStmt(If->getInit());
Guy Benyei11169dd2012-12-18 14:30:41 +00002712 AddDecl(If->getConditionVariable());
2713}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002714void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 // We care about the syntactic form of the initializer list, only.
2716 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2717 IE = Syntactic;
2718 EnqueueChildren(IE);
2719}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002720void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002721 WL.push_back(MemberExprParts(M, Parent));
Michael Kruse7520cf02020-03-25 09:26:14 -05002722
Guy Benyei11169dd2012-12-18 14:30:41 +00002723 // If the base of the member access expression is an implicit 'this', don't
2724 // visit it.
2725 // FIXME: If we ever want to show these implicit accesses, this will be
2726 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002727 if (M->isImplicitAccess())
2728 return;
2729
2730 // Ignore base anonymous struct/union fields, otherwise they will shadow the
Alexander Kornienko2a8c18d2018-04-06 15:14:32 +00002731 // real field that we are interested in.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002732 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2733 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2734 if (FD->isAnonymousStructOrUnion()) {
2735 AddStmt(SubME->getBase());
2736 return;
2737 }
2738 }
2739 }
2740
2741 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002742}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002743void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002744 AddTypeLoc(E->getEncodedTypeSourceInfo());
2745}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002746void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002747 EnqueueChildren(M);
2748 AddTypeLoc(M->getClassReceiverTypeInfo());
2749}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002750void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002751 // Visit the components of the offsetof expression.
2752 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
Michael Kruse7520cf02020-03-25 09:26:14 -05002753 const OffsetOfNode &Node = E->getComponent(I - 1);
Guy Benyei11169dd2012-12-18 14:30:41 +00002754 switch (Node.getKind()) {
2755 case OffsetOfNode::Array:
2756 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2757 break;
2758 case OffsetOfNode::Field:
2759 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2760 break;
2761 case OffsetOfNode::Identifier:
2762 case OffsetOfNode::Base:
2763 continue;
2764 }
2765 }
2766 // Visit the type into which we're computing the offset.
2767 AddTypeLoc(E->getTypeSourceInfo());
2768}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002769void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
James Y Knight04ec5bf2015-12-24 02:59:37 +00002770 if (E->hasExplicitTemplateArgs())
2771 AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
Guy Benyei11169dd2012-12-18 14:30:41 +00002772 WL.push_back(OverloadExprParts(E, Parent));
2773}
2774void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Michael Kruse7520cf02020-03-25 09:26:14 -05002775 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002776 EnqueueChildren(E);
2777 if (E->isArgumentType())
2778 AddTypeLoc(E->getArgumentTypeInfo());
2779}
Michael Kruse7520cf02020-03-25 09:26:14 -05002780void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002781void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002782 AddStmt(S->getBody());
2783 AddStmt(S->getCond());
2784 AddDecl(S->getConditionVariable());
2785}
2786
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002787void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002788 AddStmt(W->getBody());
2789 AddStmt(W->getCond());
2790 AddDecl(W->getConditionVariable());
2791}
2792
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002793void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002794 for (unsigned I = E->getNumArgs(); I > 0; --I)
Michael Kruse7520cf02020-03-25 09:26:14 -05002795 AddTypeLoc(E->getArg(I - 1));
Guy Benyei11169dd2012-12-18 14:30:41 +00002796}
2797
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002798void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002799 AddTypeLoc(E->getQueriedTypeSourceInfo());
2800}
2801
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002802void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002803 EnqueueChildren(E);
2804}
2805
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002806void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002807 VisitOverloadExpr(U);
2808 if (!U->isImplicitAccess())
2809 AddStmt(U->getBase());
2810}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002811void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002812 AddStmt(E->getSubExpr());
2813 AddTypeLoc(E->getWrittenTypeInfo());
2814}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002815void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002816 WL.push_back(SizeOfPackExprParts(E, Parent));
2817}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002818void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002819 // If the opaque value has a source expression, just transparently
2820 // visit that. This is useful for (e.g.) pseudo-object expressions.
2821 if (Expr *SourceExpr = E->getSourceExpr())
2822 return Visit(SourceExpr);
2823}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002824void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002825 AddStmt(E->getBody());
2826 WL.push_back(LambdaExprParts(E, Parent));
2827}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002828void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002829 // Treat the expression like its syntactic form.
2830 Visit(E->getSyntacticForm());
2831}
2832
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002833void EnqueueVisitor::VisitOMPExecutableDirective(
Michael Kruse7520cf02020-03-25 09:26:14 -05002834 const OMPExecutableDirective *D) {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002835 EnqueueChildren(D);
2836 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2837 E = D->clauses().end();
2838 I != E; ++I)
2839 EnqueueChildren(*I);
2840}
2841
Alexander Musman3aaab662014-08-19 11:27:13 +00002842void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2843 VisitOMPExecutableDirective(D);
2844}
2845
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002846void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2847 VisitOMPExecutableDirective(D);
2848}
2849
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002850void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002851 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002852}
2853
Alexey Bataevf29276e2014-06-18 04:14:57 +00002854void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002855 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002856}
2857
Alexander Musmanf82886e2014-09-18 05:12:34 +00002858void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2859 VisitOMPLoopDirective(D);
2860}
2861
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002862void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2863 VisitOMPExecutableDirective(D);
2864}
2865
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002866void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2867 VisitOMPExecutableDirective(D);
2868}
2869
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002870void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2871 VisitOMPExecutableDirective(D);
2872}
2873
Alexander Musman80c22892014-07-17 08:54:58 +00002874void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2875 VisitOMPExecutableDirective(D);
2876}
2877
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002878void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2879 VisitOMPExecutableDirective(D);
2880 AddDeclarationNameInfo(D);
2881}
2882
Michael Kruse7520cf02020-03-25 09:26:14 -05002883void EnqueueVisitor::VisitOMPParallelForDirective(
2884 const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002885 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002886}
2887
Alexander Musmane4e893b2014-09-23 09:33:00 +00002888void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2889 const OMPParallelForSimdDirective *D) {
2890 VisitOMPLoopDirective(D);
2891}
2892
cchen47d60942019-12-05 13:43:48 -05002893void EnqueueVisitor::VisitOMPParallelMasterDirective(
2894 const OMPParallelMasterDirective *D) {
2895 VisitOMPExecutableDirective(D);
2896}
2897
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002898void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2899 const OMPParallelSectionsDirective *D) {
2900 VisitOMPExecutableDirective(D);
2901}
2902
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002903void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2904 VisitOMPExecutableDirective(D);
2905}
2906
Michael Kruse7520cf02020-03-25 09:26:14 -05002907void EnqueueVisitor::VisitOMPTaskyieldDirective(
2908 const OMPTaskyieldDirective *D) {
Alexey Bataev68446b72014-07-18 07:47:19 +00002909 VisitOMPExecutableDirective(D);
2910}
2911
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002912void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2913 VisitOMPExecutableDirective(D);
2914}
2915
Alexey Bataev2df347a2014-07-18 10:17:07 +00002916void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2917 VisitOMPExecutableDirective(D);
2918}
2919
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002920void EnqueueVisitor::VisitOMPTaskgroupDirective(
2921 const OMPTaskgroupDirective *D) {
2922 VisitOMPExecutableDirective(D);
Alexey Bataev3b1b8952017-07-25 15:53:26 +00002923 if (const Expr *E = D->getReductionRef())
2924 VisitStmt(E);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002925}
2926
Alexey Bataev6125da92014-07-21 11:26:11 +00002927void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2928 VisitOMPExecutableDirective(D);
2929}
2930
Alexey Bataevc112e942020-02-28 09:52:15 -05002931void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
2932 VisitOMPExecutableDirective(D);
2933}
2934
Alexey Bataevfcba7c32020-03-20 07:03:01 -04002935void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
2936 VisitOMPExecutableDirective(D);
2937}
2938
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002939void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2940 VisitOMPExecutableDirective(D);
2941}
2942
Alexey Bataev0162e452014-07-22 10:10:35 +00002943void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2944 VisitOMPExecutableDirective(D);
2945}
2946
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002947void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2948 VisitOMPExecutableDirective(D);
2949}
2950
Alexey Bataevc112e942020-02-28 09:52:15 -05002951void EnqueueVisitor::VisitOMPTargetDataDirective(
2952 const OMPTargetDataDirective *D) {
Michael Wong65f367f2015-07-21 13:44:28 +00002953 VisitOMPExecutableDirective(D);
2954}
2955
Samuel Antaodf67fc42016-01-19 19:15:56 +00002956void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
2957 const OMPTargetEnterDataDirective *D) {
2958 VisitOMPExecutableDirective(D);
2959}
2960
Samuel Antao72590762016-01-19 20:04:50 +00002961void EnqueueVisitor::VisitOMPTargetExitDataDirective(
2962 const OMPTargetExitDataDirective *D) {
2963 VisitOMPExecutableDirective(D);
2964}
2965
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00002966void EnqueueVisitor::VisitOMPTargetParallelDirective(
2967 const OMPTargetParallelDirective *D) {
2968 VisitOMPExecutableDirective(D);
2969}
2970
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00002971void EnqueueVisitor::VisitOMPTargetParallelForDirective(
2972 const OMPTargetParallelForDirective *D) {
2973 VisitOMPLoopDirective(D);
2974}
2975
Alexey Bataev13314bf2014-10-09 04:18:56 +00002976void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2977 VisitOMPExecutableDirective(D);
2978}
2979
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002980void EnqueueVisitor::VisitOMPCancellationPointDirective(
2981 const OMPCancellationPointDirective *D) {
2982 VisitOMPExecutableDirective(D);
2983}
2984
Alexey Bataev80909872015-07-02 11:25:17 +00002985void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2986 VisitOMPExecutableDirective(D);
2987}
2988
Alexey Bataev49f6e782015-12-01 04:18:41 +00002989void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
2990 VisitOMPLoopDirective(D);
2991}
2992
Alexey Bataev0a6ed842015-12-03 09:40:15 +00002993void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
2994 const OMPTaskLoopSimdDirective *D) {
2995 VisitOMPLoopDirective(D);
2996}
2997
Alexey Bataev60e51c42019-10-10 20:13:02 +00002998void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
2999 const OMPMasterTaskLoopDirective *D) {
3000 VisitOMPLoopDirective(D);
3001}
3002
Alexey Bataevb8552ab2019-10-18 16:47:35 +00003003void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
3004 const OMPMasterTaskLoopSimdDirective *D) {
3005 VisitOMPLoopDirective(D);
3006}
3007
Alexey Bataev5bbcead2019-10-14 17:17:41 +00003008void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
3009 const OMPParallelMasterTaskLoopDirective *D) {
3010 VisitOMPLoopDirective(D);
3011}
3012
Alexey Bataev14a388f2019-10-25 10:27:13 -04003013void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
3014 const OMPParallelMasterTaskLoopSimdDirective *D) {
3015 VisitOMPLoopDirective(D);
3016}
3017
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00003018void EnqueueVisitor::VisitOMPDistributeDirective(
3019 const OMPDistributeDirective *D) {
3020 VisitOMPLoopDirective(D);
3021}
3022
Carlo Bertolli9925f152016-06-27 14:55:37 +00003023void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
3024 const OMPDistributeParallelForDirective *D) {
3025 VisitOMPLoopDirective(D);
3026}
3027
Kelvin Li4a39add2016-07-05 05:00:15 +00003028void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
3029 const OMPDistributeParallelForSimdDirective *D) {
3030 VisitOMPLoopDirective(D);
3031}
3032
Kelvin Li787f3fc2016-07-06 04:45:38 +00003033void EnqueueVisitor::VisitOMPDistributeSimdDirective(
3034 const OMPDistributeSimdDirective *D) {
3035 VisitOMPLoopDirective(D);
3036}
3037
Kelvin Lia579b912016-07-14 02:54:56 +00003038void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
3039 const OMPTargetParallelForSimdDirective *D) {
3040 VisitOMPLoopDirective(D);
3041}
3042
Kelvin Li986330c2016-07-20 22:57:10 +00003043void EnqueueVisitor::VisitOMPTargetSimdDirective(
3044 const OMPTargetSimdDirective *D) {
3045 VisitOMPLoopDirective(D);
3046}
3047
Kelvin Li02532872016-08-05 14:37:37 +00003048void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
3049 const OMPTeamsDistributeDirective *D) {
3050 VisitOMPLoopDirective(D);
3051}
3052
Kelvin Li4e325f72016-10-25 12:50:55 +00003053void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
3054 const OMPTeamsDistributeSimdDirective *D) {
3055 VisitOMPLoopDirective(D);
3056}
3057
Kelvin Li579e41c2016-11-30 23:51:03 +00003058void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
3059 const OMPTeamsDistributeParallelForSimdDirective *D) {
3060 VisitOMPLoopDirective(D);
3061}
3062
Kelvin Li7ade93f2016-12-09 03:24:30 +00003063void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
3064 const OMPTeamsDistributeParallelForDirective *D) {
3065 VisitOMPLoopDirective(D);
3066}
3067
Kelvin Libf594a52016-12-17 05:48:59 +00003068void EnqueueVisitor::VisitOMPTargetTeamsDirective(
3069 const OMPTargetTeamsDirective *D) {
3070 VisitOMPExecutableDirective(D);
3071}
3072
Kelvin Li83c451e2016-12-25 04:52:54 +00003073void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
3074 const OMPTargetTeamsDistributeDirective *D) {
3075 VisitOMPLoopDirective(D);
3076}
3077
Kelvin Li80e8f562016-12-29 22:16:30 +00003078void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
3079 const OMPTargetTeamsDistributeParallelForDirective *D) {
3080 VisitOMPLoopDirective(D);
3081}
3082
Kelvin Li1851df52017-01-03 05:23:48 +00003083void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
3084 const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
3085 VisitOMPLoopDirective(D);
3086}
3087
Kelvin Lida681182017-01-10 18:08:18 +00003088void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
3089 const OMPTargetTeamsDistributeSimdDirective *D) {
3090 VisitOMPLoopDirective(D);
3091}
3092
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003093void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003094 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
3095 .Visit(S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003096}
3097
3098bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
3099 if (RegionOfInterest.isValid()) {
3100 SourceRange Range = getRawCursorExtent(C);
3101 if (Range.isInvalid() || CompareRegionOfInterest(Range))
3102 return false;
3103 }
3104 return true;
3105}
3106
3107bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
3108 while (!WL.empty()) {
3109 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00003110 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00003111
3112 // Set the Parent field, then back to its old value once we're done.
3113 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
Michael Kruse7520cf02020-03-25 09:26:14 -05003114
Guy Benyei11169dd2012-12-18 14:30:41 +00003115 switch (LI.getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05003116 case VisitorJob::DeclVisitKind: {
3117 const Decl *D = cast<DeclVisit>(&LI)->get();
3118 if (!D)
3119 continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00003120
Michael Kruse7520cf02020-03-25 09:26:14 -05003121 // For now, perform default visitation for Decls.
3122 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
3123 cast<DeclVisit>(&LI)->isFirst())))
3124 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003125
Michael Kruse7520cf02020-03-25 09:26:14 -05003126 continue;
3127 }
3128 case VisitorJob::ExplicitTemplateArgsVisitKind: {
3129 for (const TemplateArgumentLoc &Arg :
3130 *cast<ExplicitTemplateArgsVisit>(&LI)) {
3131 if (VisitTemplateArgumentLoc(Arg))
Guy Benyei11169dd2012-12-18 14:30:41 +00003132 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003133 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003134 continue;
3135 }
3136 case VisitorJob::TypeLocVisitKind: {
3137 // Perform default visitation for TypeLocs.
3138 if (Visit(cast<TypeLocVisit>(&LI)->get()))
3139 return true;
3140 continue;
3141 }
3142 case VisitorJob::LabelRefVisitKind: {
3143 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
3144 if (LabelStmt *stmt = LS->getStmt()) {
3145 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
3146 TU))) {
3147 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00003148 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003150 continue;
3151 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003152
Michael Kruse7520cf02020-03-25 09:26:14 -05003153 case VisitorJob::NestedNameSpecifierLocVisitKind: {
3154 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
3155 if (VisitNestedNameSpecifierLoc(V->get()))
3156 return true;
3157 continue;
3158 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003159
Michael Kruse7520cf02020-03-25 09:26:14 -05003160 case VisitorJob::DeclarationNameInfoVisitKind: {
3161 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
3162 return true;
3163 continue;
3164 }
3165 case VisitorJob::MemberRefVisitKind: {
3166 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
3167 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
3168 return true;
3169 continue;
3170 }
3171 case VisitorJob::StmtVisitKind: {
3172 const Stmt *S = cast<StmtVisit>(&LI)->get();
3173 if (!S)
Guy Benyei11169dd2012-12-18 14:30:41 +00003174 continue;
Richard Smithba71c082013-05-16 06:20:58 +00003175
Michael Kruse7520cf02020-03-25 09:26:14 -05003176 // Update the current cursor.
3177 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
3178 if (!IsInRegionOfInterest(Cursor))
3179 continue;
3180 switch (Visitor(Cursor, Parent, ClientData)) {
3181 case CXChildVisit_Break:
3182 return true;
3183 case CXChildVisit_Continue:
3184 break;
3185 case CXChildVisit_Recurse:
3186 if (PostChildrenVisitor)
3187 WL.push_back(PostChildrenVisit(nullptr, Cursor));
3188 EnqueueWorkList(WL, S);
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 break;
3190 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003191 continue;
3192 }
3193 case VisitorJob::MemberExprPartsKind: {
3194 // Handle the other pieces in the MemberExpr besides the base.
3195 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00003196
Michael Kruse7520cf02020-03-25 09:26:14 -05003197 // Visit the nested-name-specifier
3198 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
3199 if (VisitNestedNameSpecifierLoc(QualifierLoc))
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 return true;
Michael Kruse7520cf02020-03-25 09:26:14 -05003201
3202 // Visit the declaration name.
3203 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
3204 return true;
3205
3206 // Visit the explicitly-specified template arguments, if any.
3207 if (M->hasExplicitTemplateArgs()) {
3208 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
3209 *ArgEnd = Arg + M->getNumTemplateArgs();
3210 Arg != ArgEnd; ++Arg) {
3211 if (VisitTemplateArgumentLoc(*Arg))
3212 return true;
3213 }
3214 }
3215 continue;
3216 }
3217 case VisitorJob::DeclRefExprPartsKind: {
3218 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
3219 // Visit nested-name-specifier, if present.
3220 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
3221 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3222 return true;
3223 // Visit declaration name.
3224 if (VisitDeclarationNameInfo(DR->getNameInfo()))
3225 return true;
3226 continue;
3227 }
3228 case VisitorJob::OverloadExprPartsKind: {
3229 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
3230 // Visit the nested-name-specifier.
3231 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
3232 if (VisitNestedNameSpecifierLoc(QualifierLoc))
3233 return true;
3234 // Visit the declaration name.
3235 if (VisitDeclarationNameInfo(O->getNameInfo()))
3236 return true;
3237 // Visit the overloaded declaration reference.
3238 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
3239 return true;
3240 continue;
3241 }
3242 case VisitorJob::SizeOfPackExprPartsKind: {
3243 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
3244 NamedDecl *Pack = E->getPack();
3245 if (isa<TemplateTypeParmDecl>(Pack)) {
3246 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
3247 E->getPackLoc(), TU)))
3248 return true;
3249
3250 continue;
3251 }
3252
3253 if (isa<TemplateTemplateParmDecl>(Pack)) {
3254 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
3255 E->getPackLoc(), TU)))
3256 return true;
3257
3258 continue;
3259 }
3260
3261 // Non-type template parameter packs and function parameter packs are
3262 // treated like DeclRefExpr cursors.
3263 continue;
3264 }
3265
3266 case VisitorJob::LambdaExprPartsKind: {
3267 // Visit non-init captures.
3268 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
3269 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
3270 CEnd = E->explicit_capture_end();
3271 C != CEnd; ++C) {
3272 if (!C->capturesVariable())
3273 continue;
3274
3275 if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
3276 TU)))
3277 return true;
3278 }
3279 // Visit init captures
3280 for (auto InitExpr : E->capture_inits()) {
Christian Kandeler6e089e92020-07-08 12:19:49 -07003281 if (InitExpr && Visit(InitExpr))
Michael Kruse7520cf02020-03-25 09:26:14 -05003282 return true;
3283 }
3284
3285 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
3286 // Visit parameters and return type, if present.
3287 if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
3288 if (E->hasExplicitParameters()) {
3289 // Visit parameters.
3290 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
3291 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
3292 return true;
3293 }
3294 if (E->hasExplicitResultType()) {
3295 // Visit result type.
3296 if (Visit(Proto.getReturnLoc()))
3297 return true;
3298 }
3299 }
3300 break;
3301 }
3302
3303 case VisitorJob::PostChildrenVisitKind:
3304 if (PostChildrenVisitor(Parent, ClientData))
3305 return true;
3306 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00003307 }
3308 }
3309 return false;
3310}
3311
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003312bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00003313 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 if (!WorkListFreeList.empty()) {
3315 WL = WorkListFreeList.back();
3316 WL->clear();
3317 WorkListFreeList.pop_back();
Michael Kruse7520cf02020-03-25 09:26:14 -05003318 } else {
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 WL = new VisitorWorkList();
3320 WorkListCache.push_back(WL);
3321 }
3322 EnqueueWorkList(*WL, S);
3323 bool result = RunVisitorWorkList(*WL);
3324 WorkListFreeList.push_back(WL);
3325 return result;
3326}
3327
3328namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00003329typedef SmallVector<SourceRange, 4> RefNamePieces;
James Y Knight04ec5bf2015-12-24 02:59:37 +00003330RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
3331 const DeclarationNameInfo &NI, SourceRange QLoc,
3332 const SourceRange *TemplateArgsLoc = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
3334 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
3335 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
Michael Kruse7520cf02020-03-25 09:26:14 -05003336
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
Michael Kruse7520cf02020-03-25 09:26:14 -05003338
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 RefNamePieces Pieces;
3340
3341 if (WantQualifier && QLoc.isValid())
3342 Pieces.push_back(QLoc);
Michael Kruse7520cf02020-03-25 09:26:14 -05003343
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
3345 Pieces.push_back(NI.getLoc());
James Y Knight04ec5bf2015-12-24 02:59:37 +00003346
3347 if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
3348 Pieces.push_back(*TemplateArgsLoc);
3349
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 if (Kind == DeclarationName::CXXOperatorName) {
3351 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003352 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 Pieces.push_back(SourceLocation::getFromRawEncoding(
Michael Kruse7520cf02020-03-25 09:26:14 -05003354 NI.getInfo().CXXOperatorName.EndOpNameLoc));
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003356
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 if (WantSinglePiece) {
3358 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
3359 Pieces.clear();
3360 Pieces.push_back(R);
Michael Kruse7520cf02020-03-25 09:26:14 -05003361 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003362
Michael Kruse7520cf02020-03-25 09:26:14 -05003363 return Pieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00003364}
Michael Kruse7520cf02020-03-25 09:26:14 -05003365} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00003366
3367//===----------------------------------------------------------------------===//
3368// Misc. API hooks.
Michael Kruse7520cf02020-03-25 09:26:14 -05003369//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00003370
Chandler Carruth66660742014-06-27 16:37:27 +00003371namespace {
3372struct RegisterFatalErrorHandler {
3373 RegisterFatalErrorHandler() {
Jan Korousf7d23762019-09-12 22:55:55 +00003374 clang_install_aborting_llvm_fatal_error_handler();
Chandler Carruth66660742014-06-27 16:37:27 +00003375 }
3376};
Michael Kruse7520cf02020-03-25 09:26:14 -05003377} // namespace
Chandler Carruth66660742014-06-27 16:37:27 +00003378
Michael Kruse7520cf02020-03-25 09:26:14 -05003379static llvm::ManagedStatic<RegisterFatalErrorHandler>
3380 RegisterFatalErrorHandlerOnce;
Chandler Carruth66660742014-06-27 16:37:27 +00003381
Guy Benyei11169dd2012-12-18 14:30:41 +00003382CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
3383 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 // We use crash recovery to make some of our APIs more reliable, implicitly
3385 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00003386 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
3387 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00003388
Chandler Carruth66660742014-06-27 16:37:27 +00003389 // Look through the managed static to trigger construction of the managed
3390 // static which registers our fatal error handler. This ensures it is only
3391 // registered once.
3392 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00003393
Adrian Prantlbc068582015-07-08 01:00:30 +00003394 // Initialize targets for clang module support.
3395 llvm::InitializeAllTargets();
3396 llvm::InitializeAllTargetMCs();
3397 llvm::InitializeAllAsmPrinters();
3398 llvm::InitializeAllAsmParsers();
3399
Adrian Prantlfb2398d2015-07-17 01:19:54 +00003400 CIndexer *CIdxr = new CIndexer();
3401
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 if (excludeDeclarationsFromPCH)
3403 CIdxr->setOnlyLocalDecls();
3404 if (displayDiagnostics)
3405 CIdxr->setDisplayDiagnostics();
3406
3407 if (getenv("LIBCLANG_BGPRIO_INDEX"))
3408 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3409 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
3410 if (getenv("LIBCLANG_BGPRIO_EDIT"))
3411 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
3412 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
3413
3414 return CIdxr;
3415}
3416
3417void clang_disposeIndex(CXIndex CIdx) {
3418 if (CIdx)
3419 delete static_cast<CIndexer *>(CIdx);
3420}
3421
3422void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
3423 if (CIdx)
3424 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
3425}
3426
3427unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
3428 if (CIdx)
3429 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
3430 return 0;
3431}
3432
Alex Lorenz08615792017-12-04 21:56:36 +00003433void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
3434 const char *Path) {
3435 if (CIdx)
3436 static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
3437}
3438
Guy Benyei11169dd2012-12-18 14:30:41 +00003439void clang_toggleCrashRecovery(unsigned isEnabled) {
3440 if (isEnabled)
3441 llvm::CrashRecoveryContext::Enable();
3442 else
3443 llvm::CrashRecoveryContext::Disable();
3444}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003445
Guy Benyei11169dd2012-12-18 14:30:41 +00003446CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
3447 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003448 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003449 enum CXErrorCode Result =
3450 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00003451 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003452 assert((TU && Result == CXError_Success) ||
3453 (!TU && Result != CXError_Success));
3454 return TU;
3455}
3456
3457enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
3458 const char *ast_filename,
3459 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003460 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003461 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00003462
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003463 if (!CIdx || !ast_filename || !out_TU)
3464 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00003465
Michael Kruse7520cf02020-03-25 09:26:14 -05003466 LOG_FUNC_SECTION { *Log << ast_filename; }
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00003467
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3469 FileSystemOptions FileSystemOpts;
3470
Justin Bognerd512c1e2014-10-15 00:33:06 +00003471 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
3472 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00003473 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Richard Smithdbafb6c2017-06-29 23:23:46 +00003474 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
Michael Kruse7520cf02020-03-25 09:26:14 -05003475 ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
3476 CXXIdx->getOnlyLocalDecls(), None, CaptureDiagsKind::All,
David Blaikie6f7382d2014-08-10 19:08:04 +00003477 /*AllowPCHWithCompilerErrors=*/true,
3478 /*UserFilesAreVolatile=*/true);
David Blaikieea4395e2017-01-06 19:49:01 +00003479 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003480 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003481}
3482
3483unsigned clang_defaultEditingTranslationUnitOptions() {
Michael Kruse7520cf02020-03-25 09:26:14 -05003484 return CXTranslationUnit_PrecompiledPreamble |
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 CXTranslationUnit_CacheCompletionResults;
3486}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003487
Michael Kruse7520cf02020-03-25 09:26:14 -05003488CXTranslationUnit clang_createTranslationUnitFromSourceFile(
3489 CXIndex CIdx, const char *source_filename, int num_command_line_args,
3490 const char *const *command_line_args, unsigned num_unsaved_files,
3491 struct CXUnsavedFile *unsaved_files) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
Michael Kruse7520cf02020-03-25 09:26:14 -05003493 return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
3494 num_command_line_args, unsaved_files,
3495 num_unsaved_files, Options);
Guy Benyei11169dd2012-12-18 14:30:41 +00003496}
3497
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003498static CXErrorCode
3499clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3500 const char *const *command_line_args,
3501 int num_command_line_args,
3502 ArrayRef<CXUnsavedFile> unsaved_files,
3503 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003504 // Set up the initial return values.
3505 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003506 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003507
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003508 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003509 if (!CIdx || !out_TU)
3510 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003511
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3513
3514 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3515 setThreadBackgroundPriority();
3516
3517 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003518 bool CreatePreambleOnFirstParse =
3519 options & CXTranslationUnit_CreatePreambleOnFirstParse;
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 // FIXME: Add a flag for modules.
Michael Kruse7520cf02020-03-25 09:26:14 -05003521 TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
3522 CXTranslationUnit_SingleFileParse))
3523 ? TU_Prefix
3524 : TU_Complete;
3525 bool CacheCodeCompletionResults =
3526 options & CXTranslationUnit_CacheCompletionResults;
3527 bool IncludeBriefCommentsInCodeCompletion =
3528 options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003529 bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
3530 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
Michael Kruse7520cf02020-03-25 09:26:14 -05003531 bool RetainExcludedCB =
3532 options & CXTranslationUnit_RetainExcludedConditionalBlocks;
Ivan Donchevskii6e895282018-05-17 09:24:37 +00003533 SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
3534 if (options & CXTranslationUnit_SkipFunctionBodies) {
3535 SkipFunctionBodies =
3536 (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
3537 ? SkipFunctionBodiesScope::Preamble
3538 : SkipFunctionBodiesScope::PreambleAndMainFile;
3539 }
Ivan Donchevskiif70d28b2018-05-17 09:15:22 +00003540
3541 // Configure the diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05003542 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
3543 CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003544
Manuel Klimek016c0242016-03-01 10:56:19 +00003545 if (options & CXTranslationUnit_KeepGoing)
Ivan Donchevskii878271b2019-03-07 10:13:50 +00003546 Diags->setFatalsAsError(true);
Manuel Klimek016c0242016-03-01 10:56:19 +00003547
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003548 CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
3549 if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
3550 CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;
3551
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003553 llvm::CrashRecoveryContextCleanupRegistrar<
3554 DiagnosticsEngine,
3555 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
3556 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003557
Ahmed Charlesb8984322014-03-07 20:03:18 +00003558 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3559 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003560
3561 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05003562 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
3563 RemappedCleanup(RemappedFiles.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003564
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003565 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003566 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003567 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003568 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 }
3570
Ahmed Charlesb8984322014-03-07 20:03:18 +00003571 std::unique_ptr<std::vector<const char *>> Args(
3572 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003573
3574 // Recover resources if we crash before exiting this method.
Michael Kruse7520cf02020-03-25 09:26:14 -05003575 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
3576 ArgsCleanup(Args.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003577
3578 // Since the Clang C library is primarily used by batch tools dealing with
3579 // (often very broken) source code, where spell-checking can have a
Michael Kruse7520cf02020-03-25 09:26:14 -05003580 // significant negative impact on performance (particularly when
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 // precompiled headers are involved), we disable it by default.
3582 // Only do this if we haven't found a spell-checking-related argument.
3583 bool FoundSpellCheckingArgument = false;
3584 for (int I = 0; I != num_command_line_args; ++I) {
3585 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3586 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3587 FoundSpellCheckingArgument = true;
3588 break;
3589 }
3590 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 Args->insert(Args->end(), command_line_args,
3592 command_line_args + num_command_line_args);
3593
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003594 if (!FoundSpellCheckingArgument)
3595 Args->insert(Args->begin() + 1, "-fno-spell-checking");
3596
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 // The 'source_filename' argument is optional. If the caller does not
3598 // specify it then it is assumed that the source file is specified
3599 // in the actual argument list.
3600 // Put the source file after command_line_args otherwise if '-x' flag is
3601 // present it will be unused.
3602 if (source_filename)
3603 Args->push_back(source_filename);
3604
3605 // Do we need the detailed preprocessing record?
3606 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3607 Args->push_back("-Xclang");
3608 Args->push_back("-detailed-preprocessing-record");
3609 }
Alex Lorenzcb006402017-04-27 13:47:03 +00003610
3611 // Suppress any editor placeholder diagnostics.
3612 Args->push_back("-fallow-editor-placeholders");
3613
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003615 std::unique_ptr<ASTUnit> ErrUnit;
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003616 // Unless the user specified that they want the preamble on the first parse
3617 // set it up to be created on the first reparse. This makes the first parse
3618 // faster, trading for a slower (first) reparse.
3619 unsigned PrecompilePreambleAfterNParses =
3620 !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
Alex Lorenz08615792017-12-04 21:56:36 +00003621
Alex Lorenz08615792017-12-04 21:56:36 +00003622 LibclangInvocationReporter InvocationReporter(
3623 *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
Alex Lorenz690f0e22017-12-07 20:37:50 +00003624 options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
3625 unsaved_files);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003626 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003627 Args->data(), Args->data() + Args->size(),
3628 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003629 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
Nikolai Kosjar8edd8da2019-06-11 14:14:24 +00003630 CaptureDiagnostics, *RemappedFiles.get(),
Benjamin Kramer5c248d82015-12-15 09:30:31 +00003631 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
3632 TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
Argyrios Kyrtzidis735e92c2017-06-09 01:20:48 +00003633 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
Evgeny Mankov2ed2e622019-08-27 22:15:32 +00003634 /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
Argyrios Kyrtzidisa3e2ff12015-11-20 03:36:21 +00003635 CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
3636 &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003637
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003638 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003639 if (!Unit && !ErrUnit)
3640 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003641
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 if (NumErrors != Diags->getClient()->getNumErrors()) {
3643 // Make sure to check that 'Unit' is non-NULL.
3644 if (CXXIdx->getDisplayDiagnostics())
3645 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3646 }
3647
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003648 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3649 return CXError_ASTReadError;
3650
David Blaikieea4395e2017-01-06 19:49:01 +00003651 *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
Alex Lorenz690f0e22017-12-07 20:37:50 +00003652 if (CXTranslationUnitImpl *TU = *out_TU) {
3653 TU->ParsingOptions = options;
3654 TU->Arguments.reserve(Args->size());
3655 for (const char *Arg : *Args)
3656 TU->Arguments.push_back(Arg);
3657 return CXError_Success;
3658 }
3659 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003660}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003661
3662CXTranslationUnit
Michael Kruse7520cf02020-03-25 09:26:14 -05003663clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003664 const char *const *command_line_args,
3665 int num_command_line_args,
3666 struct CXUnsavedFile *unsaved_files,
Michael Kruse7520cf02020-03-25 09:26:14 -05003667 unsigned num_unsaved_files, unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003668 CXTranslationUnit TU;
3669 enum CXErrorCode Result = clang_parseTranslationUnit2(
3670 CIdx, source_filename, command_line_args, num_command_line_args,
3671 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003672 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003673 assert((TU && Result == CXError_Success) ||
3674 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003675 return TU;
3676}
3677
3678enum CXErrorCode clang_parseTranslationUnit2(
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003679 CXIndex CIdx, const char *source_filename,
3680 const char *const *command_line_args, int num_command_line_args,
3681 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3682 unsigned options, CXTranslationUnit *out_TU) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003683 noteBottomOfStack();
Benjamin Kramerc02670e2015-11-18 16:14:27 +00003684 SmallVector<const char *, 4> Args;
3685 Args.push_back("clang");
3686 Args.append(command_line_args, command_line_args + num_command_line_args);
3687 return clang_parseTranslationUnit2FullArgv(
3688 CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
3689 num_unsaved_files, options, out_TU);
3690}
3691
3692enum CXErrorCode clang_parseTranslationUnit2FullArgv(
3693 CXIndex CIdx, const char *source_filename,
3694 const char *const *command_line_args, int num_command_line_args,
3695 struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
3696 unsigned options, CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003697 LOG_FUNC_SECTION {
3698 *Log << source_filename << ": ";
3699 for (int i = 0; i != num_command_line_args; ++i)
3700 *Log << command_line_args[i] << " ";
3701 }
3702
Alp Toker9d85b182014-07-07 01:23:14 +00003703 if (num_unsaved_files && !unsaved_files)
3704 return CXError_InvalidArguments;
3705
Alp Toker5c532982014-07-07 22:42:03 +00003706 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003707 auto ParseTranslationUnitImpl = [=, &result] {
Alexandre Ganea471d0602019-11-29 10:52:13 -05003708 noteBottomOfStack();
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003709 result = clang_parseTranslationUnit_Impl(
3710 CIdx, source_filename, command_line_args, num_command_line_args,
3711 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3712 };
Erik Verbruggen284848d2017-08-29 09:08:02 +00003713
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 llvm::CrashRecoveryContext CRC;
3715
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003716 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3718 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3719 fprintf(stderr, " 'command_line_args' : [");
3720 for (int i = 0; i != num_command_line_args; ++i) {
3721 if (i)
3722 fprintf(stderr, ", ");
3723 fprintf(stderr, "'%s'", command_line_args[i]);
3724 }
3725 fprintf(stderr, "],\n");
3726 fprintf(stderr, " 'unsaved_files' : [");
3727 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3728 if (i)
3729 fprintf(stderr, ", ");
3730 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3731 unsaved_files[i].Length);
3732 }
3733 fprintf(stderr, "],\n");
3734 fprintf(stderr, " 'options' : %d,\n", options);
3735 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003736
3737 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003739 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003740 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 }
Alp Toker5c532982014-07-07 22:42:03 +00003742
3743 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003744}
3745
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003746CXString clang_Type_getObjCEncoding(CXType CT) {
3747 CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
3748 ASTContext &Ctx = getASTUnit(tu)->getASTContext();
3749 std::string encoding;
Michael Kruse7520cf02020-03-25 09:26:14 -05003750 Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003751
3752 return cxstring::createDup(encoding);
3753}
3754
3755static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
3756 if (C.kind == CXCursor_MacroDefinition) {
3757 if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
3758 return MDR->getName();
3759 } else if (C.kind == CXCursor_MacroExpansion) {
3760 MacroExpansionCursor ME = getCursorMacroExpansion(C);
3761 return ME.getName();
3762 }
3763 return nullptr;
3764}
3765
3766unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
3767 const IdentifierInfo *II = getMacroIdentifier(C);
3768 if (!II) {
3769 return false;
3770 }
3771 ASTUnit *ASTU = getCursorASTUnit(C);
3772 Preprocessor &PP = ASTU->getPreprocessor();
3773 if (const MacroInfo *MI = PP.getMacroInfo(II))
3774 return MI->isFunctionLike();
3775 return false;
3776}
3777
3778unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
3779 const IdentifierInfo *II = getMacroIdentifier(C);
3780 if (!II) {
3781 return false;
3782 }
3783 ASTUnit *ASTU = getCursorASTUnit(C);
3784 Preprocessor &PP = ASTU->getPreprocessor();
3785 if (const MacroInfo *MI = PP.getMacroInfo(II))
3786 return MI->isBuiltinMacro();
3787 return false;
3788}
3789
3790unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
3791 const Decl *D = getCursorDecl(C);
3792 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
3793 if (!FD) {
3794 return false;
3795 }
3796 return FD->isInlined();
3797}
3798
Michael Kruse7520cf02020-03-25 09:26:14 -05003799static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003800 if (callExpr->getNumArgs() != 1) {
3801 return nullptr;
3802 }
3803
3804 StringLiteral *S = nullptr;
3805 auto *arg = callExpr->getArg(0);
3806 if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
3807 ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
3808 auto *subExpr = I->getSubExprAsWritten();
3809
Michael Kruse7520cf02020-03-25 09:26:14 -05003810 if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003811 return nullptr;
3812 }
3813
3814 S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
3815 } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
3816 S = static_cast<StringLiteral *>(callExpr->getArg(0));
3817 } else {
3818 return nullptr;
3819 }
3820 return S;
3821}
3822
David Blaikie59272572016-04-13 18:23:33 +00003823struct ExprEvalResult {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003824 CXEvalResultKind EvalType;
3825 union {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003826 unsigned long long unsignedVal;
3827 long long intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003828 double floatVal;
3829 char *stringVal;
3830 } EvalData;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003831 bool IsUnsignedInt;
David Blaikie59272572016-04-13 18:23:33 +00003832 ~ExprEvalResult() {
3833 if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
3834 EvalType != CXEval_Int) {
Alex Lorenza19cb2e2019-01-08 23:28:37 +00003835 delete[] EvalData.stringVal;
David Blaikie59272572016-04-13 18:23:33 +00003836 }
3837 }
3838};
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003839
3840void clang_EvalResult_dispose(CXEvalResult E) {
David Blaikie59272572016-04-13 18:23:33 +00003841 delete static_cast<ExprEvalResult *>(E);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003842}
3843
3844CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
3845 if (!E) {
3846 return CXEval_UnExposed;
3847 }
3848 return ((ExprEvalResult *)E)->EvalType;
3849}
3850
3851int clang_EvalResult_getAsInt(CXEvalResult E) {
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003852 return clang_EvalResult_getAsLongLong(E);
3853}
3854
3855long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003856 if (!E) {
3857 return 0;
3858 }
Michael Kruse7520cf02020-03-25 09:26:14 -05003859 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003860 if (Result->IsUnsignedInt)
3861 return Result->EvalData.unsignedVal;
3862 return Result->EvalData.intVal;
3863}
3864
3865unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
3866 return ((ExprEvalResult *)E)->IsUnsignedInt;
3867}
3868
3869unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
3870 if (!E) {
3871 return 0;
3872 }
3873
Michael Kruse7520cf02020-03-25 09:26:14 -05003874 ExprEvalResult *Result = (ExprEvalResult *)E;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003875 if (Result->IsUnsignedInt)
3876 return Result->EvalData.unsignedVal;
3877 return Result->EvalData.intVal;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003878}
3879
3880double clang_EvalResult_getAsDouble(CXEvalResult E) {
3881 if (!E) {
3882 return 0;
3883 }
3884 return ((ExprEvalResult *)E)->EvalData.floatVal;
3885}
3886
Michael Kruse7520cf02020-03-25 09:26:14 -05003887const char *clang_EvalResult_getAsStr(CXEvalResult E) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003888 if (!E) {
3889 return nullptr;
3890 }
3891 return ((ExprEvalResult *)E)->EvalData.stringVal;
3892}
3893
Michael Kruse7520cf02020-03-25 09:26:14 -05003894static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003895 Expr::EvalResult ER;
3896 ASTContext &ctx = getCursorContext(C);
David Blaikiebbc00882016-04-13 18:36:19 +00003897 if (!expr)
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003898 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003899
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003900 expr = expr->IgnoreParens();
Emilio Cobos Alvarez74375452019-07-09 14:27:01 +00003901 if (expr->isValueDependent())
3902 return nullptr;
David Blaikiebbc00882016-04-13 18:36:19 +00003903 if (!expr->EvaluateAsRValue(ER, ctx))
3904 return nullptr;
3905
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003906 QualType rettype;
3907 CallExpr *callExpr;
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +00003908 auto result = std::make_unique<ExprEvalResult>();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003909 result->EvalType = CXEval_UnExposed;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003910 result->IsUnsignedInt = false;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003911
David Blaikiebbc00882016-04-13 18:36:19 +00003912 if (ER.Val.isInt()) {
3913 result->EvalType = CXEval_Int;
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003914
Michael Kruse7520cf02020-03-25 09:26:14 -05003915 auto &val = ER.Val.getInt();
Argyrios Kyrtzidis5dda1122016-12-01 23:41:27 +00003916 if (val.isUnsigned()) {
3917 result->IsUnsignedInt = true;
3918 result->EvalData.unsignedVal = val.getZExtValue();
3919 } else {
3920 result->EvalData.intVal = val.getExtValue();
3921 }
3922
David Blaikiebbc00882016-04-13 18:36:19 +00003923 return result.release();
3924 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003925
David Blaikiebbc00882016-04-13 18:36:19 +00003926 if (ER.Val.isFloat()) {
3927 llvm::SmallVector<char, 100> Buffer;
3928 ER.Val.getFloat().toString(Buffer);
3929 std::string floatStr(Buffer.data(), Buffer.size());
3930 result->EvalType = CXEval_Float;
3931 bool ignored;
3932 llvm::APFloat apFloat = ER.Val.getFloat();
Stephan Bergmann17c7f702016-12-14 11:57:17 +00003933 apFloat.convert(llvm::APFloat::IEEEdouble(),
David Blaikiebbc00882016-04-13 18:36:19 +00003934 llvm::APFloat::rmNearestTiesToEven, &ignored);
3935 result->EvalData.floatVal = apFloat.convertToDouble();
3936 return result.release();
3937 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003938
David Blaikiebbc00882016-04-13 18:36:19 +00003939 if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
3940 const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
3941 auto *subExpr = I->getSubExprAsWritten();
3942 if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
3943 subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003944 const StringLiteral *StrE = nullptr;
3945 const ObjCStringLiteral *ObjCExpr;
David Blaikiebbc00882016-04-13 18:36:19 +00003946 ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003947
3948 if (ObjCExpr) {
3949 StrE = ObjCExpr->getString();
3950 result->EvalType = CXEval_ObjCStrLiteral;
3951 } else {
David Blaikiebbc00882016-04-13 18:36:19 +00003952 StrE = cast<StringLiteral>(I->getSubExprAsWritten());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003953 result->EvalType = CXEval_StrLiteral;
3954 }
3955
3956 std::string strRef(StrE->getString().str());
David Blaikie59272572016-04-13 18:23:33 +00003957 result->EvalData.stringVal = new char[strRef.size() + 1];
David Blaikiebbc00882016-04-13 18:36:19 +00003958 strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
3959 strRef.size());
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003960 result->EvalData.stringVal[strRef.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00003961 return result.release();
David Blaikiebbc00882016-04-13 18:36:19 +00003962 }
3963 } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
3964 expr->getStmtClass() == Stmt::StringLiteralClass) {
3965 const StringLiteral *StrE = nullptr;
3966 const ObjCStringLiteral *ObjCExpr;
3967 ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003968
David Blaikiebbc00882016-04-13 18:36:19 +00003969 if (ObjCExpr) {
3970 StrE = ObjCExpr->getString();
3971 result->EvalType = CXEval_ObjCStrLiteral;
3972 } else {
3973 StrE = cast<StringLiteral>(expr);
3974 result->EvalType = CXEval_StrLiteral;
3975 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003976
David Blaikiebbc00882016-04-13 18:36:19 +00003977 std::string strRef(StrE->getString().str());
3978 result->EvalData.stringVal = new char[strRef.size() + 1];
3979 strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
3980 result->EvalData.stringVal[strRef.size()] = '\0';
3981 return result.release();
3982 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003983
David Blaikiebbc00882016-04-13 18:36:19 +00003984 if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
3985 CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003986
David Blaikiebbc00882016-04-13 18:36:19 +00003987 rettype = CC->getType();
3988 if (rettype.getAsString() == "CFStringRef" &&
3989 CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003990
David Blaikiebbc00882016-04-13 18:36:19 +00003991 callExpr = static_cast<CallExpr *>(CC->getSubExpr());
3992 StringLiteral *S = getCFSTR_value(callExpr);
3993 if (S) {
3994 std::string strLiteral(S->getString().str());
3995 result->EvalType = CXEval_CFStr;
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00003996
David Blaikiebbc00882016-04-13 18:36:19 +00003997 result->EvalData.stringVal = new char[strLiteral.size() + 1];
3998 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
3999 strLiteral.size());
4000 result->EvalData.stringVal[strLiteral.size()] = '\0';
David Blaikie59272572016-04-13 18:23:33 +00004001 return result.release();
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004002 }
4003 }
4004
David Blaikiebbc00882016-04-13 18:36:19 +00004005 } else if (expr->getStmtClass() == Stmt::CallExprClass) {
4006 callExpr = static_cast<CallExpr *>(expr);
4007 rettype = callExpr->getCallReturnType(ctx);
4008
4009 if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
4010 return nullptr;
4011
4012 if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
4013 if (callExpr->getNumArgs() == 1 &&
4014 !callExpr->getArg(0)->getType()->isIntegralType(ctx))
4015 return nullptr;
4016 } else if (rettype.getAsString() == "CFStringRef") {
4017
4018 StringLiteral *S = getCFSTR_value(callExpr);
4019 if (S) {
4020 std::string strLiteral(S->getString().str());
4021 result->EvalType = CXEval_CFStr;
4022 result->EvalData.stringVal = new char[strLiteral.size() + 1];
4023 strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
4024 strLiteral.size());
4025 result->EvalData.stringVal[strLiteral.size()] = '\0';
4026 return result.release();
4027 }
4028 }
4029 } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
4030 DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
4031 ValueDecl *V = D->getDecl();
4032 if (V->getKind() == Decl::Function) {
4033 std::string strName = V->getNameAsString();
4034 result->EvalType = CXEval_Other;
4035 result->EvalData.stringVal = new char[strName.size() + 1];
4036 strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
4037 result->EvalData.stringVal[strName.size()] = '\0';
4038 return result.release();
4039 }
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004040 }
4041
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004042 return nullptr;
4043}
4044
Alex Lorenz65317e12019-01-08 22:32:51 +00004045static const Expr *evaluateDeclExpr(const Decl *D) {
4046 if (!D)
Evgeniy Stepanov9b871492018-07-10 19:48:53 +00004047 return nullptr;
Alex Lorenz65317e12019-01-08 22:32:51 +00004048 if (auto *Var = dyn_cast<VarDecl>(D))
4049 return Var->getInit();
4050 else if (auto *Field = dyn_cast<FieldDecl>(D))
4051 return Field->getInClassInitializer();
4052 return nullptr;
4053}
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004054
Alex Lorenz65317e12019-01-08 22:32:51 +00004055static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
4056 assert(CS && "invalid compound statement");
4057 for (auto *bodyIterator : CS->body()) {
4058 if (const auto *E = dyn_cast<Expr>(bodyIterator))
4059 return E;
Evgeniy Stepanov6df47ce2018-07-10 19:49:07 +00004060 }
Alex Lorenzc4cf96e2018-07-09 19:56:45 +00004061 return nullptr;
4062}
4063
Alex Lorenz65317e12019-01-08 22:32:51 +00004064CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
Christian Kandeler72131422020-06-24 11:56:45 +01004065 const Expr *E = nullptr;
4066 if (clang_getCursorKind(C) == CXCursor_CompoundStmt)
4067 E = evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)));
4068 else if (clang_isDeclaration(C.kind))
4069 E = evaluateDeclExpr(getCursorDecl(C));
4070 else if (clang_isExpression(C.kind))
4071 E = getCursorExpr(C);
4072 if (E)
Alex Lorenz65317e12019-01-08 22:32:51 +00004073 return const_cast<CXEvalResult>(
4074 reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
4075 return nullptr;
4076}
4077
Argyrios Kyrtzidis785705b2016-01-16 00:20:02 +00004078unsigned clang_Cursor_hasAttrs(CXCursor C) {
4079 const Decl *D = getCursorDecl(C);
4080 if (!D) {
4081 return 0;
4082 }
4083
4084 if (D->hasAttrs()) {
4085 return 1;
4086 }
4087
4088 return 0;
4089}
Guy Benyei11169dd2012-12-18 14:30:41 +00004090unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
4091 return CXSaveTranslationUnit_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05004092}
Guy Benyei11169dd2012-12-18 14:30:41 +00004093
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004094static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
4095 const char *FileName,
4096 unsigned options) {
4097 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
4099 setThreadBackgroundPriority();
4100
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004101 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
4102 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00004103}
4104
4105int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
4106 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004107 LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004108
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004109 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004110 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004112 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004113
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004114 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4116 if (!CXXUnit->hasSema())
4117 return CXSaveError_InvalidTU;
4118
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004119 CXSaveError result;
4120 auto SaveTranslationUnitImpl = [=, &result]() {
4121 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
4122 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004123
Erik Verbruggen3cc39112017-11-14 09:34:39 +00004124 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004125 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00004126
4127 if (getenv("LIBCLANG_RESOURCE_USAGE"))
4128 PrintLibclangResourceUsage(TU);
4129
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004130 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 }
4132
4133 // We have an AST that has invalid nodes due to compiler errors.
4134 // Use a crash recovery thread for protection.
4135
4136 llvm::CrashRecoveryContext CRC;
4137
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004138 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
4140 fprintf(stderr, " 'filename' : '%s'\n", FileName);
4141 fprintf(stderr, " 'options' : %d,\n", options);
4142 fprintf(stderr, "}\n");
4143
4144 return CXSaveError_Unknown;
4145
4146 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
4147 PrintLibclangResourceUsage(TU);
4148 }
4149
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004150 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004151}
4152
4153void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
4154 if (CTUnit) {
4155 // If the translation unit has been marked as unsafe to free, just discard
4156 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004157 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4158 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 return;
4160
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004161 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00004162 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
4164 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00004165 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 delete CTUnit;
4167 }
4168}
4169
Erik Verbruggen346066b2017-05-30 14:25:54 +00004170unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
4171 if (CTUnit) {
4172 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
4173
4174 if (Unit && Unit->isUnsafeToFree())
4175 return false;
4176
4177 Unit->ResetForParse();
4178 return true;
4179 }
4180
4181 return false;
4182}
4183
Guy Benyei11169dd2012-12-18 14:30:41 +00004184unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
4185 return CXReparse_None;
4186}
4187
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004188static CXErrorCode
4189clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
4190 ArrayRef<CXUnsavedFile> unsaved_files,
4191 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004192 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004193 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004194 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004195 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004196 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004197
4198 // Reset the associated diagnostics.
Michael Kruse7520cf02020-03-25 09:26:14 -05004199 delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00004200 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004201
Dmitri Gribenko183436e2013-01-26 21:49:50 +00004202 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
4204 setThreadBackgroundPriority();
4205
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004206 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00004208
4209 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
4210 new std::vector<ASTUnit::RemappedFile>());
4211
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 // Recover resources if we crash before exiting this function.
Michael Kruse7520cf02020-03-25 09:26:14 -05004213 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
4214 RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00004215
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004216 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004217 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00004218 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00004219 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004221
Adrian Prantlbb165fb2015-06-20 18:53:08 +00004222 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
4223 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004224 return CXError_Success;
4225 if (isASTReadError(CXXUnit))
4226 return CXError_ASTReadError;
4227 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00004228}
4229
4230int clang_reparseTranslationUnit(CXTranslationUnit TU,
4231 unsigned num_unsaved_files,
4232 struct CXUnsavedFile *unsaved_files,
4233 unsigned options) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004234 LOG_FUNC_SECTION { *Log << TU; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004235
Alp Toker9d85b182014-07-07 01:23:14 +00004236 if (num_unsaved_files && !unsaved_files)
4237 return CXError_InvalidArguments;
4238
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004239 CXErrorCode result;
4240 auto ReparseTranslationUnitImpl = [=, &result]() {
4241 result = clang_reparseTranslationUnit_Impl(
4242 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
4243 };
Guy Benyei11169dd2012-12-18 14:30:41 +00004244
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 llvm::CrashRecoveryContext CRC;
4246
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00004247 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004249 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00004250 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
4252 PrintLibclangResourceUsage(TU);
4253
Alp Toker5c532982014-07-07 22:42:03 +00004254 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00004255}
4256
Guy Benyei11169dd2012-12-18 14:30:41 +00004257CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004258 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004259 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004260 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004261 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004262
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004263 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004264 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004265}
4266
4267CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004268 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004269 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004270 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004271 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00004272
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004273 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004274 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
4275}
4276
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004277CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
4278 if (isNotUsableTU(CTUnit)) {
4279 LOG_BAD_TU(CTUnit);
4280 return nullptr;
4281 }
4282
Michael Kruse7520cf02020-03-25 09:26:14 -05004283 CXTargetInfoImpl *impl = new CXTargetInfoImpl();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004284 impl->TranslationUnit = CTUnit;
4285 return impl;
4286}
4287
4288CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
4289 if (!TargetInfo)
4290 return cxstring::createEmpty();
4291
4292 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4293 assert(!isNotUsableTU(CTUnit) &&
4294 "Unexpected unusable translation unit in TargetInfo");
4295
4296 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4297 std::string Triple =
Michael Kruse7520cf02020-03-25 09:26:14 -05004298 CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
Emilio Cobos Alvarez485ad422017-04-28 15:56:39 +00004299 return cxstring::createDup(Triple);
4300}
4301
4302int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
4303 if (!TargetInfo)
4304 return -1;
4305
4306 CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
4307 assert(!isNotUsableTU(CTUnit) &&
4308 "Unexpected unusable translation unit in TargetInfo");
4309
4310 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
4311 return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
4312}
4313
4314void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
4315 if (!TargetInfo)
4316 return;
4317
4318 delete TargetInfo;
4319}
4320
Guy Benyei11169dd2012-12-18 14:30:41 +00004321//===----------------------------------------------------------------------===//
4322// CXFile Operations.
4323//===----------------------------------------------------------------------===//
4324
Guy Benyei11169dd2012-12-18 14:30:41 +00004325CXString clang_getFileName(CXFile SFile) {
4326 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00004327 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00004328
4329 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004330 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004331}
4332
4333time_t clang_getFileTime(CXFile SFile) {
4334 if (!SFile)
4335 return 0;
4336
4337 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4338 return FEnt->getModificationTime();
4339}
4340
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004341CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004342 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004343 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00004344 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004345 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004346
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004347 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004348
4349 FileManager &FMgr = CXXUnit->getFileManager();
Harlan Haskins8d323d12019-08-01 21:31:56 +00004350 auto File = FMgr.getFile(file_name);
4351 if (!File)
4352 return nullptr;
4353 return const_cast<FileEntry *>(*File);
Guy Benyei11169dd2012-12-18 14:30:41 +00004354}
4355
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004356const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
4357 size_t *size) {
4358 if (isNotUsableTU(TU)) {
4359 LOG_BAD_TU(TU);
4360 return nullptr;
4361 }
4362
4363 const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
4364 FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
4365 bool Invalid = true;
Nico Weber04347d82019-04-04 21:06:41 +00004366 const llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid);
Erik Verbruggen3afa3ce2017-12-06 09:02:52 +00004367 if (Invalid) {
4368 if (size)
4369 *size = 0;
4370 return nullptr;
4371 }
4372 if (size)
4373 *size = buf->getBufferSize();
4374 return buf->getBufferStart();
4375}
4376
Michael Kruse7520cf02020-03-25 09:26:14 -05004377unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004378 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004379 LOG_BAD_TU(TU);
4380 return 0;
4381 }
4382
4383 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 return 0;
4385
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004386 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004387 FileEntry *FEnt = static_cast<FileEntry *>(file);
Michael Kruse7520cf02020-03-25 09:26:14 -05004388 return CXXUnit->getPreprocessor()
4389 .getHeaderSearchInfo()
4390 .isFileMultipleIncludeGuarded(FEnt);
Guy Benyei11169dd2012-12-18 14:30:41 +00004391}
4392
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004393int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
4394 if (!file || !outID)
4395 return 1;
4396
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004397 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00004398 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
4399 outID->data[0] = ID.getDevice();
4400 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004401 outID->data[2] = FEnt->getModificationTime();
4402 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00004403}
4404
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00004405int clang_File_isEqual(CXFile file1, CXFile file2) {
4406 if (file1 == file2)
4407 return true;
4408
4409 if (!file1 || !file2)
4410 return false;
4411
4412 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
4413 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
4414 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
4415}
4416
Fangrui Songe46ac5f2018-04-07 20:50:35 +00004417CXString clang_File_tryGetRealPathName(CXFile SFile) {
4418 if (!SFile)
4419 return cxstring::createNull();
4420
4421 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
4422 return cxstring::createRef(FEnt->tryGetRealPathName());
4423}
4424
Guy Benyei11169dd2012-12-18 14:30:41 +00004425//===----------------------------------------------------------------------===//
4426// CXCursor Operations.
4427//===----------------------------------------------------------------------===//
4428
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004429static const Decl *getDeclFromExpr(const Stmt *E) {
4430 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 return getDeclFromExpr(CE->getSubExpr());
4432
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004433 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004435 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004437 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004439 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 if (PRE->isExplicitProperty())
4441 return PRE->getExplicitProperty();
4442 // It could be messaging both getter and setter as in:
4443 // ++myobj.myprop;
4444 // in which case prefer to associate the setter since it is less obvious
4445 // from inspecting the source that the setter is going to get called.
4446 if (PRE->isMessagingSetter())
4447 return PRE->getImplicitPropertySetter();
4448 return PRE->getImplicitPropertyGetter();
4449 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004450 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004452 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 if (Expr *Src = OVE->getSourceExpr())
4454 return getDeclFromExpr(Src);
Michael Kruse7520cf02020-03-25 09:26:14 -05004455
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004456 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004458 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 if (!CE->isElidable())
Michael Kruse7520cf02020-03-25 09:26:14 -05004460 return CE->getConstructor();
Richard Smith5179eb72016-06-28 19:03:57 +00004461 if (const CXXInheritedCtorInitExpr *CE =
4462 dyn_cast<CXXInheritedCtorInitExpr>(E))
4463 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004464 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 return OME->getMethodDecl();
4466
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004467 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 return PE->getProtocol();
Michael Kruse7520cf02020-03-25 09:26:14 -05004469 if (const SubstNonTypeTemplateParmPackExpr *NTTP =
4470 dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004472 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004473 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 isa<ParmVarDecl>(SizeOfPack->getPack()))
4475 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00004476
4477 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00004478}
4479
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004480static SourceLocation getLocationFromExpr(const Expr *E) {
4481 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004482 return getLocationFromExpr(CE->getSubExpr());
4483
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004484 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Michael Kruse7520cf02020-03-25 09:26:14 -05004485 return /*FIXME:*/ Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004486 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004488 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004490 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004492 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004494 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 return PropRef->getLocation();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00004496
4497 return E->getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00004498}
4499
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00004500extern "C" {
4501
Michael Kruse7520cf02020-03-25 09:26:14 -05004502unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 CXClientData client_data) {
4504 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
4505 /*VisitPreprocessorLast=*/false);
4506 return CursorVis.VisitChildren(parent);
4507}
4508
4509#ifndef __has_feature
4510#define __has_feature(x) 0
4511#endif
4512#if __has_feature(blocks)
Michael Kruse7520cf02020-03-25 09:26:14 -05004513typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
4514 CXCursor parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00004515
4516static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004517 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004518 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4519 return block(cursor, parent);
4520}
4521#else
4522// If we are compiled with a compiler that doesn't have native blocks support,
Michael Kruse7520cf02020-03-25 09:26:14 -05004523// define and call the block manually, so the
4524typedef struct _CXChildVisitResult {
4525 void *isa;
4526 int flags;
4527 int reserved;
4528 enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
4529 CXCursor);
4530} * CXCursorVisitorBlock;
Guy Benyei11169dd2012-12-18 14:30:41 +00004531
4532static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
Michael Kruse7520cf02020-03-25 09:26:14 -05004533 CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
4535 return block->invoke(block, cursor, parent);
4536}
4537#endif
4538
Guy Benyei11169dd2012-12-18 14:30:41 +00004539unsigned clang_visitChildrenWithBlock(CXCursor parent,
4540 CXCursorVisitorBlock block) {
4541 return clang_visitChildren(parent, visitWithBlock, block);
4542}
4543
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004544static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004546 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004547
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004548 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004550 if (const ObjCPropertyImplDecl *PropImpl =
4551 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004553 return cxstring::createDup(Property->getIdentifier()->getName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004554
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004555 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004557 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004558
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004559 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004561
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004562 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004563 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004564
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004565 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00004566 // No, this isn't the same as the code below. getIdentifier() is non-virtual
4567 // and returns different names. NamedDecl returns the class name and
4568 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004569 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004570
4571 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004572 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05004573
Guy Benyei11169dd2012-12-18 14:30:41 +00004574 SmallString<1024> S;
4575 llvm::raw_svector_ostream os(S);
4576 ND->printName(os);
Michael Kruse7520cf02020-03-25 09:26:14 -05004577
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004578 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00004579}
4580
4581CXString clang_getCursorSpelling(CXCursor C) {
4582 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00004583 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004584
4585 if (clang_isReference(C.kind)) {
4586 switch (C.kind) {
4587 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004588 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004589 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 }
4591 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004592 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004593 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004594 }
4595 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004596 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004597 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004598 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004599 }
4600 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004601 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004602 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004603 }
4604 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004605 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004606 assert(Type && "Missing type decl");
4607
Michael Kruse7520cf02020-03-25 09:26:14 -05004608 return cxstring::createDup(
4609 getCursorContext(C).getTypeDeclType(Type).getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004610 }
4611 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004612 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 assert(Template && "Missing template decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004614
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004615 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004617
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004619 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 assert(NS && "Missing namespace decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004621
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004622 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 }
4624
4625 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004626 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 assert(Field && "Missing member decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004628
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004629 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 }
4631
4632 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004633 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 assert(Label && "Missing label");
Michael Kruse7520cf02020-03-25 09:26:14 -05004635
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004636 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 }
4638
4639 case CXCursor_OverloadedDeclRef: {
4640 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004641 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
4642 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004643 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004644 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004646 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004647 return cxstring::createDup(E->getName().getAsString());
Michael Kruse7520cf02020-03-25 09:26:14 -05004648 OverloadedTemplateStorage *Ovl =
4649 Storage.get<OverloadedTemplateStorage *>();
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004651 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004652 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004654
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004656 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 assert(Var && "Missing variable decl");
Michael Kruse7520cf02020-03-25 09:26:14 -05004658
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004659 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00004660 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004661
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004663 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 }
4665 }
4666
4667 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00004668 const Expr *E = getCursorExpr(C);
4669
4670 if (C.kind == CXCursor_ObjCStringLiteral ||
4671 C.kind == CXCursor_StringLiteral) {
4672 const StringLiteral *SLit;
4673 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
4674 SLit = OSL->getString();
4675 } else {
4676 SLit = cast<StringLiteral>(E);
4677 }
4678 SmallString<256> Buf;
4679 llvm::raw_svector_ostream OS(Buf);
4680 SLit->outputString(OS);
4681 return cxstring::createDup(OS.str());
4682 }
4683
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004684 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 if (D)
4686 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004687 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004688 }
4689
4690 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004691 const Stmt *S = getCursorStmt(C);
4692 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004693 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00004694
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004695 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004696 }
Michael Kruse7520cf02020-03-25 09:26:14 -05004697
Guy Benyei11169dd2012-12-18 14:30:41 +00004698 if (C.kind == CXCursor_MacroExpansion)
Michael Kruse7520cf02020-03-25 09:26:14 -05004699 return cxstring::createRef(
4700 getCursorMacroExpansion(C).getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004701
4702 if (C.kind == CXCursor_MacroDefinition)
Michael Kruse7520cf02020-03-25 09:26:14 -05004703 return cxstring::createRef(
4704 getCursorMacroDefinition(C)->getName()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00004705
4706 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004707 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Michael Kruse7520cf02020-03-25 09:26:14 -05004708
Guy Benyei11169dd2012-12-18 14:30:41 +00004709 if (clang_isDeclaration(C.kind))
4710 return getDeclSpelling(getCursorDecl(C));
4711
4712 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004713 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004714 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00004715 }
4716
4717 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00004718 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004719 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 }
4721
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004722 if (C.kind == CXCursor_PackedAttr) {
4723 return cxstring::createRef("packed");
4724 }
4725
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004726 if (C.kind == CXCursor_VisibilityAttr) {
4727 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
4728 switch (AA->getVisibility()) {
4729 case VisibilityAttr::VisibilityType::Default:
4730 return cxstring::createRef("default");
4731 case VisibilityAttr::VisibilityType::Hidden:
4732 return cxstring::createRef("hidden");
4733 case VisibilityAttr::VisibilityType::Protected:
4734 return cxstring::createRef("protected");
4735 }
4736 llvm_unreachable("unknown visibility type");
4737 }
4738
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004739 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004740}
4741
Michael Kruse7520cf02020-03-25 09:26:14 -05004742CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 unsigned options) {
4744 if (clang_Cursor_isNull(C))
4745 return clang_getNullRange();
4746
4747 ASTContext &Ctx = getCursorContext(C);
4748
4749 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004750 const Stmt *S = getCursorStmt(C);
4751 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 if (pieceIndex > 0)
4753 return clang_getNullRange();
4754 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
4755 }
4756
4757 return clang_getNullRange();
4758 }
4759
4760 if (C.kind == CXCursor_ObjCMessageExpr) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004761 if (const ObjCMessageExpr *ME =
4762 dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 if (pieceIndex >= ME->getNumSelectorLocs())
4764 return clang_getNullRange();
4765 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
4766 }
4767 }
4768
4769 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
4770 C.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05004771 if (const ObjCMethodDecl *MD =
4772 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 if (pieceIndex >= MD->getNumSelectorLocs())
4774 return clang_getNullRange();
4775 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
4776 }
4777 }
4778
4779 if (C.kind == CXCursor_ObjCCategoryDecl ||
4780 C.kind == CXCursor_ObjCCategoryImplDecl) {
4781 if (pieceIndex > 0)
4782 return clang_getNullRange();
Michael Kruse7520cf02020-03-25 09:26:14 -05004783 if (const ObjCCategoryDecl *CD =
4784 dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Michael Kruse7520cf02020-03-25 09:26:14 -05004786 if (const ObjCCategoryImplDecl *CID =
4787 dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004788 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
4789 }
4790
4791 if (C.kind == CXCursor_ModuleImportDecl) {
4792 if (pieceIndex > 0)
4793 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004794 if (const ImportDecl *ImportD =
4795 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004796 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
4797 if (!Locs.empty())
Michael Kruse7520cf02020-03-25 09:26:14 -05004798 return cxloc::translateSourceRange(
4799 Ctx, SourceRange(Locs.front(), Locs.back()));
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 }
4801 return clang_getNullRange();
4802 }
4803
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004804 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
Kevin Funk4be5d672016-12-20 09:56:56 +00004805 C.kind == CXCursor_ConversionFunction ||
4806 C.kind == CXCursor_FunctionDecl) {
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00004807 if (pieceIndex > 0)
4808 return clang_getNullRange();
4809 if (const FunctionDecl *FD =
4810 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
4811 DeclarationNameInfo FunctionName = FD->getNameInfo();
4812 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
4813 }
4814 return clang_getNullRange();
4815 }
4816
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 // FIXME: A CXCursor_InclusionDirective should give the location of the
4818 // filename, but we don't keep track of this.
4819
4820 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
4821 // but we don't keep track of this.
4822
4823 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
4824 // but we don't keep track of this.
4825
4826 // Default handling, give the location of the cursor.
4827
4828 if (pieceIndex > 0)
4829 return clang_getNullRange();
4830
4831 CXSourceLocation CXLoc = clang_getCursorLocation(C);
4832 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
4833 return cxloc::translateSourceRange(Ctx, Loc);
4834}
4835
Eli Bendersky44a206f2014-07-31 18:04:56 +00004836CXString clang_Cursor_getMangling(CXCursor C) {
4837 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4838 return cxstring::createEmpty();
4839
Eli Bendersky44a206f2014-07-31 18:04:56 +00004840 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00004841 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00004842 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
4843 return cxstring::createEmpty();
4844
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004845 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004846 ASTNameGenerator ASTNameGen(Ctx);
4847 return cxstring::createDup(ASTNameGen.getName(D));
Eli Bendersky44a206f2014-07-31 18:04:56 +00004848}
4849
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004850CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
4851 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4852 return nullptr;
4853
4854 const Decl *D = getCursorDecl(C);
4855 if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
4856 return nullptr;
4857
Argyrios Kyrtzidisca741ce2016-02-14 22:30:14 +00004858 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004859 ASTNameGenerator ASTNameGen(Ctx);
4860 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Saleem Abdulrasool60034432015-11-12 03:57:22 +00004861 return cxstring::createSet(Manglings);
4862}
4863
Dave Lee1a532c92017-09-22 16:58:57 +00004864CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
4865 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
4866 return nullptr;
4867
4868 const Decl *D = getCursorDecl(C);
4869 if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
4870 return nullptr;
4871
4872 ASTContext &Ctx = D->getASTContext();
Jan Korous7e36ecd2019-09-05 20:33:52 +00004873 ASTNameGenerator ASTNameGen(Ctx);
4874 std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
Dave Lee1a532c92017-09-22 16:58:57 +00004875 return cxstring::createSet(Manglings);
4876}
4877
Jonathan Coe45ef5032018-01-16 10:19:56 +00004878CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
4879 if (clang_Cursor_isNull(C))
4880 return 0;
4881 return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
4882}
4883
4884void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
4885 if (Policy)
4886 delete static_cast<PrintingPolicy *>(Policy);
4887}
4888
4889unsigned
4890clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
4891 enum CXPrintingPolicyProperty Property) {
4892 if (!Policy)
4893 return 0;
4894
4895 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4896 switch (Property) {
4897 case CXPrintingPolicy_Indentation:
4898 return P->Indentation;
4899 case CXPrintingPolicy_SuppressSpecifiers:
4900 return P->SuppressSpecifiers;
4901 case CXPrintingPolicy_SuppressTagKeyword:
4902 return P->SuppressTagKeyword;
4903 case CXPrintingPolicy_IncludeTagDefinition:
4904 return P->IncludeTagDefinition;
4905 case CXPrintingPolicy_SuppressScope:
4906 return P->SuppressScope;
4907 case CXPrintingPolicy_SuppressUnwrittenScope:
4908 return P->SuppressUnwrittenScope;
4909 case CXPrintingPolicy_SuppressInitializers:
4910 return P->SuppressInitializers;
4911 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4912 return P->ConstantArraySizeAsWritten;
4913 case CXPrintingPolicy_AnonymousTagLocations:
4914 return P->AnonymousTagLocations;
4915 case CXPrintingPolicy_SuppressStrongLifetime:
4916 return P->SuppressStrongLifetime;
4917 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4918 return P->SuppressLifetimeQualifiers;
4919 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4920 return P->SuppressTemplateArgsInCXXConstructors;
4921 case CXPrintingPolicy_Bool:
4922 return P->Bool;
4923 case CXPrintingPolicy_Restrict:
4924 return P->Restrict;
4925 case CXPrintingPolicy_Alignof:
4926 return P->Alignof;
4927 case CXPrintingPolicy_UnderscoreAlignof:
4928 return P->UnderscoreAlignof;
4929 case CXPrintingPolicy_UseVoidForZeroParams:
4930 return P->UseVoidForZeroParams;
4931 case CXPrintingPolicy_TerseOutput:
4932 return P->TerseOutput;
4933 case CXPrintingPolicy_PolishForDeclaration:
4934 return P->PolishForDeclaration;
4935 case CXPrintingPolicy_Half:
4936 return P->Half;
4937 case CXPrintingPolicy_MSWChar:
4938 return P->MSWChar;
4939 case CXPrintingPolicy_IncludeNewlines:
4940 return P->IncludeNewlines;
4941 case CXPrintingPolicy_MSVCFormatting:
4942 return P->MSVCFormatting;
4943 case CXPrintingPolicy_ConstantsAsWritten:
4944 return P->ConstantsAsWritten;
4945 case CXPrintingPolicy_SuppressImplicitBase:
4946 return P->SuppressImplicitBase;
4947 case CXPrintingPolicy_FullyQualifiedName:
4948 return P->FullyQualifiedName;
4949 }
4950
4951 assert(false && "Invalid CXPrintingPolicyProperty");
4952 return 0;
4953}
4954
4955void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
4956 enum CXPrintingPolicyProperty Property,
4957 unsigned Value) {
4958 if (!Policy)
4959 return;
4960
4961 PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
4962 switch (Property) {
4963 case CXPrintingPolicy_Indentation:
4964 P->Indentation = Value;
4965 return;
4966 case CXPrintingPolicy_SuppressSpecifiers:
4967 P->SuppressSpecifiers = Value;
4968 return;
4969 case CXPrintingPolicy_SuppressTagKeyword:
4970 P->SuppressTagKeyword = Value;
4971 return;
4972 case CXPrintingPolicy_IncludeTagDefinition:
4973 P->IncludeTagDefinition = Value;
4974 return;
4975 case CXPrintingPolicy_SuppressScope:
4976 P->SuppressScope = Value;
4977 return;
4978 case CXPrintingPolicy_SuppressUnwrittenScope:
4979 P->SuppressUnwrittenScope = Value;
4980 return;
4981 case CXPrintingPolicy_SuppressInitializers:
4982 P->SuppressInitializers = Value;
4983 return;
4984 case CXPrintingPolicy_ConstantArraySizeAsWritten:
4985 P->ConstantArraySizeAsWritten = Value;
4986 return;
4987 case CXPrintingPolicy_AnonymousTagLocations:
4988 P->AnonymousTagLocations = Value;
4989 return;
4990 case CXPrintingPolicy_SuppressStrongLifetime:
4991 P->SuppressStrongLifetime = Value;
4992 return;
4993 case CXPrintingPolicy_SuppressLifetimeQualifiers:
4994 P->SuppressLifetimeQualifiers = Value;
4995 return;
4996 case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
4997 P->SuppressTemplateArgsInCXXConstructors = Value;
4998 return;
4999 case CXPrintingPolicy_Bool:
5000 P->Bool = Value;
5001 return;
5002 case CXPrintingPolicy_Restrict:
5003 P->Restrict = Value;
5004 return;
5005 case CXPrintingPolicy_Alignof:
5006 P->Alignof = Value;
5007 return;
5008 case CXPrintingPolicy_UnderscoreAlignof:
5009 P->UnderscoreAlignof = Value;
5010 return;
5011 case CXPrintingPolicy_UseVoidForZeroParams:
5012 P->UseVoidForZeroParams = Value;
5013 return;
5014 case CXPrintingPolicy_TerseOutput:
5015 P->TerseOutput = Value;
5016 return;
5017 case CXPrintingPolicy_PolishForDeclaration:
5018 P->PolishForDeclaration = Value;
5019 return;
5020 case CXPrintingPolicy_Half:
5021 P->Half = Value;
5022 return;
5023 case CXPrintingPolicy_MSWChar:
5024 P->MSWChar = Value;
5025 return;
5026 case CXPrintingPolicy_IncludeNewlines:
5027 P->IncludeNewlines = Value;
5028 return;
5029 case CXPrintingPolicy_MSVCFormatting:
5030 P->MSVCFormatting = Value;
5031 return;
5032 case CXPrintingPolicy_ConstantsAsWritten:
5033 P->ConstantsAsWritten = Value;
5034 return;
5035 case CXPrintingPolicy_SuppressImplicitBase:
5036 P->SuppressImplicitBase = Value;
5037 return;
5038 case CXPrintingPolicy_FullyQualifiedName:
5039 P->FullyQualifiedName = Value;
5040 return;
5041 }
5042
5043 assert(false && "Invalid CXPrintingPolicyProperty");
5044}
5045
5046CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
5047 if (clang_Cursor_isNull(C))
5048 return cxstring::createEmpty();
5049
5050 if (clang_isDeclaration(C.kind)) {
5051 const Decl *D = getCursorDecl(C);
5052 if (!D)
5053 return cxstring::createEmpty();
5054
5055 SmallString<128> Str;
5056 llvm::raw_svector_ostream OS(Str);
5057 PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
5058 D->print(OS, UserPolicy ? *UserPolicy
5059 : getCursorContext(C).getPrintingPolicy());
5060
5061 return cxstring::createDup(OS.str());
5062 }
5063
5064 return cxstring::createEmpty();
5065}
5066
Guy Benyei11169dd2012-12-18 14:30:41 +00005067CXString clang_getCursorDisplayName(CXCursor C) {
5068 if (!clang_isDeclaration(C.kind))
5069 return clang_getCursorSpelling(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05005070
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005071 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005072 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005073 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005074
5075 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005076 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005077 D = FunTmpl->getTemplatedDecl();
Michael Kruse7520cf02020-03-25 09:26:14 -05005078
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005079 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005080 SmallString<64> Str;
5081 llvm::raw_svector_ostream OS(Str);
5082 OS << *Function;
5083 if (Function->getPrimaryTemplate())
5084 OS << "<>";
5085 OS << "(";
5086 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
5087 if (I)
5088 OS << ", ";
5089 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
5090 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005091
Guy Benyei11169dd2012-12-18 14:30:41 +00005092 if (Function->isVariadic()) {
5093 if (Function->getNumParams())
5094 OS << ", ";
5095 OS << "...";
5096 }
5097 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005098 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005100
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005101 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005102 SmallString<64> Str;
5103 llvm::raw_svector_ostream OS(Str);
5104 OS << *ClassTemplate;
5105 OS << "<";
5106 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
5107 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
5108 if (I)
5109 OS << ", ";
Michael Kruse7520cf02020-03-25 09:26:14 -05005110
Guy Benyei11169dd2012-12-18 14:30:41 +00005111 NamedDecl *Param = Params->getParam(I);
5112 if (Param->getIdentifier()) {
5113 OS << Param->getIdentifier()->getName();
5114 continue;
5115 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005116
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 // There is no parameter name, which makes this tricky. Try to come up
5118 // with something useful that isn't too long.
5119 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
Saar Razff1e0fc2020-01-15 02:48:42 +02005120 if (const auto *TC = TTP->getTypeConstraint()) {
5121 TC->getConceptNameInfo().printName(OS, Policy);
5122 if (TC->hasExplicitTemplateArgs())
5123 OS << "<...>";
5124 } else
Michael Kruse7520cf02020-03-25 09:26:14 -05005125 OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
5126 else if (NonTypeTemplateParmDecl *NTTP =
5127 dyn_cast<NonTypeTemplateParmDecl>(Param))
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 OS << NTTP->getType().getAsString(Policy);
5129 else
5130 OS << "template<...> class";
5131 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005132
Guy Benyei11169dd2012-12-18 14:30:41 +00005133 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005134 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005135 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005136
5137 if (const ClassTemplateSpecializationDecl *ClassSpec =
5138 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005139 // If the type was explicitly written, use that.
5140 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005141 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Serge Pavlov03e672c2017-11-28 16:14:14 +00005142
Benjamin Kramer9170e912013-02-22 15:46:01 +00005143 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00005144 llvm::raw_svector_ostream OS(Str);
5145 OS << *ClassSpec;
Serge Pavlov03e672c2017-11-28 16:14:14 +00005146 printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
5147 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005148 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00005149 }
Michael Kruse7520cf02020-03-25 09:26:14 -05005150
Guy Benyei11169dd2012-12-18 14:30:41 +00005151 return clang_getCursorSpelling(C);
5152}
Michael Kruse7520cf02020-03-25 09:26:14 -05005153
Guy Benyei11169dd2012-12-18 14:30:41 +00005154CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
5155 switch (Kind) {
5156 case CXCursor_FunctionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005157 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 case CXCursor_TypedefDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005159 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005160 case CXCursor_EnumDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005161 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005162 case CXCursor_EnumConstantDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005163 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 case CXCursor_StructDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005165 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005166 case CXCursor_UnionDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005167 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005168 case CXCursor_ClassDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005169 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 case CXCursor_FieldDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005171 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 case CXCursor_VarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005173 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005174 case CXCursor_ParmDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005175 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 case CXCursor_ObjCInterfaceDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005177 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 case CXCursor_ObjCCategoryDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005179 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 case CXCursor_ObjCProtocolDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005181 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 case CXCursor_ObjCPropertyDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005183 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 case CXCursor_ObjCIvarDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005185 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 case CXCursor_ObjCInstanceMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005187 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 case CXCursor_ObjCClassMethodDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005189 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 case CXCursor_ObjCImplementationDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005191 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 case CXCursor_ObjCCategoryImplDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005193 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 case CXCursor_CXXMethod:
Michael Kruse7520cf02020-03-25 09:26:14 -05005195 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 case CXCursor_UnexposedDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005197 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005199 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 case CXCursor_ObjCProtocolRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005201 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 case CXCursor_ObjCClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005203 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 case CXCursor_TypeRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005205 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 case CXCursor_TemplateRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005207 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005209 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005211 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005213 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005215 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005217 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 case CXCursor_IntegerLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005219 return cxstring::createRef("IntegerLiteral");
Leonard Chandb01c3a2018-06-20 17:19:40 +00005220 case CXCursor_FixedPointLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005221 return cxstring::createRef("FixedPointLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 case CXCursor_FloatingLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005223 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 case CXCursor_ImaginaryLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005225 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 case CXCursor_StringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005227 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 case CXCursor_CharacterLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005229 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 case CXCursor_ParenExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005231 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 case CXCursor_UnaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005233 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 case CXCursor_ArraySubscriptExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005235 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00005236 case CXCursor_OMPArraySectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005237 return cxstring::createRef("OMPArraySectionExpr");
Alexey Bataev7ac9efb2020-02-05 09:33:05 -05005238 case CXCursor_OMPArrayShapingExpr:
5239 return cxstring::createRef("OMPArrayShapingExpr");
Alexey Bataev13a15042020-04-01 15:06:38 -04005240 case CXCursor_OMPIteratorExpr:
5241 return cxstring::createRef("OMPIteratorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005242 case CXCursor_BinaryOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005243 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 case CXCursor_CompoundAssignOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005245 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 case CXCursor_ConditionalOperator:
Michael Kruse7520cf02020-03-25 09:26:14 -05005247 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 case CXCursor_CStyleCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005249 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 case CXCursor_CompoundLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005251 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 case CXCursor_InitListExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005253 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 case CXCursor_AddrLabelExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005255 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 case CXCursor_StmtExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005257 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 case CXCursor_GenericSelectionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005259 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 case CXCursor_GNUNullExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005261 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 case CXCursor_CXXStaticCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005263 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 case CXCursor_CXXDynamicCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005265 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005266 case CXCursor_CXXReinterpretCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005267 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005268 case CXCursor_CXXConstCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005269 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 case CXCursor_CXXFunctionalCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005271 return cxstring::createRef("CXXFunctionalCastExpr");
Anastasia Stulovaa6a237f2020-05-18 11:02:01 +01005272 case CXCursor_CXXAddrspaceCastExpr:
5273 return cxstring::createRef("CXXAddrspaceCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 case CXCursor_CXXTypeidExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005275 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 case CXCursor_CXXBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005277 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 case CXCursor_CXXNullPtrLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005279 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 case CXCursor_CXXThisExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005281 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 case CXCursor_CXXThrowExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005283 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 case CXCursor_CXXNewExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005285 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 case CXCursor_CXXDeleteExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005287 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 case CXCursor_UnaryExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005289 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 case CXCursor_ObjCStringLiteral:
Michael Kruse7520cf02020-03-25 09:26:14 -05005291 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 case CXCursor_ObjCBoolLiteralExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005293 return cxstring::createRef("ObjCBoolLiteralExpr");
Erik Pilkington29099de2016-07-16 00:35:23 +00005294 case CXCursor_ObjCAvailabilityCheckExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005295 return cxstring::createRef("ObjCAvailabilityCheckExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00005296 case CXCursor_ObjCSelfExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005297 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005298 case CXCursor_ObjCEncodeExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005299 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005300 case CXCursor_ObjCSelectorExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005301 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005302 case CXCursor_ObjCProtocolExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005303 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005304 case CXCursor_ObjCBridgedCastExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005305 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 case CXCursor_BlockExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005307 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005308 case CXCursor_PackExpansionExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005309 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005310 case CXCursor_SizeOfPackExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005311 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005312 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005313 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005314 case CXCursor_UnexposedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005315 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005316 case CXCursor_DeclRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005317 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 case CXCursor_MemberRefExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005319 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005320 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005321 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 case CXCursor_ObjCMessageExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005323 return cxstring::createRef("ObjCMessageExpr");
Erik Pilkingtoneee944e2019-07-02 18:28:13 +00005324 case CXCursor_BuiltinBitCastExpr:
5325 return cxstring::createRef("BuiltinBitCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 case CXCursor_UnexposedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005327 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 case CXCursor_DeclStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005329 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 case CXCursor_LabelStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005331 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 case CXCursor_CompoundStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005333 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 case CXCursor_CaseStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005335 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 case CXCursor_DefaultStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005337 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 case CXCursor_IfStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005339 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 case CXCursor_SwitchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005341 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 case CXCursor_WhileStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005343 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 case CXCursor_DoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005345 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 case CXCursor_ForStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005347 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 case CXCursor_GotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005349 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 case CXCursor_IndirectGotoStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005351 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 case CXCursor_ContinueStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005353 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 case CXCursor_BreakStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005355 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 case CXCursor_ReturnStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005357 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 case CXCursor_GCCAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005359 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 case CXCursor_MSAsmStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005361 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 case CXCursor_ObjCAtTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005363 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 case CXCursor_ObjCAtCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005365 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 case CXCursor_ObjCAtFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005367 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005368 case CXCursor_ObjCAtThrowStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005369 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 case CXCursor_ObjCAtSynchronizedStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005371 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 case CXCursor_ObjCAutoreleasePoolStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005373 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 case CXCursor_ObjCForCollectionStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005375 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 case CXCursor_CXXCatchStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005377 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 case CXCursor_CXXTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005379 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005380 case CXCursor_CXXForRangeStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005381 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005382 case CXCursor_SEHTryStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005383 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005384 case CXCursor_SEHExceptStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005385 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005386 case CXCursor_SEHFinallyStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005387 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00005388 case CXCursor_SEHLeaveStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005389 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005390 case CXCursor_NullStmt:
Michael Kruse7520cf02020-03-25 09:26:14 -05005391 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00005392 case CXCursor_InvalidFile:
Michael Kruse7520cf02020-03-25 09:26:14 -05005393 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00005394 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005395 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00005396 case CXCursor_NoDeclFound:
Michael Kruse7520cf02020-03-25 09:26:14 -05005397 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00005398 case CXCursor_NotImplemented:
Michael Kruse7520cf02020-03-25 09:26:14 -05005399 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00005400 case CXCursor_TranslationUnit:
Michael Kruse7520cf02020-03-25 09:26:14 -05005401 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00005402 case CXCursor_UnexposedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005403 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00005404 case CXCursor_IBActionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005405 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005406 case CXCursor_IBOutletAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005407 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005408 case CXCursor_IBOutletCollectionAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005409 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005410 case CXCursor_CXXFinalAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005411 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005412 case CXCursor_CXXOverrideAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005413 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005414 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005415 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005416 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005417 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00005418 case CXCursor_PackedAttr:
5419 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00005420 case CXCursor_PureAttr:
5421 return cxstring::createRef("attribute(pure)");
5422 case CXCursor_ConstAttr:
5423 return cxstring::createRef("attribute(const)");
5424 case CXCursor_NoDuplicateAttr:
5425 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00005426 case CXCursor_CUDAConstantAttr:
5427 return cxstring::createRef("attribute(constant)");
5428 case CXCursor_CUDADeviceAttr:
5429 return cxstring::createRef("attribute(device)");
5430 case CXCursor_CUDAGlobalAttr:
5431 return cxstring::createRef("attribute(global)");
5432 case CXCursor_CUDAHostAttr:
5433 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00005434 case CXCursor_CUDASharedAttr:
5435 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00005436 case CXCursor_VisibilityAttr:
5437 return cxstring::createRef("attribute(visibility)");
Saleem Abdulrasool8aa0b802015-12-10 18:45:18 +00005438 case CXCursor_DLLExport:
5439 return cxstring::createRef("attribute(dllexport)");
5440 case CXCursor_DLLImport:
5441 return cxstring::createRef("attribute(dllimport)");
Michael Wud092d0b2018-08-03 05:03:22 +00005442 case CXCursor_NSReturnsRetained:
5443 return cxstring::createRef("attribute(ns_returns_retained)");
5444 case CXCursor_NSReturnsNotRetained:
5445 return cxstring::createRef("attribute(ns_returns_not_retained)");
5446 case CXCursor_NSReturnsAutoreleased:
5447 return cxstring::createRef("attribute(ns_returns_autoreleased)");
5448 case CXCursor_NSConsumesSelf:
5449 return cxstring::createRef("attribute(ns_consumes_self)");
5450 case CXCursor_NSConsumed:
5451 return cxstring::createRef("attribute(ns_consumed)");
5452 case CXCursor_ObjCException:
5453 return cxstring::createRef("attribute(objc_exception)");
5454 case CXCursor_ObjCNSObject:
5455 return cxstring::createRef("attribute(NSObject)");
5456 case CXCursor_ObjCIndependentClass:
5457 return cxstring::createRef("attribute(objc_independent_class)");
5458 case CXCursor_ObjCPreciseLifetime:
5459 return cxstring::createRef("attribute(objc_precise_lifetime)");
5460 case CXCursor_ObjCReturnsInnerPointer:
5461 return cxstring::createRef("attribute(objc_returns_inner_pointer)");
5462 case CXCursor_ObjCRequiresSuper:
5463 return cxstring::createRef("attribute(objc_requires_super)");
5464 case CXCursor_ObjCRootClass:
5465 return cxstring::createRef("attribute(objc_root_class)");
5466 case CXCursor_ObjCSubclassingRestricted:
5467 return cxstring::createRef("attribute(objc_subclassing_restricted)");
5468 case CXCursor_ObjCExplicitProtocolImpl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005469 return cxstring::createRef(
5470 "attribute(objc_protocol_requires_explicit_implementation)");
Michael Wud092d0b2018-08-03 05:03:22 +00005471 case CXCursor_ObjCDesignatedInitializer:
5472 return cxstring::createRef("attribute(objc_designated_initializer)");
5473 case CXCursor_ObjCRuntimeVisible:
5474 return cxstring::createRef("attribute(objc_runtime_visible)");
5475 case CXCursor_ObjCBoxable:
5476 return cxstring::createRef("attribute(objc_boxable)");
Michael Wu58d837d2018-08-03 05:55:40 +00005477 case CXCursor_FlagEnum:
5478 return cxstring::createRef("attribute(flag_enum)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005480 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005482 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005484 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005485 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005486 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005488 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005490 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005492 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005493 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005494 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005495 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005496 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005498 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00005499 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005500 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005501 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005502 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005503 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005504 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005506 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005508 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00005509 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005510 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005512 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00005513 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005514 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005516 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005518 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005520 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005521 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005522 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00005523 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005524 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00005525 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005526 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00005527 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00005528 return cxstring::createRef("OMPParallelDirective");
5529 case CXCursor_OMPSimdDirective:
5530 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00005531 case CXCursor_OMPForDirective:
5532 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00005533 case CXCursor_OMPForSimdDirective:
5534 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00005535 case CXCursor_OMPSectionsDirective:
5536 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00005537 case CXCursor_OMPSectionDirective:
5538 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00005539 case CXCursor_OMPSingleDirective:
5540 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00005541 case CXCursor_OMPMasterDirective:
5542 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00005543 case CXCursor_OMPCriticalDirective:
5544 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00005545 case CXCursor_OMPParallelForDirective:
5546 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00005547 case CXCursor_OMPParallelForSimdDirective:
5548 return cxstring::createRef("OMPParallelForSimdDirective");
cchen47d60942019-12-05 13:43:48 -05005549 case CXCursor_OMPParallelMasterDirective:
5550 return cxstring::createRef("OMPParallelMasterDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00005551 case CXCursor_OMPParallelSectionsDirective:
5552 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00005553 case CXCursor_OMPTaskDirective:
5554 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00005555 case CXCursor_OMPTaskyieldDirective:
5556 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00005557 case CXCursor_OMPBarrierDirective:
5558 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00005559 case CXCursor_OMPTaskwaitDirective:
5560 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00005561 case CXCursor_OMPTaskgroupDirective:
5562 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00005563 case CXCursor_OMPFlushDirective:
5564 return cxstring::createRef("OMPFlushDirective");
Alexey Bataevc112e942020-02-28 09:52:15 -05005565 case CXCursor_OMPDepobjDirective:
5566 return cxstring::createRef("OMPDepobjDirective");
Alexey Bataevfcba7c32020-03-20 07:03:01 -04005567 case CXCursor_OMPScanDirective:
5568 return cxstring::createRef("OMPScanDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00005569 case CXCursor_OMPOrderedDirective:
5570 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00005571 case CXCursor_OMPAtomicDirective:
5572 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00005573 case CXCursor_OMPTargetDirective:
5574 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00005575 case CXCursor_OMPTargetDataDirective:
5576 return cxstring::createRef("OMPTargetDataDirective");
Samuel Antaodf67fc42016-01-19 19:15:56 +00005577 case CXCursor_OMPTargetEnterDataDirective:
5578 return cxstring::createRef("OMPTargetEnterDataDirective");
Samuel Antao72590762016-01-19 20:04:50 +00005579 case CXCursor_OMPTargetExitDataDirective:
5580 return cxstring::createRef("OMPTargetExitDataDirective");
Arpith Chacko Jacobe955b3d2016-01-26 18:48:41 +00005581 case CXCursor_OMPTargetParallelDirective:
5582 return cxstring::createRef("OMPTargetParallelDirective");
Arpith Chacko Jacob05bebb52016-02-03 15:46:42 +00005583 case CXCursor_OMPTargetParallelForDirective:
5584 return cxstring::createRef("OMPTargetParallelForDirective");
Samuel Antao686c70c2016-05-26 17:30:50 +00005585 case CXCursor_OMPTargetUpdateDirective:
5586 return cxstring::createRef("OMPTargetUpdateDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00005587 case CXCursor_OMPTeamsDirective:
5588 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00005589 case CXCursor_OMPCancellationPointDirective:
5590 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00005591 case CXCursor_OMPCancelDirective:
5592 return cxstring::createRef("OMPCancelDirective");
Alexey Bataev49f6e782015-12-01 04:18:41 +00005593 case CXCursor_OMPTaskLoopDirective:
5594 return cxstring::createRef("OMPTaskLoopDirective");
Alexey Bataev0a6ed842015-12-03 09:40:15 +00005595 case CXCursor_OMPTaskLoopSimdDirective:
5596 return cxstring::createRef("OMPTaskLoopSimdDirective");
Alexey Bataev60e51c42019-10-10 20:13:02 +00005597 case CXCursor_OMPMasterTaskLoopDirective:
5598 return cxstring::createRef("OMPMasterTaskLoopDirective");
Alexey Bataevb8552ab2019-10-18 16:47:35 +00005599 case CXCursor_OMPMasterTaskLoopSimdDirective:
5600 return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
Alexey Bataev5bbcead2019-10-14 17:17:41 +00005601 case CXCursor_OMPParallelMasterTaskLoopDirective:
5602 return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
Alexey Bataev14a388f2019-10-25 10:27:13 -04005603 case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
5604 return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
Carlo Bertolli6200a3d2015-12-14 14:51:25 +00005605 case CXCursor_OMPDistributeDirective:
5606 return cxstring::createRef("OMPDistributeDirective");
Carlo Bertolli9925f152016-06-27 14:55:37 +00005607 case CXCursor_OMPDistributeParallelForDirective:
5608 return cxstring::createRef("OMPDistributeParallelForDirective");
Kelvin Li4a39add2016-07-05 05:00:15 +00005609 case CXCursor_OMPDistributeParallelForSimdDirective:
5610 return cxstring::createRef("OMPDistributeParallelForSimdDirective");
Kelvin Li787f3fc2016-07-06 04:45:38 +00005611 case CXCursor_OMPDistributeSimdDirective:
5612 return cxstring::createRef("OMPDistributeSimdDirective");
Kelvin Lia579b912016-07-14 02:54:56 +00005613 case CXCursor_OMPTargetParallelForSimdDirective:
5614 return cxstring::createRef("OMPTargetParallelForSimdDirective");
Kelvin Li986330c2016-07-20 22:57:10 +00005615 case CXCursor_OMPTargetSimdDirective:
5616 return cxstring::createRef("OMPTargetSimdDirective");
Kelvin Li02532872016-08-05 14:37:37 +00005617 case CXCursor_OMPTeamsDistributeDirective:
5618 return cxstring::createRef("OMPTeamsDistributeDirective");
Kelvin Li4e325f72016-10-25 12:50:55 +00005619 case CXCursor_OMPTeamsDistributeSimdDirective:
5620 return cxstring::createRef("OMPTeamsDistributeSimdDirective");
Kelvin Li579e41c2016-11-30 23:51:03 +00005621 case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
5622 return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
Kelvin Li7ade93f2016-12-09 03:24:30 +00005623 case CXCursor_OMPTeamsDistributeParallelForDirective:
5624 return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
Kelvin Libf594a52016-12-17 05:48:59 +00005625 case CXCursor_OMPTargetTeamsDirective:
5626 return cxstring::createRef("OMPTargetTeamsDirective");
Kelvin Li83c451e2016-12-25 04:52:54 +00005627 case CXCursor_OMPTargetTeamsDistributeDirective:
5628 return cxstring::createRef("OMPTargetTeamsDistributeDirective");
Kelvin Li80e8f562016-12-29 22:16:30 +00005629 case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
5630 return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
Kelvin Li1851df52017-01-03 05:23:48 +00005631 case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
5632 return cxstring::createRef(
5633 "OMPTargetTeamsDistributeParallelForSimdDirective");
Kelvin Lida681182017-01-10 18:08:18 +00005634 case CXCursor_OMPTargetTeamsDistributeSimdDirective:
5635 return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00005636 case CXCursor_OverloadCandidate:
Michael Kruse7520cf02020-03-25 09:26:14 -05005637 return cxstring::createRef("OverloadCandidate");
Sergey Kalinichev8f3b1872015-11-15 13:48:32 +00005638 case CXCursor_TypeAliasTemplateDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005639 return cxstring::createRef("TypeAliasTemplateDecl");
Olivier Goffart81978012016-06-09 16:15:55 +00005640 case CXCursor_StaticAssert:
Michael Kruse7520cf02020-03-25 09:26:14 -05005641 return cxstring::createRef("StaticAssert");
Olivier Goffartd211c642016-11-04 06:29:27 +00005642 case CXCursor_FriendDecl:
Michael Kruse7520cf02020-03-25 09:26:14 -05005643 return cxstring::createRef("FriendDecl");
Sven van Haastregtdc2c9302019-02-11 11:00:56 +00005644 case CXCursor_ConvergentAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005645 return cxstring::createRef("attribute(convergent)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005646 case CXCursor_WarnUnusedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005647 return cxstring::createRef("attribute(warn_unused)");
Emilio Cobos Alvarez0a3fe502019-02-25 21:24:52 +00005648 case CXCursor_WarnUnusedResultAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005649 return cxstring::createRef("attribute(warn_unused_result)");
Emilio Cobos Alvarezcd741272019-03-13 16:16:54 +00005650 case CXCursor_AlignedAttr:
Michael Kruse7520cf02020-03-25 09:26:14 -05005651 return cxstring::createRef("attribute(aligned)");
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 }
5653
5654 llvm_unreachable("Unhandled CXCursorKind");
5655}
5656
5657struct GetCursorData {
5658 SourceLocation TokenBeginLoc;
5659 bool PointsAtMacroArgExpansion;
5660 bool VisitedObjCPropertyImplDecl;
5661 SourceLocation VisitedDeclaratorDeclStartLoc;
5662 CXCursor &BestCursor;
5663
Michael Kruse7520cf02020-03-25 09:26:14 -05005664 GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
5665 CXCursor &outputCursor)
5666 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
5668 VisitedObjCPropertyImplDecl = false;
5669 }
5670};
5671
Michael Kruse7520cf02020-03-25 09:26:14 -05005672static enum CXChildVisitResult
5673GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
5675 CXCursor *BestCursor = &Data->BestCursor;
5676
5677 // If we point inside a macro argument we should provide info of what the
5678 // token is so use the actual cursor, don't replace it with a macro expansion
5679 // cursor.
5680 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
5681 return CXChildVisit_Recurse;
Michael Kruse7520cf02020-03-25 09:26:14 -05005682
Guy Benyei11169dd2012-12-18 14:30:41 +00005683 if (clang_isDeclaration(cursor.kind)) {
5684 // Avoid having the implicit methods override the property decls.
Michael Kruse7520cf02020-03-25 09:26:14 -05005685 if (const ObjCMethodDecl *MD =
5686 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005687 if (MD->isImplicit())
5688 return CXChildVisit_Break;
5689
Michael Kruse7520cf02020-03-25 09:26:14 -05005690 } else if (const ObjCInterfaceDecl *ID =
5691 dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005692 // Check that when we have multiple @class references in the same line,
5693 // that later ones do not override the previous ones.
5694 // If we have:
5695 // @class Foo, Bar;
5696 // source ranges for both start at '@', so 'Bar' will end up overriding
5697 // 'Foo' even though the cursor location was at 'Foo'.
5698 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
5699 BestCursor->kind == CXCursor_ObjCClassRef)
Michael Kruse7520cf02020-03-25 09:26:14 -05005700 if (const ObjCInterfaceDecl *PrevID =
5701 dyn_cast_or_null<ObjCInterfaceDecl>(
5702 getCursorDecl(*BestCursor))) {
5703 if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
5704 !ID->isThisDeclarationADefinition())
5705 return CXChildVisit_Break;
Guy Benyei11169dd2012-12-18 14:30:41 +00005706 }
5707
Michael Kruse7520cf02020-03-25 09:26:14 -05005708 } else if (const DeclaratorDecl *DD =
5709 dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005710 SourceLocation StartLoc = DD->getSourceRange().getBegin();
5711 // Check that when we have multiple declarators in the same line,
5712 // that later ones do not override the previous ones.
5713 // If we have:
5714 // int Foo, Bar;
5715 // source ranges for both start at 'int', so 'Bar' will end up overriding
5716 // 'Foo' even though the cursor location was at 'Foo'.
5717 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
5718 return CXChildVisit_Break;
5719 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
5720
Michael Kruse7520cf02020-03-25 09:26:14 -05005721 } else if (const ObjCPropertyImplDecl *PropImp =
5722 dyn_cast_or_null<ObjCPropertyImplDecl>(
5723 getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005724 (void)PropImp;
5725 // Check that when we have multiple @synthesize in the same line,
5726 // that later ones do not override the previous ones.
5727 // If we have:
5728 // @synthesize Foo, Bar;
5729 // source ranges for both start at '@', so 'Bar' will end up overriding
5730 // 'Foo' even though the cursor location was at 'Foo'.
5731 if (Data->VisitedObjCPropertyImplDecl)
5732 return CXChildVisit_Break;
5733 Data->VisitedObjCPropertyImplDecl = true;
5734 }
5735 }
5736
5737 if (clang_isExpression(cursor.kind) &&
5738 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005739 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005740 // Avoid having the cursor of an expression replace the declaration cursor
5741 // when the expression source range overlaps the declaration range.
5742 // This can happen for C++ constructor expressions whose range generally
5743 // include the variable declaration, e.g.:
Michael Kruse7520cf02020-03-25 09:26:14 -05005744 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
5745 // cursor.
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
5747 D->getLocation() == Data->TokenBeginLoc)
5748 return CXChildVisit_Break;
5749 }
5750 }
5751
Michael Kruse7520cf02020-03-25 09:26:14 -05005752 // If our current best cursor is the construction of a temporary object,
5753 // don't replace that cursor with a type reference, because we want
Guy Benyei11169dd2012-12-18 14:30:41 +00005754 // clang_getCursor() to point at the constructor.
5755 if (clang_isExpression(BestCursor->kind) &&
5756 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
5757 cursor.kind == CXCursor_TypeRef) {
5758 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
5759 // as having the actual point on the type reference.
5760 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
5761 return CXChildVisit_Recurse;
5762 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00005763
5764 // If we already have an Objective-C superclass reference, don't
5765 // update it further.
5766 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
5767 return CXChildVisit_Break;
5768
Guy Benyei11169dd2012-12-18 14:30:41 +00005769 *BestCursor = cursor;
5770 return CXChildVisit_Recurse;
5771}
5772
5773CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005774 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005775 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005776 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005777 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005778
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005779 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5781
5782 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
5783 CXCursor Result = cxcursor::getCursor(TU, SLoc);
5784
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005785 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00005786 CXFile SearchFile;
5787 unsigned SearchLine, SearchColumn;
5788 CXFile ResultFile;
5789 unsigned ResultLine, ResultColumn;
5790 CXString SearchFileName, ResultFileName, KindSpelling, USR;
Michael Kruse7520cf02020-03-25 09:26:14 -05005791 const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
Guy Benyei11169dd2012-12-18 14:30:41 +00005792 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00005793
5794 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
5795 nullptr);
Michael Kruse7520cf02020-03-25 09:26:14 -05005796 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
5797 nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005798 SearchFileName = clang_getFileName(SearchFile);
5799 ResultFileName = clang_getFileName(ResultFile);
5800 KindSpelling = clang_getCursorKindSpelling(Result.kind);
5801 USR = clang_getCursorUSR(Result);
Michael Kruse7520cf02020-03-25 09:26:14 -05005802 *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
5803 SearchLine, SearchColumn,
5804 clang_getCString(KindSpelling))
5805 << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
5806 ResultLine, ResultColumn, clang_getCString(USR),
5807 IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00005808 clang_disposeString(SearchFileName);
5809 clang_disposeString(ResultFileName);
5810 clang_disposeString(KindSpelling);
5811 clang_disposeString(USR);
Michael Kruse7520cf02020-03-25 09:26:14 -05005812
Guy Benyei11169dd2012-12-18 14:30:41 +00005813 CXCursor Definition = clang_getCursorDefinition(Result);
5814 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
5815 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
Michael Kruse7520cf02020-03-25 09:26:14 -05005816 CXString DefinitionKindSpelling =
5817 clang_getCursorKindSpelling(Definition.kind);
Guy Benyei11169dd2012-12-18 14:30:41 +00005818 CXFile DefinitionFile;
5819 unsigned DefinitionLine, DefinitionColumn;
Michael Kruse7520cf02020-03-25 09:26:14 -05005820 clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
5821 &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00005822 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005823 *Log << llvm::format(" -> %s(%s:%d:%d)",
Michael Kruse7520cf02020-03-25 09:26:14 -05005824 clang_getCString(DefinitionKindSpelling),
5825 clang_getCString(DefinitionFileName), DefinitionLine,
5826 DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00005827 clang_disposeString(DefinitionFileName);
5828 clang_disposeString(DefinitionKindSpelling);
5829 }
5830 }
5831
5832 return Result;
5833}
5834
5835CXCursor clang_getNullCursor(void) {
5836 return MakeCXCursorInvalid(CXCursor_InvalidFile);
5837}
5838
5839unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005840 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
5841 // can't set consistently. For example, when visiting a DeclStmt we will set
5842 // it but we don't set it on the result of clang_getCursorDefinition for
5843 // a reference of the same declaration.
5844 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
5845 // when visiting a DeclStmt currently, the AST should be enhanced to be able
5846 // to provide that kind of info.
5847 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005848 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005849 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00005850 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00005851
Guy Benyei11169dd2012-12-18 14:30:41 +00005852 return X == Y;
5853}
5854
5855unsigned clang_hashCursor(CXCursor C) {
5856 unsigned Index = 0;
5857 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
5858 Index = 1;
Michael Kruse7520cf02020-03-25 09:26:14 -05005859
5860 return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
5861 std::make_pair(C.kind, C.data[Index]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005862}
5863
5864unsigned clang_isInvalid(enum CXCursorKind K) {
5865 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
5866}
5867
5868unsigned clang_isDeclaration(enum CXCursorKind K) {
5869 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005870 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
5871}
5872
Ivan Donchevskii08ff9102018-01-04 10:59:50 +00005873unsigned clang_isInvalidDeclaration(CXCursor C) {
5874 if (clang_isDeclaration(C.kind)) {
5875 if (const Decl *D = getCursorDecl(C))
5876 return D->isInvalidDecl();
5877 }
5878
5879 return 0;
5880}
5881
Ivan Donchevskii1c27b152018-01-03 10:33:21 +00005882unsigned clang_isReference(enum CXCursorKind K) {
5883 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
5884}
Guy Benyei11169dd2012-12-18 14:30:41 +00005885
5886unsigned clang_isExpression(enum CXCursorKind K) {
5887 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
5888}
5889
5890unsigned clang_isStatement(enum CXCursorKind K) {
5891 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
5892}
5893
5894unsigned clang_isAttribute(enum CXCursorKind K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005895 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005896}
5897
5898unsigned clang_isTranslationUnit(enum CXCursorKind K) {
5899 return K == CXCursor_TranslationUnit;
5900}
5901
5902unsigned clang_isPreprocessing(enum CXCursorKind K) {
5903 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
5904}
Michael Kruse7520cf02020-03-25 09:26:14 -05005905
Guy Benyei11169dd2012-12-18 14:30:41 +00005906unsigned clang_isUnexposed(enum CXCursorKind K) {
5907 switch (K) {
Michael Kruse7520cf02020-03-25 09:26:14 -05005908 case CXCursor_UnexposedDecl:
5909 case CXCursor_UnexposedExpr:
5910 case CXCursor_UnexposedStmt:
5911 case CXCursor_UnexposedAttr:
5912 return true;
5913 default:
5914 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 }
5916}
5917
Michael Kruse7520cf02020-03-25 09:26:14 -05005918CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005919
5920CXSourceLocation clang_getCursorLocation(CXCursor C) {
5921 if (clang_isReference(C.kind)) {
5922 switch (C.kind) {
5923 case CXCursor_ObjCSuperClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005924 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5925 getCursorObjCSuperClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005926 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5927 }
5928
5929 case CXCursor_ObjCProtocolRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005930 std::pair<const ObjCProtocolDecl *, SourceLocation> P =
5931 getCursorObjCProtocolRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005932 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5933 }
5934
5935 case CXCursor_ObjCClassRef: {
Michael Kruse7520cf02020-03-25 09:26:14 -05005936 std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
5937 getCursorObjCClassRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005938 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5939 }
5940
5941 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005942 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005943 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5944 }
5945
5946 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005947 std::pair<const TemplateDecl *, SourceLocation> P =
5948 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005949 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5950 }
5951
5952 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005953 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005954 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5955 }
5956
5957 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005958 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005959 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5960 }
5961
5962 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005963 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005964 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
5965 }
5966
5967 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005968 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005969 if (!BaseSpec)
5970 return clang_getNullLocation();
Michael Kruse7520cf02020-03-25 09:26:14 -05005971
Guy Benyei11169dd2012-12-18 14:30:41 +00005972 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
Michael Kruse7520cf02020-03-25 09:26:14 -05005973 return cxloc::translateSourceLocation(
5974 getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005975
Guy Benyei11169dd2012-12-18 14:30:41 +00005976 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00005977 BaseSpec->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00005978 }
5979
5980 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005981 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005982 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
5983 }
5984
5985 case CXCursor_OverloadedDeclRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05005986 return cxloc::translateSourceLocation(
5987 getCursorContext(C), getCursorOverloadedDeclRef(C).second);
Guy Benyei11169dd2012-12-18 14:30:41 +00005988
5989 default:
5990 // FIXME: Need a way to enumerate all non-reference cases.
5991 llvm_unreachable("Missed a reference kind");
5992 }
5993 }
5994
5995 if (clang_isExpression(C.kind))
Michael Kruse7520cf02020-03-25 09:26:14 -05005996 return cxloc::translateSourceLocation(
5997 getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));
Guy Benyei11169dd2012-12-18 14:30:41 +00005998
5999 if (clang_isStatement(C.kind))
6000 return cxloc::translateSourceLocation(getCursorContext(C),
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006001 getCursorStmt(C)->getBeginLoc());
Guy Benyei11169dd2012-12-18 14:30:41 +00006002
6003 if (C.kind == CXCursor_PreprocessingDirective) {
6004 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
6005 return cxloc::translateSourceLocation(getCursorContext(C), L);
6006 }
6007
6008 if (C.kind == CXCursor_MacroExpansion) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006009 SourceLocation L =
6010 cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 return cxloc::translateSourceLocation(getCursorContext(C), L);
6012 }
6013
6014 if (C.kind == CXCursor_MacroDefinition) {
6015 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
6016 return cxloc::translateSourceLocation(getCursorContext(C), L);
6017 }
6018
6019 if (C.kind == CXCursor_InclusionDirective) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006020 SourceLocation L =
6021 cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00006022 return cxloc::translateSourceLocation(getCursorContext(C), L);
6023 }
6024
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00006025 if (clang_isAttribute(C.kind)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006026 SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00006027 return cxloc::translateSourceLocation(getCursorContext(C), L);
6028 }
6029
Guy Benyei11169dd2012-12-18 14:30:41 +00006030 if (!clang_isDeclaration(C.kind))
6031 return clang_getNullLocation();
6032
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006033 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006034 if (!D)
6035 return clang_getNullLocation();
6036
6037 SourceLocation Loc = D->getLocation();
6038 // FIXME: Multiple variables declared in a single declaration
6039 // currently lack the information needed to correctly determine their
6040 // ranges when accounting for the type-specifier. We use context
6041 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6042 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006043 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006044 if (!cxcursor::isFirstInDeclGroup(C))
6045 Loc = VD->getLocation();
6046 }
6047
6048 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006049 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006050 Loc = MD->getSelectorStartLoc();
6051
6052 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
6053}
6054
NAKAMURA Takumia01f4c32016-12-19 16:50:43 +00006055} // end extern "C"
6056
Guy Benyei11169dd2012-12-18 14:30:41 +00006057CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
6058 assert(TU);
6059
6060 // Guard against an invalid SourceLocation, or we may assert in one
6061 // of the following calls.
6062 if (SLoc.isInvalid())
6063 return clang_getNullCursor();
6064
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006065 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006066
6067 // Translate the given source location to make it point at the beginning of
6068 // the token under the cursor.
6069 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
6070 CXXUnit->getASTContext().getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05006071
Guy Benyei11169dd2012-12-18 14:30:41 +00006072 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
6073 if (SLoc.isValid()) {
6074 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
6075 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
Michael Kruse7520cf02020-03-25 09:26:14 -05006076 /*VisitPreprocessorLast=*/true,
Guy Benyei11169dd2012-12-18 14:30:41 +00006077 /*VisitIncludedEntities=*/false,
6078 SourceLocation(SLoc));
6079 CursorVis.visitFileRegion();
6080 }
6081
6082 return Result;
6083}
6084
6085static SourceRange getRawCursorExtent(CXCursor C) {
6086 if (clang_isReference(C.kind)) {
6087 switch (C.kind) {
6088 case CXCursor_ObjCSuperClassRef:
Michael Kruse7520cf02020-03-25 09:26:14 -05006089 return getCursorObjCSuperClassRef(C).second;
Guy Benyei11169dd2012-12-18 14:30:41 +00006090
6091 case CXCursor_ObjCProtocolRef:
6092 return getCursorObjCProtocolRef(C).second;
6093
6094 case CXCursor_ObjCClassRef:
6095 return getCursorObjCClassRef(C).second;
6096
6097 case CXCursor_TypeRef:
6098 return getCursorTypeRef(C).second;
6099
6100 case CXCursor_TemplateRef:
6101 return getCursorTemplateRef(C).second;
6102
6103 case CXCursor_NamespaceRef:
6104 return getCursorNamespaceRef(C).second;
6105
6106 case CXCursor_MemberRef:
6107 return getCursorMemberRef(C).second;
6108
6109 case CXCursor_CXXBaseSpecifier:
6110 return getCursorCXXBaseSpecifier(C)->getSourceRange();
6111
6112 case CXCursor_LabelRef:
6113 return getCursorLabelRef(C).second;
6114
6115 case CXCursor_OverloadedDeclRef:
6116 return getCursorOverloadedDeclRef(C).second;
6117
6118 case CXCursor_VariableRef:
6119 return getCursorVariableRef(C).second;
Michael Kruse7520cf02020-03-25 09:26:14 -05006120
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 default:
6122 // FIXME: Need a way to enumerate all non-reference cases.
6123 llvm_unreachable("Missed a reference kind");
6124 }
6125 }
6126
6127 if (clang_isExpression(C.kind))
6128 return getCursorExpr(C)->getSourceRange();
6129
6130 if (clang_isStatement(C.kind))
6131 return getCursorStmt(C)->getSourceRange();
6132
6133 if (clang_isAttribute(C.kind))
6134 return getCursorAttr(C)->getRange();
6135
6136 if (C.kind == CXCursor_PreprocessingDirective)
6137 return cxcursor::getCursorPreprocessingDirective(C);
6138
6139 if (C.kind == CXCursor_MacroExpansion) {
6140 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006141 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006142 return TU->mapRangeFromPreamble(Range);
6143 }
6144
6145 if (C.kind == CXCursor_MacroDefinition) {
6146 ASTUnit *TU = getCursorASTUnit(C);
6147 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
6148 return TU->mapRangeFromPreamble(Range);
6149 }
6150
6151 if (C.kind == CXCursor_InclusionDirective) {
6152 ASTUnit *TU = getCursorASTUnit(C);
Michael Kruse7520cf02020-03-25 09:26:14 -05006153 SourceRange Range =
6154 cxcursor::getCursorInclusionDirective(C)->getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006155 return TU->mapRangeFromPreamble(Range);
6156 }
6157
6158 if (C.kind == CXCursor_TranslationUnit) {
6159 ASTUnit *TU = getCursorASTUnit(C);
6160 FileID MainID = TU->getSourceManager().getMainFileID();
6161 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
6162 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
6163 return SourceRange(Start, End);
6164 }
6165
6166 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006167 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006168 if (!D)
6169 return SourceRange();
6170
6171 SourceRange R = D->getSourceRange();
6172 // FIXME: Multiple variables declared in a single declaration
6173 // currently lack the information needed to correctly determine their
6174 // ranges when accounting for the type-specifier. We use context
6175 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6176 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006177 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006178 if (!cxcursor::isFirstInDeclGroup(C))
6179 R.setBegin(VD->getLocation());
6180 }
6181 return R;
6182 }
6183 return SourceRange();
6184}
6185
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00006186/// Retrieves the "raw" cursor extent, which is then extended to include
Guy Benyei11169dd2012-12-18 14:30:41 +00006187/// the decl-specifier-seq for declarations.
6188static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
6189 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006190 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006191 if (!D)
6192 return SourceRange();
6193
6194 SourceRange R = D->getSourceRange();
6195
6196 // Adjust the start of the location for declarations preceded by
6197 // declaration specifiers.
6198 SourceLocation StartLoc;
6199 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
6200 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006201 StartLoc = TI->getTypeLoc().getBeginLoc();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006202 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006203 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
Stephen Kellyf2ceec42018-08-09 21:08:08 +00006204 StartLoc = TI->getTypeLoc().getBeginLoc();
Guy Benyei11169dd2012-12-18 14:30:41 +00006205 }
6206
6207 if (StartLoc.isValid() && R.getBegin().isValid() &&
6208 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
6209 R.setBegin(StartLoc);
6210
6211 // FIXME: Multiple variables declared in a single declaration
6212 // currently lack the information needed to correctly determine their
6213 // ranges when accounting for the type-specifier. We use context
6214 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
6215 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006216 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006217 if (!cxcursor::isFirstInDeclGroup(C))
6218 R.setBegin(VD->getLocation());
6219 }
6220
Michael Kruse7520cf02020-03-25 09:26:14 -05006221 return R;
Guy Benyei11169dd2012-12-18 14:30:41 +00006222 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006223
Guy Benyei11169dd2012-12-18 14:30:41 +00006224 return getRawCursorExtent(C);
6225}
6226
Guy Benyei11169dd2012-12-18 14:30:41 +00006227CXSourceRange clang_getCursorExtent(CXCursor C) {
6228 SourceRange R = getRawCursorExtent(C);
6229 if (R.isInvalid())
6230 return clang_getNullRange();
6231
6232 return cxloc::translateSourceRange(getCursorContext(C), R);
6233}
6234
6235CXCursor clang_getCursorReferenced(CXCursor C) {
6236 if (clang_isInvalid(C.kind))
6237 return clang_getNullCursor();
6238
6239 CXTranslationUnit tu = getCursorTU(C);
6240 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006241 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006242 if (!D)
6243 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006244 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006245 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006246 if (const ObjCPropertyImplDecl *PropImpl =
6247 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006248 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
6249 return MakeCXCursor(Property, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006250
Guy Benyei11169dd2012-12-18 14:30:41 +00006251 return C;
6252 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006253
Guy Benyei11169dd2012-12-18 14:30:41 +00006254 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006255 const Expr *E = getCursorExpr(C);
6256 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00006257 if (D) {
6258 CXCursor declCursor = MakeCXCursor(D, tu);
6259 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
6260 declCursor);
6261 return declCursor;
6262 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006263
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006264 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00006265 return MakeCursorOverloadedDeclRef(Ovl, tu);
Michael Kruse7520cf02020-03-25 09:26:14 -05006266
Guy Benyei11169dd2012-12-18 14:30:41 +00006267 return clang_getNullCursor();
6268 }
6269
6270 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006271 const Stmt *S = getCursorStmt(C);
6272 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00006273 if (LabelDecl *label = Goto->getLabel())
6274 if (LabelStmt *labelS = label->getStmt())
Michael Kruse7520cf02020-03-25 09:26:14 -05006275 return MakeCXCursor(labelS, getCursorDecl(C), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006276
6277 return clang_getNullCursor();
6278 }
Richard Smith66a81862015-05-04 02:25:31 +00006279
Guy Benyei11169dd2012-12-18 14:30:41 +00006280 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00006281 if (const MacroDefinitionRecord *Def =
6282 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006283 return MakeMacroDefinitionCursor(Def, tu);
6284 }
6285
6286 if (!clang_isReference(C.kind))
6287 return clang_getNullCursor();
6288
6289 switch (C.kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006290 case CXCursor_ObjCSuperClassRef:
6291 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006292
Michael Kruse7520cf02020-03-25 09:26:14 -05006293 case CXCursor_ObjCProtocolRef: {
6294 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
6295 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
6296 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006297
Michael Kruse7520cf02020-03-25 09:26:14 -05006298 return MakeCXCursor(Prot, tu);
6299 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006300
Michael Kruse7520cf02020-03-25 09:26:14 -05006301 case CXCursor_ObjCClassRef: {
6302 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
6303 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
6304 return MakeCXCursor(Def, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006305
Michael Kruse7520cf02020-03-25 09:26:14 -05006306 return MakeCXCursor(Class, tu);
6307 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006308
Michael Kruse7520cf02020-03-25 09:26:14 -05006309 case CXCursor_TypeRef:
6310 return MakeCXCursor(getCursorTypeRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006311
Michael Kruse7520cf02020-03-25 09:26:14 -05006312 case CXCursor_TemplateRef:
6313 return MakeCXCursor(getCursorTemplateRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006314
Michael Kruse7520cf02020-03-25 09:26:14 -05006315 case CXCursor_NamespaceRef:
6316 return MakeCXCursor(getCursorNamespaceRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006317
Michael Kruse7520cf02020-03-25 09:26:14 -05006318 case CXCursor_MemberRef:
6319 return MakeCXCursor(getCursorMemberRef(C).first, tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006320
Michael Kruse7520cf02020-03-25 09:26:14 -05006321 case CXCursor_CXXBaseSpecifier: {
6322 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
6323 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
6324 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006325
Michael Kruse7520cf02020-03-25 09:26:14 -05006326 case CXCursor_LabelRef:
6327 // FIXME: We end up faking the "parent" declaration here because we
6328 // don't want to make CXCursor larger.
6329 return MakeCXCursor(
6330 getCursorLabelRef(C).first,
6331 cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);
Guy Benyei11169dd2012-12-18 14:30:41 +00006332
Michael Kruse7520cf02020-03-25 09:26:14 -05006333 case CXCursor_OverloadedDeclRef:
6334 return C;
Guy Benyei11169dd2012-12-18 14:30:41 +00006335
Michael Kruse7520cf02020-03-25 09:26:14 -05006336 case CXCursor_VariableRef:
6337 return MakeCXCursor(getCursorVariableRef(C).first, tu);
6338
6339 default:
6340 // We would prefer to enumerate all non-reference cursor kinds here.
6341 llvm_unreachable("Unhandled reference cursor kind");
Guy Benyei11169dd2012-12-18 14:30:41 +00006342 }
6343}
6344
6345CXCursor clang_getCursorDefinition(CXCursor C) {
6346 if (clang_isInvalid(C.kind))
6347 return clang_getNullCursor();
6348
6349 CXTranslationUnit TU = getCursorTU(C);
6350
6351 bool WasReference = false;
6352 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
6353 C = clang_getCursorReferenced(C);
6354 WasReference = true;
6355 }
6356
6357 if (C.kind == CXCursor_MacroExpansion)
6358 return clang_getCursorReferenced(C);
6359
6360 if (!clang_isDeclaration(C.kind))
6361 return clang_getNullCursor();
6362
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006363 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00006364 if (!D)
6365 return clang_getNullCursor();
6366
6367 switch (D->getKind()) {
6368 // Declaration kinds that don't really separate the notions of
6369 // declaration and definition.
6370 case Decl::Namespace:
6371 case Decl::Typedef:
6372 case Decl::TypeAlias:
6373 case Decl::TypeAliasTemplate:
6374 case Decl::TemplateTypeParm:
6375 case Decl::EnumConstant:
6376 case Decl::Field:
Richard Smithbdb84f32016-07-22 23:36:59 +00006377 case Decl::Binding:
John McCall5e77d762013-04-16 07:28:30 +00006378 case Decl::MSProperty:
Richard Smithbab6df82020-04-11 22:15:29 -07006379 case Decl::MSGuid:
Guy Benyei11169dd2012-12-18 14:30:41 +00006380 case Decl::IndirectField:
6381 case Decl::ObjCIvar:
6382 case Decl::ObjCAtDefsField:
6383 case Decl::ImplicitParam:
6384 case Decl::ParmVar:
6385 case Decl::NonTypeTemplateParm:
6386 case Decl::TemplateTemplateParm:
6387 case Decl::ObjCCategoryImpl:
6388 case Decl::ObjCImplementation:
6389 case Decl::AccessSpec:
6390 case Decl::LinkageSpec:
Richard Smith8df390f2016-09-08 23:14:54 +00006391 case Decl::Export:
Guy Benyei11169dd2012-12-18 14:30:41 +00006392 case Decl::ObjCPropertyImpl:
6393 case Decl::FileScopeAsm:
6394 case Decl::StaticAssert:
6395 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00006396 case Decl::Captured:
Alexey Bataev4244be22016-02-11 05:35:55 +00006397 case Decl::OMPCapturedExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006398 case Decl::Label: // FIXME: Is this right??
Guy Benyei11169dd2012-12-18 14:30:41 +00006399 case Decl::ClassScopeFunctionSpecialization:
Richard Smithbc491202017-02-17 20:05:37 +00006400 case Decl::CXXDeductionGuide:
Guy Benyei11169dd2012-12-18 14:30:41 +00006401 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00006402 case Decl::OMPThreadPrivate:
Alexey Bataev25ed0c02019-03-07 17:54:44 +00006403 case Decl::OMPAllocate:
Alexey Bataev94a4f0c2016-03-03 05:21:39 +00006404 case Decl::OMPDeclareReduction:
Michael Kruse251e1482019-02-01 20:25:04 +00006405 case Decl::OMPDeclareMapper:
Kelvin Li1408f912018-09-26 04:28:39 +00006406 case Decl::OMPRequires:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006407 case Decl::ObjCTypeParam:
David Majnemerd9b1a4f2015-11-04 03:40:30 +00006408 case Decl::BuiltinTemplate:
Nico Weber66220292016-03-02 17:28:48 +00006409 case Decl::PragmaComment:
Nico Webercbbaeb12016-03-02 19:28:54 +00006410 case Decl::PragmaDetectMismatch:
Richard Smith151c4562016-12-20 21:35:28 +00006411 case Decl::UsingPack:
Saar Razd7aae332019-07-10 21:25:49 +00006412 case Decl::Concept:
Tykerb0561b32019-11-17 11:41:55 +01006413 case Decl::LifetimeExtendedTemporary:
Saar Raza0f50d72020-01-18 09:11:43 +02006414 case Decl::RequiresExprBody:
Guy Benyei11169dd2012-12-18 14:30:41 +00006415 return C;
6416
6417 // Declaration kinds that don't make any sense here, but are
6418 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00006419 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00006420 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00006421 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00006422 break;
6423
6424 // Declaration kinds for which the definition is not resolvable.
6425 case Decl::UnresolvedUsingTypename:
6426 case Decl::UnresolvedUsingValue:
6427 break;
6428
6429 case Decl::UsingDirective:
6430 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
6431 TU);
6432
6433 case Decl::NamespaceAlias:
6434 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
6435
6436 case Decl::Enum:
6437 case Decl::Record:
6438 case Decl::CXXRecord:
6439 case Decl::ClassTemplateSpecialization:
6440 case Decl::ClassTemplatePartialSpecialization:
6441 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
6442 return MakeCXCursor(Def, TU);
6443 return clang_getNullCursor();
6444
6445 case Decl::Function:
6446 case Decl::CXXMethod:
6447 case Decl::CXXConstructor:
6448 case Decl::CXXDestructor:
6449 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00006450 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006451 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00006452 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 return clang_getNullCursor();
6454 }
6455
Larisse Voufo39a1e502013-08-06 01:03:05 +00006456 case Decl::Var:
6457 case Decl::VarTemplateSpecialization:
Richard Smithbdb84f32016-07-22 23:36:59 +00006458 case Decl::VarTemplatePartialSpecialization:
6459 case Decl::Decomposition: {
Guy Benyei11169dd2012-12-18 14:30:41 +00006460 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006461 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 return MakeCXCursor(Def, TU);
6463 return clang_getNullCursor();
6464 }
6465
6466 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00006467 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006468 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
6469 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
6470 return clang_getNullCursor();
6471 }
6472
6473 case Decl::ClassTemplate: {
Michael Kruse7520cf02020-03-25 09:26:14 -05006474 if (RecordDecl *Def =
6475 cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006476 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
6477 TU);
6478 return clang_getNullCursor();
6479 }
6480
Larisse Voufo39a1e502013-08-06 01:03:05 +00006481 case Decl::VarTemplate: {
6482 if (VarDecl *Def =
6483 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
6484 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
6485 return clang_getNullCursor();
6486 }
6487
Guy Benyei11169dd2012-12-18 14:30:41 +00006488 case Decl::Using:
Michael Kruse7520cf02020-03-25 09:26:14 -05006489 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
6490 TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006491
6492 case Decl::UsingShadow:
Richard Smith5179eb72016-06-28 19:03:57 +00006493 case Decl::ConstructorUsingShadow:
Guy Benyei11169dd2012-12-18 14:30:41 +00006494 return clang_getCursorDefinition(
Michael Kruse7520cf02020-03-25 09:26:14 -05006495 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +00006496
6497 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006498 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006499 if (Method->isThisDeclarationADefinition())
6500 return C;
6501
6502 // Dig out the method definition in the associated
6503 // @implementation, if we have it.
6504 // FIXME: The ASTs should make finding the definition easier.
Michael Kruse7520cf02020-03-25 09:26:14 -05006505 if (const ObjCInterfaceDecl *Class =
6506 dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006507 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
Michael Kruse7520cf02020-03-25 09:26:14 -05006508 if (ObjCMethodDecl *Def = ClassImpl->getMethod(
6509 Method->getSelector(), Method->isInstanceMethod()))
Guy Benyei11169dd2012-12-18 14:30:41 +00006510 if (Def->isThisDeclarationADefinition())
6511 return MakeCXCursor(Def, TU);
6512
6513 return clang_getNullCursor();
6514 }
6515
6516 case Decl::ObjCCategory:
Michael Kruse7520cf02020-03-25 09:26:14 -05006517 if (ObjCCategoryImplDecl *Impl =
6518 cast<ObjCCategoryDecl>(D)->getImplementation())
Guy Benyei11169dd2012-12-18 14:30:41 +00006519 return MakeCXCursor(Impl, TU);
6520 return clang_getNullCursor();
6521
6522 case Decl::ObjCProtocol:
Michael Kruse7520cf02020-03-25 09:26:14 -05006523 if (const ObjCProtocolDecl *Def =
6524 cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006525 return MakeCXCursor(Def, TU);
6526 return clang_getNullCursor();
6527
6528 case Decl::ObjCInterface: {
6529 // There are two notions of a "definition" for an Objective-C
6530 // class: the interface and its implementation. When we resolved a
6531 // reference to an Objective-C class, produce the @interface as
6532 // the definition; when we were provided with the interface,
6533 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006534 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006535 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006536 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006537 return MakeCXCursor(Def, TU);
6538 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
6539 return MakeCXCursor(Impl, TU);
6540 return clang_getNullCursor();
6541 }
6542
6543 case Decl::ObjCProperty:
6544 // FIXME: We don't really know where to find the
6545 // ObjCPropertyImplDecls that implement this property.
6546 return clang_getNullCursor();
6547
6548 case Decl::ObjCCompatibleAlias:
Michael Kruse7520cf02020-03-25 09:26:14 -05006549 if (const ObjCInterfaceDecl *Class =
6550 cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006551 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00006552 return MakeCXCursor(Def, TU);
6553
6554 return clang_getNullCursor();
6555
6556 case Decl::Friend:
6557 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
6558 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6559 return clang_getNullCursor();
6560
6561 case Decl::FriendTemplate:
6562 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
6563 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
6564 return clang_getNullCursor();
6565 }
6566
6567 return clang_getNullCursor();
6568}
6569
6570unsigned clang_isCursorDefinition(CXCursor C) {
6571 if (!clang_isDeclaration(C.kind))
6572 return 0;
6573
6574 return clang_getCursorDefinition(C) == C;
6575}
6576
6577CXCursor clang_getCanonicalCursor(CXCursor C) {
6578 if (!clang_isDeclaration(C.kind))
6579 return C;
Michael Kruse7520cf02020-03-25 09:26:14 -05006580
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006581 if (const Decl *D = getCursorDecl(C)) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006582 if (const ObjCCategoryImplDecl *CatImplD =
6583 dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006584 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
6585 return MakeCXCursor(CatD, getCursorTU(C));
6586
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006587 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
6588 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00006589 return MakeCXCursor(IFD, getCursorTU(C));
6590
6591 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
6592 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006593
Guy Benyei11169dd2012-12-18 14:30:41 +00006594 return C;
6595}
6596
6597int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
6598 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
6599}
Michael Kruse7520cf02020-03-25 09:26:14 -05006600
Guy Benyei11169dd2012-12-18 14:30:41 +00006601unsigned clang_getNumOverloadedDecls(CXCursor C) {
6602 if (C.kind != CXCursor_OverloadedDeclRef)
6603 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05006604
Guy Benyei11169dd2012-12-18 14:30:41 +00006605 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006606 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006607 return E->getNumDecls();
Michael Kruse7520cf02020-03-25 09:26:14 -05006608
6609 if (OverloadedTemplateStorage *S =
6610 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006611 return S->size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006612
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006613 const Decl *D = Storage.get<const Decl *>();
6614 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006615 return Using->shadow_size();
Michael Kruse7520cf02020-03-25 09:26:14 -05006616
Guy Benyei11169dd2012-12-18 14:30:41 +00006617 return 0;
6618}
6619
6620CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
6621 if (cursor.kind != CXCursor_OverloadedDeclRef)
6622 return clang_getNullCursor();
6623
6624 if (index >= clang_getNumOverloadedDecls(cursor))
6625 return clang_getNullCursor();
Michael Kruse7520cf02020-03-25 09:26:14 -05006626
Guy Benyei11169dd2012-12-18 14:30:41 +00006627 CXTranslationUnit TU = getCursorTU(cursor);
6628 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006629 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006630 return MakeCXCursor(E->decls_begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006631
6632 if (OverloadedTemplateStorage *S =
6633 Storage.dyn_cast<OverloadedTemplateStorage *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00006634 return MakeCXCursor(S->begin()[index], TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05006635
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006636 const Decl *D = Storage.get<const Decl *>();
6637 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006638 // FIXME: This is, unfortunately, linear time.
6639 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
6640 std::advance(Pos, index);
6641 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
6642 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006643
Guy Benyei11169dd2012-12-18 14:30:41 +00006644 return clang_getNullCursor();
6645}
Michael Kruse7520cf02020-03-25 09:26:14 -05006646
6647void clang_getDefinitionSpellingAndExtent(
6648 CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
6649 unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006650 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006651 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00006652 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
6653
6654 SourceManager &SM = FD->getASTContext().getSourceManager();
6655 *startBuf = SM.getCharacterData(Body->getLBracLoc());
6656 *endBuf = SM.getCharacterData(Body->getRBracLoc());
6657 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
6658 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
6659 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
6660 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
6661}
6662
Guy Benyei11169dd2012-12-18 14:30:41 +00006663CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
6664 unsigned PieceIndex) {
6665 RefNamePieces Pieces;
Michael Kruse7520cf02020-03-25 09:26:14 -05006666
Guy Benyei11169dd2012-12-18 14:30:41 +00006667 switch (C.kind) {
6668 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006669 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006670 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
6671 E->getQualifierLoc().getSourceRange());
6672 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006673
Guy Benyei11169dd2012-12-18 14:30:41 +00006674 case CXCursor_DeclRefExpr:
James Y Knight04ec5bf2015-12-24 02:59:37 +00006675 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
6676 SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
6677 Pieces =
6678 buildPieces(NameFlags, false, E->getNameInfo(),
6679 E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
6680 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006681 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006682
Guy Benyei11169dd2012-12-18 14:30:41 +00006683 case CXCursor_CallExpr:
Michael Kruse7520cf02020-03-25 09:26:14 -05006684 if (const CXXOperatorCallExpr *OCE =
6685 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006686 const Expr *Callee = OCE->getCallee();
6687 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006688 Callee = ICE->getSubExpr();
6689
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00006690 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00006691 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
6692 DRE->getQualifierLoc().getSourceRange());
6693 }
6694 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05006695
Guy Benyei11169dd2012-12-18 14:30:41 +00006696 default:
6697 break;
6698 }
6699
6700 if (Pieces.empty()) {
6701 if (PieceIndex == 0)
6702 return clang_getCursorExtent(C);
6703 } else if (PieceIndex < Pieces.size()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006704 SourceRange R = Pieces[PieceIndex];
6705 if (R.isValid())
6706 return cxloc::translateSourceRange(getCursorContext(C), R);
Guy Benyei11169dd2012-12-18 14:30:41 +00006707 }
Michael Kruse7520cf02020-03-25 09:26:14 -05006708
Guy Benyei11169dd2012-12-18 14:30:41 +00006709 return clang_getNullRange();
6710}
6711
6712void clang_enableStackTraces(void) {
Richard Smithdfed58a2016-06-09 00:53:41 +00006713 // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
6714 llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
Guy Benyei11169dd2012-12-18 14:30:41 +00006715}
6716
Michael Kruse7520cf02020-03-25 09:26:14 -05006717void clang_executeOnThread(void (*fn)(void *), void *user_data,
Guy Benyei11169dd2012-12-18 14:30:41 +00006718 unsigned stack_size) {
Alexandre Ganea471d0602019-11-29 10:52:13 -05006719 llvm::llvm_execute_on_thread(fn, user_data,
6720 stack_size == 0
6721 ? clang::DesiredStackSize
6722 : llvm::Optional<unsigned>(stack_size));
Guy Benyei11169dd2012-12-18 14:30:41 +00006723}
6724
Guy Benyei11169dd2012-12-18 14:30:41 +00006725//===----------------------------------------------------------------------===//
6726// Token-based Operations.
6727//===----------------------------------------------------------------------===//
6728
6729/* CXToken layout:
6730 * int_data[0]: a CXTokenKind
6731 * int_data[1]: starting token location
6732 * int_data[2]: token length
6733 * int_data[3]: reserved
6734 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
6735 * otherwise unused.
6736 */
Guy Benyei11169dd2012-12-18 14:30:41 +00006737CXTokenKind clang_getTokenKind(CXToken CXTok) {
6738 return static_cast<CXTokenKind>(CXTok.int_data[0]);
6739}
6740
6741CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
6742 switch (clang_getTokenKind(CXTok)) {
6743 case CXToken_Identifier:
6744 case CXToken_Keyword:
6745 // We know we have an IdentifierInfo*, so use that.
Michael Kruse7520cf02020-03-25 09:26:14 -05006746 return cxstring::createRef(
6747 static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00006748
6749 case CXToken_Literal: {
6750 // We have stashed the starting pointer in the ptr_data field. Use it.
6751 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006752 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006753 }
6754
6755 case CXToken_Punctuation:
6756 case CXToken_Comment:
6757 break;
6758 }
6759
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006760 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006761 LOG_BAD_TU(TU);
6762 return cxstring::createEmpty();
6763 }
6764
Guy Benyei11169dd2012-12-18 14:30:41 +00006765 // We have to find the starting buffer pointer the hard way, by
6766 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006767 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006768 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006769 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006770
6771 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
Michael Kruse7520cf02020-03-25 09:26:14 -05006772 std::pair<FileID, unsigned> LocInfo =
6773 CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
Guy Benyei11169dd2012-12-18 14:30:41 +00006774 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006775 StringRef Buffer =
6776 CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006777 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006778 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006779
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006780 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006781}
6782
6783CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006784 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006785 LOG_BAD_TU(TU);
6786 return clang_getNullLocation();
6787 }
6788
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006789 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006790 if (!CXXUnit)
6791 return clang_getNullLocation();
6792
Michael Kruse7520cf02020-03-25 09:26:14 -05006793 return cxloc::translateSourceLocation(
6794 CXXUnit->getASTContext(),
6795 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006796}
6797
6798CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006799 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006800 LOG_BAD_TU(TU);
6801 return clang_getNullRange();
6802 }
6803
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006804 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006805 if (!CXXUnit)
6806 return clang_getNullRange();
6807
Michael Kruse7520cf02020-03-25 09:26:14 -05006808 return cxloc::translateSourceRange(
6809 CXXUnit->getASTContext(),
6810 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006811}
6812
6813static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
6814 SmallVectorImpl<CXToken> &CXTokens) {
6815 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05006816 std::pair<FileID, unsigned> BeginLocInfo =
6817 SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
6818 std::pair<FileID, unsigned> EndLocInfo =
6819 SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006820
6821 // Cannot tokenize across files.
6822 if (BeginLocInfo.first != EndLocInfo.first)
6823 return;
6824
6825 // Create a lexer
6826 bool Invalid = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05006827 StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
Guy Benyei11169dd2012-12-18 14:30:41 +00006828 if (Invalid)
6829 return;
Michael Kruse7520cf02020-03-25 09:26:14 -05006830
Guy Benyei11169dd2012-12-18 14:30:41 +00006831 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05006832 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
6833 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00006834 Lex.SetCommentRetentionState(true);
6835
6836 // Lex tokens until we hit the end of the range.
6837 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
6838 Token Tok;
6839 bool previousWasAt = false;
6840 do {
6841 // Lex the next token
6842 Lex.LexFromRawLexer(Tok);
6843 if (Tok.is(tok::eof))
6844 break;
6845
6846 // Initialize the CXToken.
6847 CXToken CXTok;
6848
6849 // - Common fields
6850 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
6851 CXTok.int_data[2] = Tok.getLength();
6852 CXTok.int_data[3] = 0;
6853
6854 // - Kind-specific fields
6855 if (Tok.isLiteral()) {
6856 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006857 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00006858 } else if (Tok.is(tok::raw_identifier)) {
6859 // Lookup the identifier to determine whether we have a keyword.
Michael Kruse7520cf02020-03-25 09:26:14 -05006860 IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
Guy Benyei11169dd2012-12-18 14:30:41 +00006861
6862 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
6863 CXTok.int_data[0] = CXToken_Keyword;
Michael Kruse7520cf02020-03-25 09:26:14 -05006864 } else {
6865 CXTok.int_data[0] =
6866 Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
Guy Benyei11169dd2012-12-18 14:30:41 +00006867 }
6868 CXTok.ptr_data = II;
6869 } else if (Tok.is(tok::comment)) {
6870 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00006871 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006872 } else {
6873 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00006874 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006875 }
6876 CXTokens.push_back(CXTok);
6877 previousWasAt = Tok.is(tok::at);
Argyrios Kyrtzidisc7c6a072016-11-09 23:58:39 +00006878 } while (Lex.getBufferLocation() < EffectiveBufferEnd);
Guy Benyei11169dd2012-12-18 14:30:41 +00006879}
6880
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006881CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
Michael Kruse7520cf02020-03-25 09:26:14 -05006882 LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006883
6884 if (isNotUsableTU(TU)) {
6885 LOG_BAD_TU(TU);
6886 return NULL;
6887 }
6888
6889 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
6890 if (!CXXUnit)
6891 return NULL;
6892
6893 SourceLocation Begin = cxloc::translateSourceLocation(Location);
6894 if (Begin.isInvalid())
6895 return NULL;
6896 SourceManager &SM = CXXUnit->getSourceManager();
6897 std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
Michael Kruse7520cf02020-03-25 09:26:14 -05006898 DecomposedEnd.second +=
6899 Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006900
Michael Kruse7520cf02020-03-25 09:26:14 -05006901 SourceLocation End =
6902 SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);
Ivan Donchevskii3957e482018-06-13 12:37:08 +00006903
6904 SmallVector<CXToken, 32> CXTokens;
6905 getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);
6906
6907 if (CXTokens.empty())
6908 return NULL;
6909
6910 CXTokens.resize(1);
6911 CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));
6912
6913 memmove(Token, CXTokens.data(), sizeof(CXToken));
6914 return Token;
6915}
6916
Michael Kruse7520cf02020-03-25 09:26:14 -05006917void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
6918 unsigned *NumTokens) {
6919 LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006920
Guy Benyei11169dd2012-12-18 14:30:41 +00006921 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00006922 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006923 if (NumTokens)
6924 *NumTokens = 0;
6925
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006926 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006927 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006928 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006929 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00006930
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006931 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006932 if (!CXXUnit || !Tokens || !NumTokens)
6933 return;
6934
6935 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Michael Kruse7520cf02020-03-25 09:26:14 -05006936
Guy Benyei11169dd2012-12-18 14:30:41 +00006937 SourceRange R = cxloc::translateCXSourceRange(Range);
6938 if (R.isInvalid())
6939 return;
6940
6941 SmallVector<CXToken, 32> CXTokens;
6942 getTokens(CXXUnit, R, CXTokens);
6943
6944 if (CXTokens.empty())
6945 return;
6946
Serge Pavlov52525732018-02-21 02:02:39 +00006947 *Tokens = static_cast<CXToken *>(
6948 llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
Guy Benyei11169dd2012-12-18 14:30:41 +00006949 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
6950 *NumTokens = CXTokens.size();
6951}
6952
Michael Kruse7520cf02020-03-25 09:26:14 -05006953void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
6954 unsigned NumTokens) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006955 free(Tokens);
6956}
6957
Guy Benyei11169dd2012-12-18 14:30:41 +00006958//===----------------------------------------------------------------------===//
6959// Token annotation APIs.
6960//===----------------------------------------------------------------------===//
6961
Guy Benyei11169dd2012-12-18 14:30:41 +00006962static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
6963 CXCursor parent,
6964 CXClientData client_data);
6965static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
6966 CXClientData client_data);
6967
6968namespace {
6969class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00006970 CXToken *Tokens;
6971 CXCursor *Cursors;
6972 unsigned NumTokens;
6973 unsigned TokIdx;
6974 unsigned PreprocessingTokIdx;
6975 CursorVisitor AnnotateVis;
6976 SourceManager &SrcMgr;
6977 bool HasContextSensitiveKeywords;
6978
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006979 struct PostChildrenAction {
6980 CXCursor cursor;
6981 enum Action { Invalid, Ignore, Postpone } action;
6982 };
6983 using PostChildrenActions = SmallVector<PostChildrenAction, 0>;
6984
Guy Benyei11169dd2012-12-18 14:30:41 +00006985 struct PostChildrenInfo {
6986 CXCursor Cursor;
6987 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00006988 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006989 unsigned BeforeChildrenTokenIdx;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00006990 PostChildrenActions ChildActions;
Guy Benyei11169dd2012-12-18 14:30:41 +00006991 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006992 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006993
6994 CXToken &getTok(unsigned Idx) {
6995 assert(Idx < NumTokens);
6996 return Tokens[Idx];
6997 }
6998 const CXToken &getTok(unsigned Idx) const {
6999 assert(Idx < NumTokens);
7000 return Tokens[Idx];
7001 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007002 bool MoreTokens() const { return TokIdx < NumTokens; }
7003 unsigned NextToken() const { return TokIdx; }
7004 void AdvanceToken() { ++TokIdx; }
7005 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007006 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007007 }
7008 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007009 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007010 }
7011 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007012 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007013 }
7014
7015 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007016 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00007017 SourceRange);
7018
7019public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007020 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007021 CXTranslationUnit TU, SourceRange RegionOfInterest)
Michael Kruse7520cf02020-03-25 09:26:14 -05007022 : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
7023 PreprocessingTokIdx(0),
7024 AnnotateVis(TU, AnnotateTokensVisitor, this,
7025 /*VisitPreprocessorLast=*/true,
7026 /*VisitIncludedEntities=*/false, RegionOfInterest,
7027 /*VisitDeclsOnly=*/false,
7028 AnnotateTokensPostChildrenVisitor),
7029 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
7030 HasContextSensitiveKeywords(false) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007031
7032 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
7033 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007034 bool IsIgnoredChildCursor(CXCursor cursor) const;
7035 PostChildrenActions DetermineChildActions(CXCursor Cursor) const;
7036
Guy Benyei11169dd2012-12-18 14:30:41 +00007037 bool postVisitChildren(CXCursor cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007038 void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
7039 void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);
7040
Guy Benyei11169dd2012-12-18 14:30:41 +00007041 void AnnotateTokens();
Michael Kruse7520cf02020-03-25 09:26:14 -05007042
7043 /// Determine whether the annotator saw any cursors that have
Guy Benyei11169dd2012-12-18 14:30:41 +00007044 /// context-sensitive keywords.
7045 bool hasContextSensitiveKeywords() const {
7046 return HasContextSensitiveKeywords;
7047 }
7048
Michael Kruse7520cf02020-03-25 09:26:14 -05007049 ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
Guy Benyei11169dd2012-12-18 14:30:41 +00007050};
Michael Kruse7520cf02020-03-25 09:26:14 -05007051} // namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00007052
7053void AnnotateTokensWorker::AnnotateTokens() {
7054 // Walk the AST within the region of interest, annotating tokens
7055 // along the way.
7056 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007057}
Guy Benyei11169dd2012-12-18 14:30:41 +00007058
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007059bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
7060 if (PostChildrenInfos.empty())
7061 return false;
7062
7063 for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
7064 if (ChildAction.cursor == cursor &&
7065 ChildAction.action == PostChildrenAction::Ignore) {
7066 return true;
7067 }
7068 }
7069
7070 return false;
7071}
7072
7073const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
7074 if (!clang_isExpression(Cursor.kind))
7075 return nullptr;
7076
7077 const Expr *E = getCursorExpr(Cursor);
7078 if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7079 const OverloadedOperatorKind Kind = OCE->getOperator();
7080 if (Kind == OO_Call || Kind == OO_Subscript)
7081 return OCE;
7082 }
7083
7084 return nullptr;
7085}
7086
7087AnnotateTokensWorker::PostChildrenActions
7088AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
7089 PostChildrenActions actions;
7090
7091 // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
7092 // visited before the arguments to the operator call. For the Call and
7093 // Subscript operator the range of this DeclRefExpr includes the whole call
7094 // expression, so that all tokens in that range would be mapped to the
7095 // operator function, including the tokens of the arguments. To avoid that,
7096 // ensure to visit this DeclRefExpr as last node.
7097 if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
7098 const Expr *Callee = OCE->getCallee();
7099 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
7100 const Expr *SubExpr = ICE->getSubExpr();
7101 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
Fangrui Songcabb36d2018-11-20 08:00:00 +00007102 const Decl *parentDecl = getCursorDecl(Cursor);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007103 CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
7104
7105 // Visit the DeclRefExpr as last.
7106 CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
7107 actions.push_back({cxChild, PostChildrenAction::Postpone});
7108
7109 // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
7110 // wide range as the DeclRefExpr. We can skip visiting this entirely.
7111 cxChild = MakeCXCursor(ICE, parentDecl, TU);
7112 actions.push_back({cxChild, PostChildrenAction::Ignore});
7113 }
7114 }
7115 }
7116
7117 return actions;
7118}
7119
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007120static inline void updateCursorAnnotation(CXCursor &Cursor,
7121 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007122 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00007123 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007124 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00007125}
7126
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007127/// It annotates and advances tokens with a cursor until the comparison
Guy Benyei11169dd2012-12-18 14:30:41 +00007128//// between the cursor location and the source range is the same as
7129/// \arg compResult.
7130///
7131/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
7132/// Pass RangeOverlap to annotate tokens inside a range.
Michael Kruse7520cf02020-03-25 09:26:14 -05007133void AnnotateTokensWorker::annotateAndAdvanceTokens(
7134 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007135 while (MoreTokens()) {
7136 const unsigned I = NextToken();
7137 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007138 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
7139 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00007140
7141 SourceLocation TokLoc = GetTokenLoc(I);
7142 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007143 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007144 AdvanceToken();
7145 continue;
7146 }
7147 break;
7148 }
7149}
7150
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007151/// Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007152/// \returns true if it advanced beyond all macro tokens, false otherwise.
7153bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Michael Kruse7520cf02020-03-25 09:26:14 -05007154 CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007155 assert(MoreTokens());
7156 assert(isFunctionMacroToken(NextToken()) &&
7157 "Should be called only for macro arg tokens");
7158
7159 // This works differently than annotateAndAdvanceTokens; because expanded
7160 // macro arguments can have arbitrary translation-unit source order, we do not
7161 // advance the token index one by one until a token fails the range test.
7162 // We only advance once past all of the macro arg tokens if all of them
7163 // pass the range test. If one of them fails we keep the token index pointing
7164 // at the start of the macro arg tokens so that the failing token will be
7165 // annotated by a subsequent annotation try.
7166
7167 bool atLeastOneCompFail = false;
Michael Kruse7520cf02020-03-25 09:26:14 -05007168
Guy Benyei11169dd2012-12-18 14:30:41 +00007169 unsigned I = NextToken();
7170 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
7171 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
7172 if (TokLoc.isFileID())
7173 continue; // not macro arg token, it's parens or comma.
7174 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
7175 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
7176 Cursors[I] = updateC;
7177 } else
7178 atLeastOneCompFail = true;
7179 }
7180
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007181 if (atLeastOneCompFail)
7182 return false;
7183
7184 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
7185 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00007186}
7187
Michael Kruse7520cf02020-03-25 09:26:14 -05007188enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
7189 CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007190 SourceRange cursorRange = getRawCursorExtent(cursor);
7191 if (cursorRange.isInvalid())
7192 return CXChildVisit_Recurse;
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007193
7194 if (IsIgnoredChildCursor(cursor))
7195 return CXChildVisit_Continue;
7196
Guy Benyei11169dd2012-12-18 14:30:41 +00007197 if (!HasContextSensitiveKeywords) {
7198 // Objective-C properties can have context-sensitive keywords.
7199 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007200 if (const ObjCPropertyDecl *Property =
7201 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
7202 HasContextSensitiveKeywords =
7203 Property->getPropertyAttributesAsWritten() != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007204 }
7205 // Objective-C methods can have context-sensitive keywords.
7206 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
7207 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007208 if (const ObjCMethodDecl *Method =
7209 dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007210 if (Method->getObjCDeclQualifier())
7211 HasContextSensitiveKeywords = true;
7212 else {
David Majnemer59f77922016-06-24 04:05:48 +00007213 for (const auto *P : Method->parameters()) {
Aaron Ballman43b68be2014-03-07 17:50:17 +00007214 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007215 HasContextSensitiveKeywords = true;
7216 break;
7217 }
7218 }
7219 }
7220 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007221 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007222 // C++ methods can have context-sensitive keywords.
7223 else if (cursor.kind == CXCursor_CXXMethod) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007224 if (const CXXMethodDecl *Method =
7225 dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007226 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
7227 HasContextSensitiveKeywords = true;
7228 }
7229 }
7230 // C++ classes can have context-sensitive keywords.
7231 else if (cursor.kind == CXCursor_StructDecl ||
7232 cursor.kind == CXCursor_ClassDecl ||
7233 cursor.kind == CXCursor_ClassTemplate ||
7234 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007235 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00007236 if (D->hasAttr<FinalAttr>())
7237 HasContextSensitiveKeywords = true;
7238 }
7239 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00007240
7241 // Don't override a property annotation with its getter/setter method.
7242 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
7243 parent.kind == CXCursor_ObjCPropertyDecl)
7244 return CXChildVisit_Continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007245
7246 if (clang_isPreprocessing(cursor.kind)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007247 // Items in the preprocessing record are kept separate from items in
7248 // declarations, so we keep a separate token index.
7249 unsigned SavedTokIdx = TokIdx;
7250 TokIdx = PreprocessingTokIdx;
7251
7252 // Skip tokens up until we catch up to the beginning of the preprocessing
7253 // entry.
7254 while (MoreTokens()) {
7255 const unsigned I = NextToken();
7256 SourceLocation TokLoc = GetTokenLoc(I);
7257 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7258 case RangeBefore:
7259 AdvanceToken();
7260 continue;
7261 case RangeAfter:
7262 case RangeOverlap:
7263 break;
7264 }
7265 break;
7266 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007267
Guy Benyei11169dd2012-12-18 14:30:41 +00007268 // Look at all of the tokens within this range.
7269 while (MoreTokens()) {
7270 const unsigned I = NextToken();
7271 SourceLocation TokLoc = GetTokenLoc(I);
7272 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
7273 case RangeBefore:
7274 llvm_unreachable("Infeasible");
7275 case RangeAfter:
7276 break;
7277 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007278 // For macro expansions, just note where the beginning of the macro
7279 // expansion occurs.
7280 if (cursor.kind == CXCursor_MacroExpansion) {
7281 if (TokLoc == cursorRange.getBegin())
7282 Cursors[I] = cursor;
7283 AdvanceToken();
7284 break;
7285 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007286 // We may have already annotated macro names inside macro definitions.
7287 if (Cursors[I].kind != CXCursor_MacroExpansion)
7288 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00007289 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007290 continue;
7291 }
7292 break;
7293 }
7294
7295 // Save the preprocessing token index; restore the non-preprocessing
7296 // token index.
7297 PreprocessingTokIdx = TokIdx;
7298 TokIdx = SavedTokIdx;
7299 return CXChildVisit_Recurse;
7300 }
7301
7302 if (cursorRange.isInvalid())
7303 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007304
7305 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00007306 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007307 const enum CXCursorKind K = clang_getCursorKind(parent);
7308 const CXCursor updateC =
Michael Kruse7520cf02020-03-25 09:26:14 -05007309 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
7310 // Attributes are annotated out-of-order, skip tokens until we reach it.
7311 clang_isAttribute(cursor.kind))
7312 ? clang_getNullCursor()
7313 : parent;
Guy Benyei11169dd2012-12-18 14:30:41 +00007314
7315 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
7316
7317 // Avoid having the cursor of an expression "overwrite" the annotation of the
7318 // variable declaration that it belongs to.
7319 // This can happen for C++ constructor expressions whose range generally
7320 // include the variable declaration, e.g.:
7321 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007322 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00007323 const Expr *E = getCursorExpr(cursor);
Fangrui Songcabb36d2018-11-20 08:00:00 +00007324 if (const Decl *D = getCursorDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007325 const unsigned I = NextToken();
Stephen Kellyf2ceec42018-08-09 21:08:08 +00007326 if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
7327 E->getBeginLoc() == D->getLocation() &&
7328 E->getBeginLoc() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007329 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00007330 AdvanceToken();
7331 }
7332 }
7333 }
7334
7335 // Before recursing into the children keep some state that we are going
7336 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
7337 // extra work after the child nodes are visited.
7338 // Note that we don't call VisitChildren here to avoid traversing statements
7339 // code-recursively which can blow the stack.
7340
7341 PostChildrenInfo Info;
7342 Info.Cursor = cursor;
7343 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007344 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007345 Info.BeforeChildrenTokenIdx = NextToken();
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007346 Info.ChildActions = DetermineChildActions(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007347 PostChildrenInfos.push_back(Info);
7348
7349 return CXChildVisit_Recurse;
7350}
7351
7352bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
7353 if (PostChildrenInfos.empty())
7354 return false;
7355 const PostChildrenInfo &Info = PostChildrenInfos.back();
7356 if (!clang_equalCursors(Info.Cursor, cursor))
7357 return false;
7358
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007359 HandlePostPonedChildCursors(Info);
7360
Guy Benyei11169dd2012-12-18 14:30:41 +00007361 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
7362 const unsigned AfterChildren = NextToken();
7363 SourceRange cursorRange = Info.CursorRange;
7364
7365 // Scan the tokens that are at the end of the cursor, but are not captured
7366 // but the child cursors.
7367 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
7368
7369 // Scan the tokens that are at the beginning of the cursor, but are not
7370 // capture by the child cursors.
7371 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
7372 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
7373 break;
7374
7375 Cursors[I] = cursor;
7376 }
7377
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00007378 // Attributes are annotated out-of-order, rewind TokIdx to when we first
7379 // encountered the attribute cursor.
7380 if (clang_isAttribute(cursor.kind))
7381 TokIdx = Info.BeforeReachingCursorIdx;
7382
Guy Benyei11169dd2012-12-18 14:30:41 +00007383 PostChildrenInfos.pop_back();
7384 return false;
7385}
7386
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007387void AnnotateTokensWorker::HandlePostPonedChildCursors(
7388 const PostChildrenInfo &Info) {
7389 for (const auto &ChildAction : Info.ChildActions) {
7390 if (ChildAction.action == PostChildrenAction::Postpone) {
7391 HandlePostPonedChildCursor(ChildAction.cursor,
7392 Info.BeforeChildrenTokenIdx);
7393 }
7394 }
7395}
7396
7397void AnnotateTokensWorker::HandlePostPonedChildCursor(
7398 CXCursor Cursor, unsigned StartTokenIndex) {
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007399 unsigned I = StartTokenIndex;
7400
7401 // The bracket tokens of a Call or Subscript operator are mapped to
7402 // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
7403 // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
7404 for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
Nikolai Kosjar2a647e72019-05-08 13:19:29 +00007405 const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
7406 Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
Ivan Donchevskiib3ae2bc2018-08-23 09:48:11 +00007407 if (clang_Range_isNull(CXRefNameRange))
7408 break; // All ranges handled.
7409
7410 SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
7411 while (I < NumTokens) {
7412 const SourceLocation TokenLocation = GetTokenLoc(I);
7413 if (!TokenLocation.isValid())
7414 break;
7415
7416 // Adapt the end range, because LocationCompare() reports
7417 // RangeOverlap even for the not-inclusive end location.
7418 const SourceLocation fixedEnd =
7419 RefNameRange.getEnd().getLocWithOffset(-1);
7420 RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);
7421
7422 const RangeComparisonResult ComparisonResult =
7423 LocationCompare(SrcMgr, TokenLocation, RefNameRange);
7424
7425 if (ComparisonResult == RangeOverlap) {
7426 Cursors[I++] = Cursor;
7427 } else if (ComparisonResult == RangeBefore) {
7428 ++I; // Not relevant token, check next one.
7429 } else if (ComparisonResult == RangeAfter) {
7430 break; // All tokens updated for current range, check next.
7431 }
7432 }
7433 }
7434}
7435
Guy Benyei11169dd2012-12-18 14:30:41 +00007436static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
7437 CXCursor parent,
7438 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007439 return static_cast<AnnotateTokensWorker *>(client_data)
7440 ->Visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007441}
7442
7443static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
7444 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007445 return static_cast<AnnotateTokensWorker *>(client_data)
7446 ->postVisitChildren(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00007447}
7448
7449namespace {
7450
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007451/// Uses the macro expansions in the preprocessing record to find
Guy Benyei11169dd2012-12-18 14:30:41 +00007452/// and mark tokens that are macro arguments. This info is used by the
7453/// AnnotateTokensWorker.
7454class MarkMacroArgTokensVisitor {
7455 SourceManager &SM;
7456 CXToken *Tokens;
7457 unsigned NumTokens;
7458 unsigned CurIdx;
Michael Kruse7520cf02020-03-25 09:26:14 -05007459
Guy Benyei11169dd2012-12-18 14:30:41 +00007460public:
Michael Kruse7520cf02020-03-25 09:26:14 -05007461 MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
7462 unsigned numTokens)
7463 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00007464
7465 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
7466 if (cursor.kind != CXCursor_MacroExpansion)
7467 return CXChildVisit_Continue;
7468
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007469 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00007470 if (macroRange.getBegin() == macroRange.getEnd())
7471 return CXChildVisit_Continue; // it's not a function macro.
7472
7473 for (; CurIdx < NumTokens; ++CurIdx) {
7474 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
7475 macroRange.getBegin()))
7476 break;
7477 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007478
Guy Benyei11169dd2012-12-18 14:30:41 +00007479 if (CurIdx == NumTokens)
7480 return CXChildVisit_Break;
7481
7482 for (; CurIdx < NumTokens; ++CurIdx) {
7483 SourceLocation tokLoc = getTokenLoc(CurIdx);
7484 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
7485 break;
7486
7487 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
7488 }
7489
7490 if (CurIdx == NumTokens)
7491 return CXChildVisit_Break;
7492
7493 return CXChildVisit_Continue;
7494 }
7495
7496private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007497 CXToken &getTok(unsigned Idx) {
7498 assert(Idx < NumTokens);
7499 return Tokens[Idx];
7500 }
7501 const CXToken &getTok(unsigned Idx) const {
7502 assert(Idx < NumTokens);
7503 return Tokens[Idx];
7504 }
7505
Guy Benyei11169dd2012-12-18 14:30:41 +00007506 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007507 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00007508 }
7509
7510 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
7511 // The third field is reserved and currently not used. Use it here
7512 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00007513 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00007514 }
7515};
7516
7517} // end anonymous namespace
7518
7519static CXChildVisitResult
7520MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
7521 CXClientData client_data) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007522 return static_cast<MarkMacroArgTokensVisitor *>(client_data)
7523 ->visit(cursor, parent);
Guy Benyei11169dd2012-12-18 14:30:41 +00007524}
7525
Adrian Prantl9fc8faf2018-05-09 01:00:01 +00007526/// Used by \c annotatePreprocessorTokens.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007527/// \returns true if lexing was finished, false otherwise.
Michael Kruse7520cf02020-03-25 09:26:14 -05007528static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
7529 unsigned NumTokens) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007530 if (NextIdx >= NumTokens)
7531 return true;
7532
7533 ++NextIdx;
7534 Lex.LexFromRawLexer(Tok);
Alexander Kornienko1a9f1842015-12-28 15:24:08 +00007535 return Tok.is(tok::eof);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007536}
7537
Guy Benyei11169dd2012-12-18 14:30:41 +00007538static void annotatePreprocessorTokens(CXTranslationUnit TU,
7539 SourceRange RegionOfInterest,
Michael Kruse7520cf02020-03-25 09:26:14 -05007540 CXCursor *Cursors, CXToken *Tokens,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007541 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007542 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007543
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007544 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00007545 SourceManager &SourceMgr = CXXUnit->getSourceManager();
Michael Kruse7520cf02020-03-25 09:26:14 -05007546 std::pair<FileID, unsigned> BeginLocInfo =
7547 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
7548 std::pair<FileID, unsigned> EndLocInfo =
7549 SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00007550
7551 if (BeginLocInfo.first != EndLocInfo.first)
7552 return;
7553
7554 StringRef Buffer;
7555 bool Invalid = false;
7556 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
7557 if (Buffer.empty() || Invalid)
7558 return;
7559
7560 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
Michael Kruse7520cf02020-03-25 09:26:14 -05007561 CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
7562 Buffer.data() + BeginLocInfo.second, Buffer.end());
Guy Benyei11169dd2012-12-18 14:30:41 +00007563 Lex.SetCommentRetentionState(true);
Michael Kruse7520cf02020-03-25 09:26:14 -05007564
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007565 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00007566 // Lex tokens in raw mode until we hit the end of the range, to avoid
7567 // entering #includes or expanding macros.
7568 while (true) {
7569 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007570 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7571 break;
Michael Kruse7520cf02020-03-25 09:26:14 -05007572 unsigned TokIdx = NextIdx - 1;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007573 assert(Tok.getLocation() ==
Michael Kruse7520cf02020-03-25 09:26:14 -05007574 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
7575
Guy Benyei11169dd2012-12-18 14:30:41 +00007576 reprocess:
7577 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007578 // We have found a preprocessing directive. Annotate the tokens
7579 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00007580 //
7581 // FIXME: Some simple tests here could identify macro definitions and
7582 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007583
7584 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007585 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7586 break;
7587
Craig Topper69186e72014-06-08 08:38:04 +00007588 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00007589 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007590 if (lexNext(Lex, Tok, NextIdx, NumTokens))
7591 break;
7592
7593 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00007594 IdentifierInfo &II =
7595 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007596 SourceLocation MappedTokLoc =
7597 CXXUnit->mapLocationToPreamble(Tok.getLocation());
7598 MI = getMacroInfo(II, MappedTokLoc, TU);
7599 }
7600 }
7601
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007602 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00007603 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007604 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
7605 finished = true;
7606 break;
7607 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007608 // If we are in a macro definition, check if the token was ever a
7609 // macro name and annotate it if that's the case.
7610 if (MI) {
7611 SourceLocation SaveLoc = Tok.getLocation();
7612 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00007613 MacroDefinitionRecord *MacroDef =
7614 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007615 Tok.setLocation(SaveLoc);
7616 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00007617 Cursors[NextIdx - 1] =
7618 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007619 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007620 } while (!Tok.isAtStartOfLine());
7621
Michael Kruse7520cf02020-03-25 09:26:14 -05007622 unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007623 assert(TokIdx <= LastIdx);
7624 SourceLocation EndLoc =
7625 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
7626 CXCursor Cursor =
7627 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
7628
7629 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00007630 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Michael Kruse7520cf02020-03-25 09:26:14 -05007631
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007632 if (finished)
7633 break;
7634 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00007635 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007636 }
7637}
7638
7639// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007640static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
7641 CXToken *Tokens, unsigned NumTokens,
7642 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00007643 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00007644 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
7645 setThreadBackgroundPriority();
7646
7647 // Determine the region of interest, which contains all of the tokens.
7648 SourceRange RegionOfInterest;
7649 RegionOfInterest.setBegin(
Michael Kruse7520cf02020-03-25 09:26:14 -05007650 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
7651 RegionOfInterest.setEnd(cxloc::translateSourceLocation(
7652 clang_getTokenLocation(TU, Tokens[NumTokens - 1])));
Guy Benyei11169dd2012-12-18 14:30:41 +00007653
Guy Benyei11169dd2012-12-18 14:30:41 +00007654 // Relex the tokens within the source range to look for preprocessing
7655 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007656 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00007657
7658 // If begin location points inside a macro argument, set it to the expansion
7659 // location so we can have the full context when annotating semantically.
7660 {
7661 SourceManager &SM = CXXUnit->getSourceManager();
7662 SourceLocation Loc =
7663 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
7664 if (Loc.isMacroID())
7665 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
7666 }
7667
Guy Benyei11169dd2012-12-18 14:30:41 +00007668 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
7669 // Search and mark tokens that are macro argument expansions.
Michael Kruse7520cf02020-03-25 09:26:14 -05007670 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
7671 NumTokens);
7672 CursorVisitor MacroArgMarker(
7673 TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
7674 /*VisitPreprocessorLast=*/true,
7675 /*VisitIncludedEntities=*/false, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00007676 MacroArgMarker.visitPreprocessedEntitiesInRegion();
7677 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007678
Guy Benyei11169dd2012-12-18 14:30:41 +00007679 // Annotate all of the source locations in the region of interest that map to
7680 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007681 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Michael Kruse7520cf02020-03-25 09:26:14 -05007682
Guy Benyei11169dd2012-12-18 14:30:41 +00007683 // FIXME: We use a ridiculous stack size here because the data-recursion
7684 // algorithm uses a large stack frame than the non-data recursive version,
7685 // and AnnotationTokensWorker currently transforms the data-recursion
7686 // algorithm back into a traditional recursion by explicitly calling
7687 // VisitChildren(). We will need to remove this explicit recursive call.
7688 W.AnnotateTokens();
7689
7690 // If we ran into any entities that involve context-sensitive keywords,
7691 // take another pass through the tokens to mark them as such.
7692 if (W.hasContextSensitiveKeywords()) {
7693 for (unsigned I = 0; I != NumTokens; ++I) {
7694 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
7695 continue;
Michael Kruse7520cf02020-03-25 09:26:14 -05007696
Guy Benyei11169dd2012-12-18 14:30:41 +00007697 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
7698 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Michael Kruse7520cf02020-03-25 09:26:14 -05007699 if (const ObjCPropertyDecl *Property =
7700 dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007701 if (Property->getPropertyAttributesAsWritten() != 0 &&
7702 llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007703 .Case("readonly", true)
7704 .Case("assign", true)
7705 .Case("unsafe_unretained", true)
7706 .Case("readwrite", true)
7707 .Case("retain", true)
7708 .Case("copy", true)
7709 .Case("nonatomic", true)
7710 .Case("atomic", true)
7711 .Case("getter", true)
7712 .Case("setter", true)
7713 .Case("strong", true)
7714 .Case("weak", true)
7715 .Case("class", true)
7716 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007717 Tokens[I].int_data[0] = CXToken_Keyword;
7718 }
7719 continue;
7720 }
Michael Kruse7520cf02020-03-25 09:26:14 -05007721
Guy Benyei11169dd2012-12-18 14:30:41 +00007722 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
7723 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
7724 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
7725 if (llvm::StringSwitch<bool>(II->getName())
Michael Kruse7520cf02020-03-25 09:26:14 -05007726 .Case("in", true)
7727 .Case("out", true)
7728 .Case("inout", true)
7729 .Case("oneway", true)
7730 .Case("bycopy", true)
7731 .Case("byref", true)
7732 .Default(false))
Guy Benyei11169dd2012-12-18 14:30:41 +00007733 Tokens[I].int_data[0] = CXToken_Keyword;
7734 continue;
7735 }
7736
7737 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
7738 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
7739 Tokens[I].int_data[0] = CXToken_Keyword;
7740 continue;
7741 }
7742 }
7743 }
7744}
7745
Michael Kruse7520cf02020-03-25 09:26:14 -05007746void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
7747 unsigned NumTokens, CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007748 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007749 LOG_BAD_TU(TU);
7750 return;
7751 }
7752 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007753 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00007754 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007755 }
7756
7757 LOG_FUNC_SECTION {
7758 *Log << TU << ' ';
7759 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
Michael Kruse7520cf02020-03-25 09:26:14 -05007760 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007761 *Log << clang_getRange(bloc, eloc);
7762 }
Guy Benyei11169dd2012-12-18 14:30:41 +00007763
7764 // Any token we don't specifically annotate will have a NULL cursor.
7765 CXCursor C = clang_getNullCursor();
7766 for (unsigned I = 0; I != NumTokens; ++I)
7767 Cursors[I] = C;
7768
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007769 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00007770 if (!CXXUnit)
7771 return;
7772
7773 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007774
7775 auto AnnotateTokensImpl = [=]() {
7776 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
7777 };
Guy Benyei11169dd2012-12-18 14:30:41 +00007778 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007779 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007780 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
7781 }
7782}
7783
Guy Benyei11169dd2012-12-18 14:30:41 +00007784//===----------------------------------------------------------------------===//
7785// Operations for querying linkage of a cursor.
7786//===----------------------------------------------------------------------===//
7787
Guy Benyei11169dd2012-12-18 14:30:41 +00007788CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
7789 if (!clang_isDeclaration(cursor.kind))
7790 return CXLinkage_Invalid;
7791
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00007792 const Decl *D = cxcursor::getCursorDecl(cursor);
7793 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00007794 switch (ND->getLinkageInternal()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007795 case NoLinkage:
7796 case VisibleNoLinkage:
7797 return CXLinkage_NoLinkage;
7798 case ModuleInternalLinkage:
7799 case InternalLinkage:
7800 return CXLinkage_Internal;
7801 case UniqueExternalLinkage:
7802 return CXLinkage_UniqueExternal;
7803 case ModuleLinkage:
7804 case ExternalLinkage:
7805 return CXLinkage_External;
Guy Benyei11169dd2012-12-18 14:30:41 +00007806 };
7807
7808 return CXLinkage_Invalid;
7809}
Guy Benyei11169dd2012-12-18 14:30:41 +00007810
7811//===----------------------------------------------------------------------===//
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007812// Operations for querying visibility of a cursor.
7813//===----------------------------------------------------------------------===//
7814
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007815CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
7816 if (!clang_isDeclaration(cursor.kind))
7817 return CXVisibility_Invalid;
7818
7819 const Decl *D = cxcursor::getCursorDecl(cursor);
7820 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
7821 switch (ND->getVisibility()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007822 case HiddenVisibility:
7823 return CXVisibility_Hidden;
7824 case ProtectedVisibility:
7825 return CXVisibility_Protected;
7826 case DefaultVisibility:
7827 return CXVisibility_Default;
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007828 };
7829
7830 return CXVisibility_Invalid;
7831}
Ehsan Akhgarib743de72016-05-31 15:55:51 +00007832
7833//===----------------------------------------------------------------------===//
Guy Benyei11169dd2012-12-18 14:30:41 +00007834// Operations for querying language of a cursor.
7835//===----------------------------------------------------------------------===//
7836
7837static CXLanguageKind getDeclLanguage(const Decl *D) {
7838 if (!D)
7839 return CXLanguage_C;
7840
7841 switch (D->getKind()) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007842 default:
7843 break;
7844 case Decl::ImplicitParam:
7845 case Decl::ObjCAtDefsField:
7846 case Decl::ObjCCategory:
7847 case Decl::ObjCCategoryImpl:
7848 case Decl::ObjCCompatibleAlias:
7849 case Decl::ObjCImplementation:
7850 case Decl::ObjCInterface:
7851 case Decl::ObjCIvar:
7852 case Decl::ObjCMethod:
7853 case Decl::ObjCProperty:
7854 case Decl::ObjCPropertyImpl:
7855 case Decl::ObjCProtocol:
7856 case Decl::ObjCTypeParam:
7857 return CXLanguage_ObjC;
7858 case Decl::CXXConstructor:
7859 case Decl::CXXConversion:
7860 case Decl::CXXDestructor:
7861 case Decl::CXXMethod:
7862 case Decl::CXXRecord:
7863 case Decl::ClassTemplate:
7864 case Decl::ClassTemplatePartialSpecialization:
7865 case Decl::ClassTemplateSpecialization:
7866 case Decl::Friend:
7867 case Decl::FriendTemplate:
7868 case Decl::FunctionTemplate:
7869 case Decl::LinkageSpec:
7870 case Decl::Namespace:
7871 case Decl::NamespaceAlias:
7872 case Decl::NonTypeTemplateParm:
7873 case Decl::StaticAssert:
7874 case Decl::TemplateTemplateParm:
7875 case Decl::TemplateTypeParm:
7876 case Decl::UnresolvedUsingTypename:
7877 case Decl::UnresolvedUsingValue:
7878 case Decl::Using:
7879 case Decl::UsingDirective:
7880 case Decl::UsingShadow:
7881 return CXLanguage_CPlusPlus;
Guy Benyei11169dd2012-12-18 14:30:41 +00007882 }
7883
7884 return CXLanguage_C;
7885}
7886
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007887static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
7888 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00007889 return CXAvailability_NotAvailable;
Michael Kruse7520cf02020-03-25 09:26:14 -05007890
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007891 switch (D->getAvailability()) {
7892 case AR_Available:
7893 case AR_NotYetIntroduced:
7894 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00007895 return getCursorAvailabilityForDecl(
7896 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007897 return CXAvailability_Available;
7898
7899 case AR_Deprecated:
7900 return CXAvailability_Deprecated;
7901
7902 case AR_Unavailable:
7903 return CXAvailability_NotAvailable;
7904 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00007905
7906 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007907}
7908
Guy Benyei11169dd2012-12-18 14:30:41 +00007909enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
7910 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007911 if (const Decl *D = cxcursor::getCursorDecl(cursor))
7912 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00007913
7914 return CXAvailability_Available;
7915}
7916
7917static CXVersion convertVersion(VersionTuple In) {
Michael Kruse7520cf02020-03-25 09:26:14 -05007918 CXVersion Out = {-1, -1, -1};
Guy Benyei11169dd2012-12-18 14:30:41 +00007919 if (In.empty())
7920 return Out;
7921
7922 Out.Major = In.getMajor();
Michael Kruse7520cf02020-03-25 09:26:14 -05007923
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007924 Optional<unsigned> Minor = In.getMinor();
7925 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007926 Out.Minor = *Minor;
7927 else
7928 return Out;
7929
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00007930 Optional<unsigned> Subminor = In.getSubminor();
7931 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00007932 Out.Subminor = *Subminor;
Michael Kruse7520cf02020-03-25 09:26:14 -05007933
Guy Benyei11169dd2012-12-18 14:30:41 +00007934 return Out;
7935}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007936
Alex Lorenz1345ea22017-06-12 19:06:30 +00007937static void getCursorPlatformAvailabilityForDecl(
7938 const Decl *D, int *always_deprecated, CXString *deprecated_message,
7939 int *always_unavailable, CXString *unavailable_message,
7940 SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007941 bool HadAvailAttr = false;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007942 for (auto A : D->attrs()) {
7943 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007944 HadAvailAttr = true;
7945 if (always_deprecated)
7946 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00007947 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007948 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007949 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00007950 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007951 continue;
7952 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007953
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007954 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007955 HadAvailAttr = true;
7956 if (always_unavailable)
7957 *always_unavailable = 1;
7958 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00007959 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007960 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
7961 }
7962 continue;
7963 }
Alex Lorenz1345ea22017-06-12 19:06:30 +00007964
Aaron Ballmanb97112e2014-03-08 22:19:01 +00007965 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Alex Lorenz1345ea22017-06-12 19:06:30 +00007966 AvailabilityAttrs.push_back(Avail);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007967 HadAvailAttr = true;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00007968 }
7969 }
7970
7971 if (!HadAvailAttr)
7972 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
7973 return getCursorPlatformAvailabilityForDecl(
Alex Lorenz1345ea22017-06-12 19:06:30 +00007974 cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
7975 deprecated_message, always_unavailable, unavailable_message,
7976 AvailabilityAttrs);
7977
7978 if (AvailabilityAttrs.empty())
7979 return;
7980
Michael Kruse7520cf02020-03-25 09:26:14 -05007981 llvm::sort(
7982 AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7983 return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
7984 });
Alex Lorenz1345ea22017-06-12 19:06:30 +00007985 ASTContext &Ctx = D->getASTContext();
7986 auto It = std::unique(
7987 AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
7988 [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
7989 if (LHS->getPlatform() != RHS->getPlatform())
7990 return false;
7991
7992 if (LHS->getIntroduced() == RHS->getIntroduced() &&
7993 LHS->getDeprecated() == RHS->getDeprecated() &&
7994 LHS->getObsoleted() == RHS->getObsoleted() &&
7995 LHS->getMessage() == RHS->getMessage() &&
7996 LHS->getReplacement() == RHS->getReplacement())
7997 return true;
7998
7999 if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
8000 (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
8001 (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
8002 return false;
8003
8004 if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
8005 LHS->setIntroduced(Ctx, RHS->getIntroduced());
8006
8007 if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
8008 LHS->setDeprecated(Ctx, RHS->getDeprecated());
8009 if (LHS->getMessage().empty())
8010 LHS->setMessage(Ctx, RHS->getMessage());
8011 if (LHS->getReplacement().empty())
8012 LHS->setReplacement(Ctx, RHS->getReplacement());
8013 }
8014
8015 if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
8016 LHS->setObsoleted(Ctx, RHS->getObsoleted());
8017 if (LHS->getMessage().empty())
8018 LHS->setMessage(Ctx, RHS->getMessage());
8019 if (LHS->getReplacement().empty())
8020 LHS->setReplacement(Ctx, RHS->getReplacement());
8021 }
8022
8023 return true;
8024 });
8025 AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008026}
8027
Alex Lorenz1345ea22017-06-12 19:06:30 +00008028int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
Guy Benyei11169dd2012-12-18 14:30:41 +00008029 CXString *deprecated_message,
8030 int *always_unavailable,
8031 CXString *unavailable_message,
8032 CXPlatformAvailability *availability,
8033 int availability_size) {
8034 if (always_deprecated)
8035 *always_deprecated = 0;
8036 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008037 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00008038 if (always_unavailable)
8039 *always_unavailable = 0;
8040 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008041 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008042
Guy Benyei11169dd2012-12-18 14:30:41 +00008043 if (!clang_isDeclaration(cursor.kind))
8044 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008045
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008046 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00008047 if (!D)
8048 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00008049
Alex Lorenz1345ea22017-06-12 19:06:30 +00008050 SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
8051 getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
8052 always_unavailable, unavailable_message,
8053 AvailabilityAttrs);
8054 for (const auto &Avail :
8055 llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
8056 .take_front(availability_size))) {
8057 availability[Avail.index()].Platform =
8058 cxstring::createDup(Avail.value()->getPlatform()->getName());
8059 availability[Avail.index()].Introduced =
8060 convertVersion(Avail.value()->getIntroduced());
8061 availability[Avail.index()].Deprecated =
8062 convertVersion(Avail.value()->getDeprecated());
8063 availability[Avail.index()].Obsoleted =
8064 convertVersion(Avail.value()->getObsoleted());
8065 availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
8066 availability[Avail.index()].Message =
8067 cxstring::createDup(Avail.value()->getMessage());
8068 }
8069
8070 return AvailabilityAttrs.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008071}
Alex Lorenz1345ea22017-06-12 19:06:30 +00008072
Guy Benyei11169dd2012-12-18 14:30:41 +00008073void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
8074 clang_disposeString(availability->Platform);
8075 clang_disposeString(availability->Message);
8076}
8077
8078CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
8079 if (clang_isDeclaration(cursor.kind))
8080 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
8081
8082 return CXLanguage_Invalid;
8083}
8084
Saleem Abdulrasool50bc5652017-09-13 02:15:09 +00008085CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
8086 const Decl *D = cxcursor::getCursorDecl(cursor);
8087 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8088 switch (VD->getTLSKind()) {
8089 case VarDecl::TLS_None:
8090 return CXTLS_None;
8091 case VarDecl::TLS_Dynamic:
8092 return CXTLS_Dynamic;
8093 case VarDecl::TLS_Static:
8094 return CXTLS_Static;
8095 }
8096 }
8097
8098 return CXTLS_None;
8099}
8100
Michael Kruse7520cf02020-03-25 09:26:14 -05008101/// If the given cursor is the "templated" declaration
8102/// describing a class or function template, return the class or
8103/// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008104static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008105 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00008106 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008107
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008108 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008109 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
8110 return FunTmpl;
8111
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008112 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00008113 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
8114 return ClassTmpl;
8115
8116 return D;
8117}
8118
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008119enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
8120 StorageClass sc = SC_None;
8121 const Decl *D = getCursorDecl(C);
8122 if (D) {
8123 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
8124 sc = FD->getStorageClass();
8125 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
8126 sc = VD->getStorageClass();
8127 } else {
8128 return CX_SC_Invalid;
8129 }
8130 } else {
8131 return CX_SC_Invalid;
8132 }
8133 switch (sc) {
8134 case SC_None:
8135 return CX_SC_None;
8136 case SC_Extern:
8137 return CX_SC_Extern;
8138 case SC_Static:
8139 return CX_SC_Static;
8140 case SC_PrivateExtern:
8141 return CX_SC_PrivateExtern;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008142 case SC_Auto:
8143 return CX_SC_Auto;
8144 case SC_Register:
8145 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008146 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00008147 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00008148}
8149
Guy Benyei11169dd2012-12-18 14:30:41 +00008150CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
8151 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008152 if (const Decl *D = getCursorDecl(cursor)) {
8153 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008154 if (!DC)
8155 return clang_getNullCursor();
8156
Michael Kruse7520cf02020-03-25 09:26:14 -05008157 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008158 getCursorTU(cursor));
8159 }
8160 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008161
Guy Benyei11169dd2012-12-18 14:30:41 +00008162 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008163 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00008164 return MakeCXCursor(D, getCursorTU(cursor));
8165 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008166
Guy Benyei11169dd2012-12-18 14:30:41 +00008167 return clang_getNullCursor();
8168}
8169
8170CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
8171 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008172 if (const Decl *D = getCursorDecl(cursor)) {
8173 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00008174 if (!DC)
8175 return clang_getNullCursor();
8176
Michael Kruse7520cf02020-03-25 09:26:14 -05008177 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
Guy Benyei11169dd2012-12-18 14:30:41 +00008178 getCursorTU(cursor));
8179 }
8180 }
8181
Michael Kruse7520cf02020-03-25 09:26:14 -05008182 // FIXME: Note that we can't easily compute the lexical context of a
Guy Benyei11169dd2012-12-18 14:30:41 +00008183 // statement or expression, so we return nothing.
8184 return clang_getNullCursor();
8185}
8186
8187CXFile clang_getIncludedFile(CXCursor cursor) {
8188 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00008189 return nullptr;
8190
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008191 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00008192 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00008193}
8194
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008195unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
8196 if (C.kind != CXCursor_ObjCPropertyDecl)
8197 return CXObjCPropertyAttr_noattr;
8198
8199 unsigned Result = CXObjCPropertyAttr_noattr;
8200 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008201 ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008202
Michael Kruse7520cf02020-03-25 09:26:14 -05008203#define SET_CXOBJCPROP_ATTR(A) \
Puyan Lotfi9721fbf2020-04-23 02:20:56 -04008204 if (Attr & ObjCPropertyAttribute::kind_##A) \
Michael Kruse7520cf02020-03-25 09:26:14 -05008205 Result |= CXObjCPropertyAttr_##A
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008206 SET_CXOBJCPROP_ATTR(readonly);
8207 SET_CXOBJCPROP_ATTR(getter);
8208 SET_CXOBJCPROP_ATTR(assign);
8209 SET_CXOBJCPROP_ATTR(readwrite);
8210 SET_CXOBJCPROP_ATTR(retain);
8211 SET_CXOBJCPROP_ATTR(copy);
8212 SET_CXOBJCPROP_ATTR(nonatomic);
8213 SET_CXOBJCPROP_ATTR(setter);
8214 SET_CXOBJCPROP_ATTR(atomic);
8215 SET_CXOBJCPROP_ATTR(weak);
8216 SET_CXOBJCPROP_ATTR(strong);
8217 SET_CXOBJCPROP_ATTR(unsafe_unretained);
Manman Ren04fd4d82016-05-31 23:22:04 +00008218 SET_CXOBJCPROP_ATTR(class);
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00008219#undef SET_CXOBJCPROP_ATTR
8220
8221 return Result;
8222}
8223
Michael Wu6e88f532018-08-03 05:38:29 +00008224CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
8225 if (C.kind != CXCursor_ObjCPropertyDecl)
8226 return cxstring::createNull();
8227
8228 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8229 Selector sel = PD->getGetterName();
8230 if (sel.isNull())
8231 return cxstring::createNull();
8232
8233 return cxstring::createDup(sel.getAsString());
8234}
8235
8236CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
8237 if (C.kind != CXCursor_ObjCPropertyDecl)
8238 return cxstring::createNull();
8239
8240 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
8241 Selector sel = PD->getSetterName();
8242 if (sel.isNull())
8243 return cxstring::createNull();
8244
8245 return cxstring::createDup(sel.getAsString());
8246}
8247
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008248unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
8249 if (!clang_isDeclaration(C.kind))
8250 return CXObjCDeclQualifier_None;
8251
8252 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
8253 const Decl *D = getCursorDecl(C);
8254 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8255 QT = MD->getObjCDeclQualifier();
8256 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
8257 QT = PD->getObjCDeclQualifier();
8258 if (QT == Decl::OBJC_TQ_None)
8259 return CXObjCDeclQualifier_None;
8260
8261 unsigned Result = CXObjCDeclQualifier_None;
Michael Kruse7520cf02020-03-25 09:26:14 -05008262 if (QT & Decl::OBJC_TQ_In)
8263 Result |= CXObjCDeclQualifier_In;
8264 if (QT & Decl::OBJC_TQ_Inout)
8265 Result |= CXObjCDeclQualifier_Inout;
8266 if (QT & Decl::OBJC_TQ_Out)
8267 Result |= CXObjCDeclQualifier_Out;
8268 if (QT & Decl::OBJC_TQ_Bycopy)
8269 Result |= CXObjCDeclQualifier_Bycopy;
8270 if (QT & Decl::OBJC_TQ_Byref)
8271 Result |= CXObjCDeclQualifier_Byref;
8272 if (QT & Decl::OBJC_TQ_Oneway)
8273 Result |= CXObjCDeclQualifier_Oneway;
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00008274
8275 return Result;
8276}
8277
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00008278unsigned clang_Cursor_isObjCOptional(CXCursor C) {
8279 if (!clang_isDeclaration(C.kind))
8280 return 0;
8281
8282 const Decl *D = getCursorDecl(C);
8283 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
8284 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
8285 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8286 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
8287
8288 return 0;
8289}
8290
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00008291unsigned clang_Cursor_isVariadic(CXCursor C) {
8292 if (!clang_isDeclaration(C.kind))
8293 return 0;
8294
8295 const Decl *D = getCursorDecl(C);
8296 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
8297 return FD->isVariadic();
8298 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
8299 return MD->isVariadic();
8300
8301 return 0;
8302}
8303
Michael Kruse7520cf02020-03-25 09:26:14 -05008304unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
8305 CXString *definedIn,
8306 unsigned *isGenerated) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008307 if (!clang_isDeclaration(C.kind))
8308 return 0;
8309
8310 const Decl *D = getCursorDecl(C);
8311
Argyrios Kyrtzidis11d70482017-05-20 04:11:33 +00008312 if (auto *attr = D->getExternalSourceSymbolAttr()) {
Argyrios Kyrtzidis0381cc72017-05-10 15:10:36 +00008313 if (language)
8314 *language = cxstring::createDup(attr->getLanguage());
8315 if (definedIn)
8316 *definedIn = cxstring::createDup(attr->getDefinedIn());
8317 if (isGenerated)
8318 *isGenerated = attr->getGeneratedDeclaration();
8319 return 1;
8320 }
8321 return 0;
8322}
8323
Guy Benyei11169dd2012-12-18 14:30:41 +00008324CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
8325 if (!clang_isDeclaration(C.kind))
8326 return clang_getNullRange();
8327
8328 const Decl *D = getCursorDecl(C);
8329 ASTContext &Context = getCursorContext(C);
8330 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8331 if (!RC)
8332 return clang_getNullRange();
8333
8334 return cxloc::translateSourceRange(Context, RC->getSourceRange());
8335}
8336
8337CXString clang_Cursor_getRawCommentText(CXCursor C) {
8338 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008339 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008340
8341 const Decl *D = getCursorDecl(C);
8342 ASTContext &Context = getCursorContext(C);
8343 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
Michael Kruse7520cf02020-03-25 09:26:14 -05008344 StringRef RawText =
8345 RC ? RC->getRawText(Context.getSourceManager()) : StringRef();
Guy Benyei11169dd2012-12-18 14:30:41 +00008346
8347 // Don't duplicate the string because RawText points directly into source
8348 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008349 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008350}
8351
8352CXString clang_Cursor_getBriefCommentText(CXCursor C) {
8353 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008354 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008355
8356 const Decl *D = getCursorDecl(C);
8357 const ASTContext &Context = getCursorContext(C);
8358 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
8359
8360 if (RC) {
8361 StringRef BriefText = RC->getBriefText(Context);
8362
8363 // Don't duplicate the string because RawComment ensures that this memory
8364 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008365 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00008366 }
8367
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00008368 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00008369}
8370
Guy Benyei11169dd2012-12-18 14:30:41 +00008371CXModule clang_Cursor_getModule(CXCursor C) {
8372 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008373 if (const ImportDecl *ImportD =
8374 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00008375 return ImportD->getImportedModule();
8376 }
8377
Craig Topper69186e72014-06-08 08:38:04 +00008378 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008379}
8380
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008381CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
8382 if (isNotUsableTU(TU)) {
8383 LOG_BAD_TU(TU);
8384 return nullptr;
8385 }
8386 if (!File)
8387 return nullptr;
8388 FileEntry *FE = static_cast<FileEntry *>(File);
Michael Kruse7520cf02020-03-25 09:26:14 -05008389
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008390 ASTUnit &Unit = *cxtu::getASTUnit(TU);
8391 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
8392 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
Michael Kruse7520cf02020-03-25 09:26:14 -05008393
Richard Smithfeb54b62014-10-23 02:01:19 +00008394 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00008395}
8396
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008397CXFile clang_Module_getASTFile(CXModule CXMod) {
8398 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008399 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008400 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00008401 return const_cast<FileEntry *>(Mod->getASTFile());
8402}
8403
Guy Benyei11169dd2012-12-18 14:30:41 +00008404CXModule clang_Module_getParent(CXModule CXMod) {
8405 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008406 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008407 Module *Mod = static_cast<Module *>(CXMod);
Guy Benyei11169dd2012-12-18 14:30:41 +00008408 return Mod->Parent;
8409}
8410
8411CXString clang_Module_getName(CXModule CXMod) {
8412 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008413 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008414 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008415 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00008416}
8417
8418CXString clang_Module_getFullName(CXModule CXMod) {
8419 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00008420 return cxstring::createEmpty();
Michael Kruse7520cf02020-03-25 09:26:14 -05008421 Module *Mod = static_cast<Module *>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00008422 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00008423}
8424
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008425int clang_Module_isSystem(CXModule CXMod) {
8426 if (!CXMod)
8427 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008428 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00008429 return Mod->IsSystem;
8430}
8431
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008432unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
8433 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008434 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008435 LOG_BAD_TU(TU);
8436 return 0;
8437 }
8438 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00008439 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008440 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008441 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
8442 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8443 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00008444}
8445
Michael Kruse7520cf02020-03-25 09:26:14 -05008446CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
8447 unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008448 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008449 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00008450 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008451 }
8452 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00008453 return nullptr;
Michael Kruse7520cf02020-03-25 09:26:14 -05008454 Module *Mod = static_cast<Module *>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008455 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00008456
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00008457 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
8458 if (Index < TopHeaders.size())
8459 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00008460
Craig Topper69186e72014-06-08 08:38:04 +00008461 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008462}
8463
Guy Benyei11169dd2012-12-18 14:30:41 +00008464//===----------------------------------------------------------------------===//
8465// C++ AST instrospection.
8466//===----------------------------------------------------------------------===//
8467
Jonathan Coe29565352016-04-27 12:48:25 +00008468unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
8469 if (!clang_isDeclaration(C.kind))
8470 return 0;
8471
8472 const Decl *D = cxcursor::getCursorDecl(C);
8473 const CXXConstructorDecl *Constructor =
8474 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8475 return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
8476}
8477
8478unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
8479 if (!clang_isDeclaration(C.kind))
8480 return 0;
8481
8482 const Decl *D = cxcursor::getCursorDecl(C);
8483 const CXXConstructorDecl *Constructor =
8484 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8485 return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
8486}
8487
8488unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
8489 if (!clang_isDeclaration(C.kind))
8490 return 0;
8491
8492 const Decl *D = cxcursor::getCursorDecl(C);
8493 const CXXConstructorDecl *Constructor =
8494 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8495 return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
8496}
8497
8498unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
8499 if (!clang_isDeclaration(C.kind))
8500 return 0;
8501
8502 const Decl *D = cxcursor::getCursorDecl(C);
8503 const CXXConstructorDecl *Constructor =
8504 D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
8505 // Passing 'false' excludes constructors marked 'explicit'.
8506 return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
8507}
8508
Saleem Abdulrasool6ea75db2015-10-27 15:50:22 +00008509unsigned clang_CXXField_isMutable(CXCursor C) {
8510 if (!clang_isDeclaration(C.kind))
8511 return 0;
8512
8513 if (const auto D = cxcursor::getCursorDecl(C))
8514 if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
8515 return FD->isMutable() ? 1 : 0;
8516 return 0;
8517}
8518
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008519unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
8520 if (!clang_isDeclaration(C.kind))
8521 return 0;
8522
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008523 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008524 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008525 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00008526 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
8527}
8528
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008529unsigned clang_CXXMethod_isConst(CXCursor C) {
8530 if (!clang_isDeclaration(C.kind))
8531 return 0;
8532
8533 const Decl *D = cxcursor::getCursorDecl(C);
8534 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008535 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Anastasia Stulovac61eaa52019-01-28 11:37:49 +00008536 return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00008537}
8538
Jonathan Coe29565352016-04-27 12:48:25 +00008539unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
8540 if (!clang_isDeclaration(C.kind))
8541 return 0;
8542
8543 const Decl *D = cxcursor::getCursorDecl(C);
8544 const CXXMethodDecl *Method =
8545 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
8546 return (Method && Method->isDefaulted()) ? 1 : 0;
8547}
8548
Guy Benyei11169dd2012-12-18 14:30:41 +00008549unsigned clang_CXXMethod_isStatic(CXCursor C) {
8550 if (!clang_isDeclaration(C.kind))
8551 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008552
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008553 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008554 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008555 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008556 return (Method && Method->isStatic()) ? 1 : 0;
8557}
8558
8559unsigned clang_CXXMethod_isVirtual(CXCursor C) {
8560 if (!clang_isDeclaration(C.kind))
8561 return 0;
Michael Kruse7520cf02020-03-25 09:26:14 -05008562
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00008563 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00008564 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00008565 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00008566 return (Method && Method->isVirtual()) ? 1 : 0;
8567}
Guy Benyei11169dd2012-12-18 14:30:41 +00008568
Alex Lorenz34ccadc2017-12-14 22:01:50 +00008569unsigned clang_CXXRecord_isAbstract(CXCursor C) {
8570 if (!clang_isDeclaration(C.kind))
8571 return 0;
8572
8573 const auto *D = cxcursor::getCursorDecl(C);
8574 const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
8575 if (RD)
8576 RD = RD->getDefinition();
8577 return (RD && RD->isAbstract()) ? 1 : 0;
8578}
8579
Alex Lorenzff7f42e2017-07-12 11:35:11 +00008580unsigned clang_EnumDecl_isScoped(CXCursor C) {
8581 if (!clang_isDeclaration(C.kind))
8582 return 0;
8583
8584 const Decl *D = cxcursor::getCursorDecl(C);
8585 auto *Enum = dyn_cast_or_null<EnumDecl>(D);
8586 return (Enum && Enum->isScoped()) ? 1 : 0;
8587}
8588
Guy Benyei11169dd2012-12-18 14:30:41 +00008589//===----------------------------------------------------------------------===//
8590// Attribute introspection.
8591//===----------------------------------------------------------------------===//
8592
Guy Benyei11169dd2012-12-18 14:30:41 +00008593CXType clang_getIBOutletCollectionType(CXCursor C) {
8594 if (C.kind != CXCursor_IBOutletCollectionAttr)
8595 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
Michael Kruse7520cf02020-03-25 09:26:14 -05008596
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00008597 const IBOutletCollectionAttr *A =
Michael Kruse7520cf02020-03-25 09:26:14 -05008598 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
8599
8600 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00008601}
Guy Benyei11169dd2012-12-18 14:30:41 +00008602
8603//===----------------------------------------------------------------------===//
8604// Inspecting memory usage.
8605//===----------------------------------------------------------------------===//
8606
8607typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
8608
8609static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
Michael Kruse7520cf02020-03-25 09:26:14 -05008610 enum CXTUResourceUsageKind k,
8611 unsigned long amount) {
8612 CXTUResourceUsageEntry entry = {k, amount};
Guy Benyei11169dd2012-12-18 14:30:41 +00008613 entries.push_back(entry);
8614}
8615
Guy Benyei11169dd2012-12-18 14:30:41 +00008616const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
8617 const char *str = "";
8618 switch (kind) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008619 case CXTUResourceUsage_AST:
8620 str = "ASTContext: expressions, declarations, and types";
8621 break;
8622 case CXTUResourceUsage_Identifiers:
8623 str = "ASTContext: identifiers";
8624 break;
8625 case CXTUResourceUsage_Selectors:
8626 str = "ASTContext: selectors";
8627 break;
8628 case CXTUResourceUsage_GlobalCompletionResults:
8629 str = "Code completion: cached global results";
8630 break;
8631 case CXTUResourceUsage_SourceManagerContentCache:
8632 str = "SourceManager: content cache allocator";
8633 break;
8634 case CXTUResourceUsage_AST_SideTables:
8635 str = "ASTContext: side tables";
8636 break;
8637 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
8638 str = "SourceManager: malloc'ed memory buffers";
8639 break;
8640 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
8641 str = "SourceManager: mmap'ed memory buffers";
8642 break;
8643 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
8644 str = "ExternalASTSource: malloc'ed memory buffers";
8645 break;
8646 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
8647 str = "ExternalASTSource: mmap'ed memory buffers";
8648 break;
8649 case CXTUResourceUsage_Preprocessor:
8650 str = "Preprocessor: malloc'ed memory";
8651 break;
8652 case CXTUResourceUsage_PreprocessingRecord:
8653 str = "Preprocessor: PreprocessingRecord";
8654 break;
8655 case CXTUResourceUsage_SourceManager_DataStructures:
8656 str = "SourceManager: data structures and tables";
8657 break;
8658 case CXTUResourceUsage_Preprocessor_HeaderSearch:
8659 str = "Preprocessor: header search tables";
8660 break;
Guy Benyei11169dd2012-12-18 14:30:41 +00008661 }
8662 return str;
8663}
8664
8665CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008666 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008667 LOG_BAD_TU(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008668 CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
Guy Benyei11169dd2012-12-18 14:30:41 +00008669 return usage;
8670 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008671
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008672 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00008673 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00008674 ASTContext &astContext = astUnit->getASTContext();
Michael Kruse7520cf02020-03-25 09:26:14 -05008675
Guy Benyei11169dd2012-12-18 14:30:41 +00008676 // How much memory is used by AST nodes and types?
Michael Kruse7520cf02020-03-25 09:26:14 -05008677 createCXTUResourceUsageEntry(
8678 *entries, CXTUResourceUsage_AST,
8679 (unsigned long)astContext.getASTAllocatedMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008680
8681 // How much memory is used by identifiers?
Michael Kruse7520cf02020-03-25 09:26:14 -05008682 createCXTUResourceUsageEntry(
8683 *entries, CXTUResourceUsage_Identifiers,
8684 (unsigned long)astContext.Idents.getAllocator().getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008685
8686 // How much memory is used for selectors?
Michael Kruse7520cf02020-03-25 09:26:14 -05008687 createCXTUResourceUsageEntry(
8688 *entries, CXTUResourceUsage_Selectors,
8689 (unsigned long)astContext.Selectors.getTotalMemory());
8690
Guy Benyei11169dd2012-12-18 14:30:41 +00008691 // How much memory is used by ASTContext's side tables?
Michael Kruse7520cf02020-03-25 09:26:14 -05008692 createCXTUResourceUsageEntry(
8693 *entries, CXTUResourceUsage_AST_SideTables,
8694 (unsigned long)astContext.getSideTableAllocatedMemory());
8695
Guy Benyei11169dd2012-12-18 14:30:41 +00008696 // How much memory is used for caching global code completion results?
8697 unsigned long completionBytes = 0;
8698 if (GlobalCodeCompletionAllocator *completionAllocator =
Michael Kruse7520cf02020-03-25 09:26:14 -05008699 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00008700 completionBytes = completionAllocator->getTotalMemory();
8701 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008702 createCXTUResourceUsageEntry(
8703 *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);
8704
Guy Benyei11169dd2012-12-18 14:30:41 +00008705 // How much memory is being used by SourceManager's content cache?
Michael Kruse7520cf02020-03-25 09:26:14 -05008706 createCXTUResourceUsageEntry(
8707 *entries, CXTUResourceUsage_SourceManagerContentCache,
8708 (unsigned long)astContext.getSourceManager().getContentCacheSize());
8709
Guy Benyei11169dd2012-12-18 14:30:41 +00008710 // How much memory is being used by the MemoryBuffer's in SourceManager?
8711 const SourceManager::MemoryBufferSizes &srcBufs =
Michael Kruse7520cf02020-03-25 09:26:14 -05008712 astUnit->getSourceManager().getMemoryBufferSizes();
8713
Guy Benyei11169dd2012-12-18 14:30:41 +00008714 createCXTUResourceUsageEntry(*entries,
8715 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008716 (unsigned long)srcBufs.malloc_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008717 createCXTUResourceUsageEntry(*entries,
8718 CXTUResourceUsage_SourceManager_Membuffer_MMap,
Michael Kruse7520cf02020-03-25 09:26:14 -05008719 (unsigned long)srcBufs.mmap_bytes);
8720 createCXTUResourceUsageEntry(
8721 *entries, CXTUResourceUsage_SourceManager_DataStructures,
8722 (unsigned long)astContext.getSourceManager().getDataStructureSizes());
8723
Guy Benyei11169dd2012-12-18 14:30:41 +00008724 // How much memory is being used by the ExternalASTSource?
8725 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
8726 const ExternalASTSource::MemoryBufferSizes &sizes =
Michael Kruse7520cf02020-03-25 09:26:14 -05008727 esrc->getMemoryBufferSizes();
8728
8729 createCXTUResourceUsageEntry(
8730 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
8731 (unsigned long)sizes.malloc_bytes);
8732 createCXTUResourceUsageEntry(
8733 *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
8734 (unsigned long)sizes.mmap_bytes);
Guy Benyei11169dd2012-12-18 14:30:41 +00008735 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008736
Guy Benyei11169dd2012-12-18 14:30:41 +00008737 // How much memory is being used by the Preprocessor?
8738 Preprocessor &pp = astUnit->getPreprocessor();
Michael Kruse7520cf02020-03-25 09:26:14 -05008739 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
Guy Benyei11169dd2012-12-18 14:30:41 +00008740 pp.getTotalMemory());
Michael Kruse7520cf02020-03-25 09:26:14 -05008741
Guy Benyei11169dd2012-12-18 14:30:41 +00008742 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
8743 createCXTUResourceUsageEntry(*entries,
8744 CXTUResourceUsage_PreprocessingRecord,
Michael Kruse7520cf02020-03-25 09:26:14 -05008745 pRec->getTotalMemory());
Guy Benyei11169dd2012-12-18 14:30:41 +00008746 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008747
Guy Benyei11169dd2012-12-18 14:30:41 +00008748 createCXTUResourceUsageEntry(*entries,
8749 CXTUResourceUsage_Preprocessor_HeaderSearch,
8750 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00008751
Michael Kruse7520cf02020-03-25 09:26:14 -05008752 CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
8753 !entries->empty() ? &(*entries)[0] : nullptr};
Eric Fiseliere95fc442016-11-14 07:03:50 +00008754 (void)entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00008755 return usage;
8756}
8757
8758void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
8759 if (usage.data)
Michael Kruse7520cf02020-03-25 09:26:14 -05008760 delete (MemUsageEntries *)usage.data;
Guy Benyei11169dd2012-12-18 14:30:41 +00008761}
8762
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008763CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
8764 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008765 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00008766 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008767
Dmitri Gribenko852d6222014-02-11 15:02:48 +00008768 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00008769 LOG_BAD_TU(TU);
8770 return skipped;
8771 }
8772
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008773 if (!file)
8774 return skipped;
8775
8776 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008777 PreprocessingRecord *ppRec =
8778 astUnit->getPreprocessor().getPreprocessingRecord();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008779 if (!ppRec)
8780 return skipped;
8781
8782 ASTContext &Ctx = astUnit->getASTContext();
8783 SourceManager &sm = Ctx.getSourceManager();
8784 FileEntry *fileEntry = static_cast<FileEntry *>(file);
8785 FileID wantedFileID = sm.translateFile(fileEntry);
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008786 bool isMainFile = wantedFileID == sm.getMainFileID();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008787
8788 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8789 std::vector<SourceRange> wantedRanges;
Michael Kruse7520cf02020-03-25 09:26:14 -05008790 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
8791 ei = SkippedRanges.end();
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008792 i != ei; ++i) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008793 if (sm.getFileID(i->getBegin()) == wantedFileID ||
8794 sm.getFileID(i->getEnd()) == wantedFileID)
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008795 wantedRanges.push_back(*i);
Michael Kruse7520cf02020-03-25 09:26:14 -05008796 else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
8797 astUnit->isInPreambleFileID(i->getEnd())))
Cameron Desrochersb60f1b62018-01-15 19:14:16 +00008798 wantedRanges.push_back(*i);
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008799 }
8800
8801 skipped->count = wantedRanges.size();
8802 skipped->ranges = new CXSourceRange[skipped->count];
8803 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8804 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
8805
8806 return skipped;
8807}
8808
Cameron Desrochersd8091282016-08-18 15:43:55 +00008809CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
8810 CXSourceRangeList *skipped = new CXSourceRangeList;
8811 skipped->count = 0;
8812 skipped->ranges = nullptr;
8813
8814 if (isNotUsableTU(TU)) {
8815 LOG_BAD_TU(TU);
8816 return skipped;
8817 }
Michael Kruse7520cf02020-03-25 09:26:14 -05008818
Cameron Desrochersd8091282016-08-18 15:43:55 +00008819 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Michael Kruse7520cf02020-03-25 09:26:14 -05008820 PreprocessingRecord *ppRec =
8821 astUnit->getPreprocessor().getPreprocessingRecord();
Cameron Desrochersd8091282016-08-18 15:43:55 +00008822 if (!ppRec)
8823 return skipped;
8824
8825 ASTContext &Ctx = astUnit->getASTContext();
8826
8827 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
8828
8829 skipped->count = SkippedRanges.size();
8830 skipped->ranges = new CXSourceRange[skipped->count];
8831 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
8832 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);
8833
8834 return skipped;
8835}
8836
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00008837void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
8838 if (ranges) {
8839 delete[] ranges->ranges;
8840 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00008841 }
8842}
8843
Guy Benyei11169dd2012-12-18 14:30:41 +00008844void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
8845 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
8846 for (unsigned I = 0; I != Usage.numEntries; ++I)
Michael Kruse7520cf02020-03-25 09:26:14 -05008847 fprintf(stderr, " %s: %lu\n",
Guy Benyei11169dd2012-12-18 14:30:41 +00008848 clang_getTUResourceUsageName(Usage.entries[I].kind),
8849 Usage.entries[I].amount);
Michael Kruse7520cf02020-03-25 09:26:14 -05008850
Guy Benyei11169dd2012-12-18 14:30:41 +00008851 clang_disposeCXTUResourceUsage(Usage);
8852}
8853
8854//===----------------------------------------------------------------------===//
8855// Misc. utility functions.
8856//===----------------------------------------------------------------------===//
8857
Richard Smith0a7b2972018-07-03 21:34:13 +00008858/// Default to using our desired 8 MB stack size on "safety" threads.
8859static unsigned SafetyStackThreadSize = DesiredStackSize;
Guy Benyei11169dd2012-12-18 14:30:41 +00008860
8861namespace clang {
8862
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008863bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00008864 unsigned Size) {
8865 if (!Size)
8866 Size = GetSafetyThreadStackSize();
Erik Verbruggen3cc39112017-11-14 09:34:39 +00008867 if (Size && !getenv("LIBCLANG_NOTHREADS"))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00008868 return CRC.RunSafelyOnThread(Fn, Size);
8869 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00008870}
8871
Michael Kruse7520cf02020-03-25 09:26:14 -05008872unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008873
Michael Kruse7520cf02020-03-25 09:26:14 -05008874void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }
Guy Benyei11169dd2012-12-18 14:30:41 +00008875
Michael Kruse7520cf02020-03-25 09:26:14 -05008876} // namespace clang
Guy Benyei11169dd2012-12-18 14:30:41 +00008877
8878void clang::setThreadBackgroundPriority() {
8879 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
8880 return;
8881
Nico Weber18cfd9f2019-04-21 19:18:41 +00008882#if LLVM_ENABLE_THREADS
Kadir Cetinkayab8f82ca2019-04-18 13:49:20 +00008883 llvm::set_thread_priority(llvm::ThreadPriority::Background);
Nico Weber18cfd9f2019-04-21 19:18:41 +00008884#endif
Guy Benyei11169dd2012-12-18 14:30:41 +00008885}
8886
8887void cxindex::printDiagsToStderr(ASTUnit *Unit) {
8888 if (!Unit)
8889 return;
8890
Michael Kruse7520cf02020-03-25 09:26:14 -05008891 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
8892 DEnd = Unit->stored_diag_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00008893 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00008894 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Michael Kruse7520cf02020-03-25 09:26:14 -05008895 CXString Msg =
8896 clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
Guy Benyei11169dd2012-12-18 14:30:41 +00008897 fprintf(stderr, "%s\n", clang_getCString(Msg));
8898 clang_disposeString(Msg);
8899 }
Nico Weber1865df42018-04-27 19:11:14 +00008900#ifdef _WIN32
Guy Benyei11169dd2012-12-18 14:30:41 +00008901 // On Windows, force a flush, since there may be multiple copies of
8902 // stderr and stdout in the file system, all with different buffers
8903 // but writing to the same device.
8904 fflush(stderr);
8905#endif
8906}
8907
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008908MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
8909 SourceLocation MacroDefLoc,
Michael Kruse7520cf02020-03-25 09:26:14 -05008910 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008911 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008912 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008913 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008914 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008915
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008916 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00008917 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00008918 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008919 if (MD) {
Michael Kruse7520cf02020-03-25 09:26:14 -05008920 for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
8921 Def = Def.getPreviousDefinition()) {
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008922 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
8923 return Def.getMacroInfo();
8924 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008925 }
8926
Craig Topper69186e72014-06-08 08:38:04 +00008927 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008928}
8929
Richard Smith66a81862015-05-04 02:25:31 +00008930const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00008931 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008932 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008933 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008934 const IdentifierInfo *II = MacroDef->getName();
8935 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00008936 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008937
8938 return getMacroInfo(*II, MacroDef->getLocation(), TU);
8939}
8940
Richard Smith66a81862015-05-04 02:25:31 +00008941MacroDefinitionRecord *
8942cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
8943 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008944 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008945 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008946 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00008947 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008948
8949 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008950 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008951 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
8952 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008953 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008954
8955 // Check that the token is inside the definition and not its argument list.
8956 SourceManager &SM = Unit->getSourceManager();
8957 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00008958 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008959 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00008960 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008961
8962 Preprocessor &PP = Unit->getPreprocessor();
8963 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
8964 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00008965 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008966
Alp Toker2d57cea2014-05-17 04:53:25 +00008967 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008968 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00008969 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008970
8971 // Check that the identifier is not one of the macro arguments.
Faisal Valiac506d72017-07-17 17:18:43 +00008972 if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
Craig Topper69186e72014-06-08 08:38:04 +00008973 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008974
Richard Smith20e883e2015-04-29 23:20:19 +00008975 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00008976 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00008977 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008978
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00008979 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008980}
8981
Richard Smith66a81862015-05-04 02:25:31 +00008982MacroDefinitionRecord *
8983cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
8984 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008985 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00008986 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008987
8988 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00008989 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00008990 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008991 Preprocessor &PP = Unit->getPreprocessor();
8992 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00008993 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008994 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
8995 Token Tok;
8996 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00008997 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00008998
8999 return checkForMacroInMacroDefinition(MI, Tok, TU);
9000}
9001
Guy Benyei11169dd2012-12-18 14:30:41 +00009002CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00009003 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00009004}
9005
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009006Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
9007 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00009008 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009009 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00009010 if (Unit->isMainFileAST())
9011 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009012 return *this;
9013 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00009014 } else {
9015 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009016 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009017 return *this;
9018}
9019
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00009020Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
9021 *this << FE->getName();
9022 return *this;
9023}
9024
9025Logger &cxindex::Logger::operator<<(CXCursor cursor) {
9026 CXString cursorName = clang_getCursorDisplayName(cursor);
9027 *this << cursorName << "@" << clang_getCursorLocation(cursor);
9028 clang_disposeString(cursorName);
9029 return *this;
9030}
9031
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009032Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
9033 CXFile File;
9034 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00009035 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009036 CXString FileName = clang_getFileName(File);
9037 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
9038 clang_disposeString(FileName);
9039 return *this;
9040}
9041
9042Logger &cxindex::Logger::operator<<(CXSourceRange range) {
9043 CXSourceLocation BLoc = clang_getRangeStart(range);
9044 CXSourceLocation ELoc = clang_getRangeEnd(range);
9045
9046 CXFile BFile;
9047 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009048 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009049
9050 CXFile EFile;
9051 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00009052 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009053
9054 CXString BFileName = clang_getFileName(BFile);
9055 if (BFile == EFile) {
9056 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
Michael Kruse7520cf02020-03-25 09:26:14 -05009057 BLine, BColumn, ELine, EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009058 } else {
9059 CXString EFileName = clang_getFileName(EFile);
Michael Kruse7520cf02020-03-25 09:26:14 -05009060 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
9061 BColumn)
9062 << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
9063 EColumn);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009064 clang_disposeString(EFileName);
9065 }
9066 clang_disposeString(BFileName);
9067 return *this;
9068}
9069
9070Logger &cxindex::Logger::operator<<(CXString Str) {
9071 *this << clang_getCString(Str);
9072 return *this;
9073}
9074
9075Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
9076 LogOS << Fmt;
9077 return *this;
9078}
9079
Benjamin Kramer762bc332019-08-07 14:44:40 +00009080static llvm::ManagedStatic<std::mutex> LoggingMutex;
Chandler Carruth37ad2582014-06-27 15:14:39 +00009081
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009082cxindex::Logger::~Logger() {
Benjamin Kramer762bc332019-08-07 14:44:40 +00009083 std::lock_guard<std::mutex> L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009084
9085 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
9086
Dmitri Gribenkof8579502013-01-12 19:30:44 +00009087 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009088 OS << "[libclang:" << Name << ':';
9089
Alp Toker1a86ad22014-07-06 06:24:00 +00009090#ifdef USE_DARWIN_THREADS
9091 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009092 mach_port_t tid = pthread_mach_thread_np(pthread_self());
9093 OS << tid << ':';
9094#endif
9095
9096 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
9097 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00009098 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009099
9100 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00009101 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00009102 OS << "--------------------------------------------------\n";
9103 }
9104}
Ivan Donchevskiic5929132018-12-10 15:58:50 +00009105
9106#ifdef CLANG_TOOL_EXTRA_BUILD
9107// This anchor is used to force the linker to link the clang-tidy plugin.
9108extern volatile int ClangTidyPluginAnchorSource;
9109static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
9110 ClangTidyPluginAnchorSource;
9111
9112// This anchor is used to force the linker to link the clang-include-fixer
9113// plugin.
9114extern volatile int ClangIncludeFixerPluginAnchorSource;
9115static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
9116 ClangIncludeFixerPluginAnchorSource;
9117#endif