blob: c3bac878df968c1dc73ceb831b7e8ff8801f152c [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Eli Bendersky44a206f2014-07-31 18:04:56 +000025#include "clang/AST/Mangle.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Eli Bendersky79759592014-08-01 15:01:10 +000030#include "clang/Basic/TargetInfo.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000031#include "clang/Basic/Version.h"
32#include "clang/Frontend/ASTUnit.h"
33#include "clang/Frontend/CompilerInstance.h"
34#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000035#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000036#include "clang/Lex/HeaderSearch.h"
37#include "clang/Lex/Lexer.h"
38#include "clang/Lex/PreprocessingRecord.h"
39#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000040#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000041#include "llvm/ADT/Optional.h"
42#include "llvm/ADT/STLExtras.h"
43#include "llvm/ADT/StringSwitch.h"
Alp Toker1d257e12014-06-04 03:28:55 +000044#include "llvm/Config/llvm-config.h"
Eli Bendersky79759592014-08-01 15:01:10 +000045#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/Mangler.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/Compiler.h"
48#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000049#include "llvm/Support/Format.h"
Chandler Carruth37ad2582014-06-27 15:14:39 +000050#include "llvm/Support/ManagedStatic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000051#include "llvm/Support/MemoryBuffer.h"
52#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000053#include "llvm/Support/Program.h"
54#include "llvm/Support/SaveAndRestore.h"
55#include "llvm/Support/Signals.h"
Adrian Prantlbc068582015-07-08 01:00:30 +000056#include "llvm/Support/TargetSelect.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000057#include "llvm/Support/Threading.h"
58#include "llvm/Support/Timer.h"
59#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000060
Alp Toker1a86ad22014-07-06 06:24:00 +000061#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
62#define USE_DARWIN_THREADS
63#endif
64
65#ifdef USE_DARWIN_THREADS
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000066#include <pthread.h>
67#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000068
69using namespace clang;
70using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000071using namespace clang::cxtu;
72using namespace clang::cxindex;
73
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000074CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
75 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;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000080 D->TheASTUnit = AU;
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;
Guy Benyei11169dd2012-12-18 14:30:41 +000085 return D;
86}
87
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000088bool cxtu::isASTReadError(ASTUnit *AU) {
89 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
90 DEnd = AU->stored_diag_end();
91 D != DEnd; ++D) {
92 if (D->getLevel() >= DiagnosticsEngine::Error &&
93 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
94 diag::DiagCat_AST_Deserialization_Issue)
95 return true;
96 }
97 return false;
98}
99
Guy Benyei11169dd2012-12-18 14:30:41 +0000100cxtu::CXTUOwner::~CXTUOwner() {
101 if (TU)
102 clang_disposeTranslationUnit(TU);
103}
104
105/// \brief Compare two source ranges to determine their relative position in
106/// the translation unit.
107static RangeComparisonResult RangeCompare(SourceManager &SM,
108 SourceRange R1,
109 SourceRange R2) {
110 assert(R1.isValid() && "First range is invalid?");
111 assert(R2.isValid() && "Second range is invalid?");
112 if (R1.getEnd() != R2.getBegin() &&
113 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
114 return RangeBefore;
115 if (R2.getEnd() != R1.getBegin() &&
116 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
117 return RangeAfter;
118 return RangeOverlap;
119}
120
121/// \brief Determine if a source location falls within, before, or after a
122/// a given source range.
123static RangeComparisonResult LocationCompare(SourceManager &SM,
124 SourceLocation L, SourceRange R) {
125 assert(R.isValid() && "First range is invalid?");
126 assert(L.isValid() && "Second range is invalid?");
127 if (L == R.getBegin() || L == R.getEnd())
128 return RangeOverlap;
129 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
130 return RangeBefore;
131 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
132 return RangeAfter;
133 return RangeOverlap;
134}
135
136/// \brief Translate a Clang source range into a CIndex source range.
137///
138/// Clang internally represents ranges where the end location points to the
139/// start of the token at the end. However, for external clients it is more
140/// useful to have a CXSourceRange be a proper half-open interval. This routine
141/// does the appropriate translation.
142CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
143 const LangOptions &LangOpts,
144 const CharSourceRange &R) {
145 // We want the last character in this location, so we will adjust the
146 // location accordingly.
147 SourceLocation EndLoc = R.getEnd();
148 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
149 EndLoc = SM.getExpansionRange(EndLoc).second;
150 if (R.isTokenRange() && !EndLoc.isInvalid()) {
151 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
152 SM, LangOpts);
153 EndLoc = EndLoc.getLocWithOffset(Length);
154 }
155
Bill Wendlingeade3622013-01-23 08:25:41 +0000156 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000157 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000158 R.getBegin().getRawEncoding(),
159 EndLoc.getRawEncoding()
160 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000161 return Result;
162}
163
164//===----------------------------------------------------------------------===//
165// Cursor visitor.
166//===----------------------------------------------------------------------===//
167
168static SourceRange getRawCursorExtent(CXCursor C);
169static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
170
171
172RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
173 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
174}
175
176/// \brief Visit the given cursor and, if requested by the visitor,
177/// its children.
178///
179/// \param Cursor the cursor to visit.
180///
181/// \param CheckedRegionOfInterest if true, then the caller already checked
182/// that this cursor is within the region of interest.
183///
184/// \returns true if the visitation should be aborted, false if it
185/// should continue.
186bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
187 if (clang_isInvalid(Cursor.kind))
188 return false;
189
190 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000191 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000192 if (!D) {
193 assert(0 && "Invalid declaration cursor");
194 return true; // abort.
195 }
196
197 // Ignore implicit declarations, unless it's an objc method because
198 // currently we should report implicit methods for properties when indexing.
199 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
200 return false;
201 }
202
203 // If we have a range of interest, and this cursor doesn't intersect with it,
204 // we're done.
205 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
206 SourceRange Range = getRawCursorExtent(Cursor);
207 if (Range.isInvalid() || CompareRegionOfInterest(Range))
208 return false;
209 }
210
211 switch (Visitor(Cursor, Parent, ClientData)) {
212 case CXChildVisit_Break:
213 return true;
214
215 case CXChildVisit_Continue:
216 return false;
217
218 case CXChildVisit_Recurse: {
219 bool ret = VisitChildren(Cursor);
220 if (PostChildrenVisitor)
221 if (PostChildrenVisitor(Cursor, ClientData))
222 return true;
223 return ret;
224 }
225 }
226
227 llvm_unreachable("Invalid CXChildVisitResult!");
228}
229
230static bool visitPreprocessedEntitiesInRange(SourceRange R,
231 PreprocessingRecord &PPRec,
232 CursorVisitor &Visitor) {
233 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
234 FileID FID;
235
236 if (!Visitor.shouldVisitIncludedEntities()) {
237 // If the begin/end of the range lie in the same FileID, do the optimization
238 // where we skip preprocessed entities that do not come from the same FileID.
239 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
240 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
241 FID = FileID();
242 }
243
Benjamin Kramerb4ef6682015-02-06 17:25:10 +0000244 const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
245 return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 PPRec, FID);
247}
248
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000249bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000250 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000251 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000252
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000253 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000254 SourceManager &SM = Unit->getSourceManager();
255
256 std::pair<FileID, unsigned>
257 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
258 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
259
260 if (End.first != Begin.first) {
261 // If the end does not reside in the same file, try to recover by
262 // picking the end of the file of begin location.
263 End.first = Begin.first;
264 End.second = SM.getFileIDSize(Begin.first);
265 }
266
267 assert(Begin.first == End.first);
268 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
271 FileID File = Begin.first;
272 unsigned Offset = Begin.second;
273 unsigned Length = End.second - Begin.second;
274
275 if (!VisitDeclsOnly && !VisitPreprocessorLast)
276 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000277 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000278
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000279 if (visitDeclsFromFileRegion(File, Offset, Length))
280 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000281
282 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000283 return visitPreprocessedEntitiesInRegion();
284
285 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000286}
287
288static bool isInLexicalContext(Decl *D, DeclContext *DC) {
289 if (!DC)
290 return false;
291
292 for (DeclContext *DeclDC = D->getLexicalDeclContext();
293 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
294 if (DeclDC == DC)
295 return true;
296 }
297 return false;
298}
299
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000300bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000301 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000302 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000303 SourceManager &SM = Unit->getSourceManager();
304 SourceRange Range = RegionOfInterest;
305
306 SmallVector<Decl *, 16> Decls;
307 Unit->findFileRegionDecls(File, Offset, Length, Decls);
308
309 // If we didn't find any file level decls for the file, try looking at the
310 // file that it was included from.
311 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
312 bool Invalid = false;
313 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
314 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 SourceLocation Outer;
318 if (SLEntry.isFile())
319 Outer = SLEntry.getFile().getIncludeLoc();
320 else
321 Outer = SLEntry.getExpansion().getExpansionLocStart();
322 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000323 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000324
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000325 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000326 Length = 0;
327 Unit->findFileRegionDecls(File, Offset, Length, Decls);
328 }
329
330 assert(!Decls.empty());
331
332 bool VisitedAtLeastOnce = false;
Craig Topper69186e72014-06-08 08:38:04 +0000333 DeclContext *CurDC = nullptr;
Craig Topper2341c0d2013-07-04 03:08:24 +0000334 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
335 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000336 Decl *D = *DIt;
337 if (D->getSourceRange().isInvalid())
338 continue;
339
340 if (isInLexicalContext(D, CurDC))
341 continue;
342
343 CurDC = dyn_cast<DeclContext>(D);
344
345 if (TagDecl *TD = dyn_cast<TagDecl>(D))
346 if (!TD->isFreeStanding())
347 continue;
348
349 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
350 if (CompRes == RangeBefore)
351 continue;
352 if (CompRes == RangeAfter)
353 break;
354
355 assert(CompRes == RangeOverlap);
356 VisitedAtLeastOnce = true;
357
358 if (isa<ObjCContainerDecl>(D)) {
359 FileDI_current = &DIt;
360 FileDE_current = DE;
361 } else {
Craig Topper69186e72014-06-08 08:38:04 +0000362 FileDI_current = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363 }
364
365 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000366 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000367 }
368
369 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000370 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000371
372 // No Decls overlapped with the range. Move up the lexical context until there
373 // is a context that contains the range or we reach the translation unit
374 // level.
375 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
376 : (*(DIt-1))->getLexicalDeclContext();
377
378 while (DC && !DC->isTranslationUnit()) {
379 Decl *D = cast<Decl>(DC);
380 SourceRange CurDeclRange = D->getSourceRange();
381 if (CurDeclRange.isInvalid())
382 break;
383
384 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000385 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
386 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000387 }
388
389 DC = D->getLexicalDeclContext();
390 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000391
392 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000393}
394
395bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
396 if (!AU->getPreprocessor().getPreprocessingRecord())
397 return false;
398
399 PreprocessingRecord &PPRec
400 = *AU->getPreprocessor().getPreprocessingRecord();
401 SourceManager &SM = AU->getSourceManager();
402
403 if (RegionOfInterest.isValid()) {
404 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
405 SourceLocation B = MappedRange.getBegin();
406 SourceLocation E = MappedRange.getEnd();
407
408 if (AU->isInPreambleFileID(B)) {
409 if (SM.isLoadedSourceLocation(E))
410 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
411 PPRec, *this);
412
413 // Beginning of range lies in the preamble but it also extends beyond
414 // it into the main file. Split the range into 2 parts, one covering
415 // the preamble and another covering the main file. This allows subsequent
416 // calls to visitPreprocessedEntitiesInRange to accept a source range that
417 // lies in the same FileID, allowing it to skip preprocessed entities that
418 // do not come from the same FileID.
419 bool breaked =
420 visitPreprocessedEntitiesInRange(
421 SourceRange(B, AU->getEndOfPreambleFileID()),
422 PPRec, *this);
423 if (breaked) return true;
424 return visitPreprocessedEntitiesInRange(
425 SourceRange(AU->getStartOfMainFileID(), E),
426 PPRec, *this);
427 }
428
429 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
430 }
431
432 bool OnlyLocalDecls
433 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
434
435 if (OnlyLocalDecls)
436 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
437 PPRec);
438
439 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
440}
441
442template<typename InputIterator>
443bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
444 InputIterator Last,
445 PreprocessingRecord &PPRec,
446 FileID FID) {
447 for (; First != Last; ++First) {
448 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
449 continue;
450
451 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000452 if (!PPE)
453 continue;
454
Guy Benyei11169dd2012-12-18 14:30:41 +0000455 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
456 if (Visit(MakeMacroExpansionCursor(ME, TU)))
457 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000458
Guy Benyei11169dd2012-12-18 14:30:41 +0000459 continue;
460 }
Richard Smith66a81862015-05-04 02:25:31 +0000461
462 if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000463 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
464 return true;
Richard Smith66a81862015-05-04 02:25:31 +0000465
Guy Benyei11169dd2012-12-18 14:30:41 +0000466 continue;
467 }
468
469 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
470 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
471 return true;
472
473 continue;
474 }
475 }
476
477 return false;
478}
479
480/// \brief Visit the children of the given cursor.
481///
482/// \returns true if the visitation should be aborted, false if it
483/// should continue.
484bool CursorVisitor::VisitChildren(CXCursor Cursor) {
485 if (clang_isReference(Cursor.kind) &&
486 Cursor.kind != CXCursor_CXXBaseSpecifier) {
487 // By definition, references have no children.
488 return false;
489 }
490
491 // Set the Parent field to Cursor, then back to its old value once we're
492 // done.
493 SetParentRAII SetParent(Parent, StmtParent, Cursor);
494
495 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000496 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 if (!D)
498 return false;
499
500 return VisitAttributes(D) || Visit(D);
501 }
502
503 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000504 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000505 return Visit(S);
506
507 return false;
508 }
509
510 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000511 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000512 return Visit(E);
513
514 return false;
515 }
516
517 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000518 CXTranslationUnit TU = getCursorTU(Cursor);
519 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000520
521 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
522 for (unsigned I = 0; I != 2; ++I) {
523 if (VisitOrder[I]) {
524 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
525 RegionOfInterest.isInvalid()) {
526 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
527 TLEnd = CXXUnit->top_level_end();
528 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000529 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000530 return true;
531 }
532 } else if (VisitDeclContext(
533 CXXUnit->getASTContext().getTranslationUnitDecl()))
534 return true;
535 continue;
536 }
537
538 // Walk the preprocessing record.
539 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
540 visitPreprocessedEntitiesInRegion();
541 }
542
543 return false;
544 }
545
546 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000547 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
549 return Visit(BaseTSInfo->getTypeLoc());
550 }
551 }
552 }
553
554 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000555 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000556 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000557 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000558 return Visit(cxcursor::MakeCursorObjCClassRef(
559 ObjT->getInterface(),
560 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000561 }
562
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 // If pointing inside a macro definition, check if the token is an identifier
564 // that was ever defined as a macro. In such a case, create a "pseudo" macro
565 // expansion cursor for that token.
566 SourceLocation BeginLoc = RegionOfInterest.getBegin();
567 if (Cursor.kind == CXCursor_MacroDefinition &&
568 BeginLoc == RegionOfInterest.getEnd()) {
569 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000570 const MacroInfo *MI =
571 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Richard Smith66a81862015-05-04 02:25:31 +0000572 if (MacroDefinitionRecord *MacroDef =
573 checkForMacroInMacroDefinition(MI, Loc, TU))
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000574 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
575 }
576
Guy Benyei11169dd2012-12-18 14:30:41 +0000577 // Nothing to visit at the moment.
578 return false;
579}
580
581bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
582 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
583 if (Visit(TSInfo->getTypeLoc()))
584 return true;
585
586 if (Stmt *Body = B->getBody())
587 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
588
589 return false;
590}
591
Ted Kremenek03325582013-02-21 01:29:01 +0000592Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000593 if (RegionOfInterest.isValid()) {
594 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
595 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000596 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000597
598 switch (CompareRegionOfInterest(Range)) {
599 case RangeBefore:
600 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000601 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000602
603 case RangeAfter:
604 // This declaration comes after the region of interest; we're done.
605 return false;
606
607 case RangeOverlap:
608 // This declaration overlaps the region of interest; visit it.
609 break;
610 }
611 }
612 return true;
613}
614
615bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
616 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
617
618 // FIXME: Eventually remove. This part of a hack to support proper
619 // iteration over all Decls contained lexically within an ObjC container.
620 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
621 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
622
623 for ( ; I != E; ++I) {
624 Decl *D = *I;
625 if (D->getLexicalDeclContext() != DC)
626 continue;
627 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
628
629 // Ignore synthesized ivars here, otherwise if we have something like:
630 // @synthesize prop = _prop;
631 // and '_prop' is not declared, we will encounter a '_prop' ivar before
632 // encountering the 'prop' synthesize declaration and we will think that
633 // we passed the region-of-interest.
634 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
635 if (ivarD->getSynthesize())
636 continue;
637 }
638
639 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
640 // declarations is a mismatch with the compiler semantics.
641 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
642 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
643 if (!ID->isThisDeclarationADefinition())
644 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
645
646 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
647 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
648 if (!PD->isThisDeclarationADefinition())
649 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
650 }
651
Ted Kremenek03325582013-02-21 01:29:01 +0000652 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000653 if (!V.hasValue())
654 continue;
655 if (!V.getValue())
656 return false;
657 if (Visit(Cursor, true))
658 return true;
659 }
660 return false;
661}
662
663bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
664 llvm_unreachable("Translation units are visited directly by Visit()");
665}
666
667bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
668 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
669 return Visit(TSInfo->getTypeLoc());
670
671 return false;
672}
673
674bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
675 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
676 return Visit(TSInfo->getTypeLoc());
677
678 return false;
679}
680
681bool CursorVisitor::VisitTagDecl(TagDecl *D) {
682 return VisitDeclContext(D);
683}
684
685bool CursorVisitor::VisitClassTemplateSpecializationDecl(
686 ClassTemplateSpecializationDecl *D) {
687 bool ShouldVisitBody = false;
688 switch (D->getSpecializationKind()) {
689 case TSK_Undeclared:
690 case TSK_ImplicitInstantiation:
691 // Nothing to visit
692 return false;
693
694 case TSK_ExplicitInstantiationDeclaration:
695 case TSK_ExplicitInstantiationDefinition:
696 break;
697
698 case TSK_ExplicitSpecialization:
699 ShouldVisitBody = true;
700 break;
701 }
702
703 // Visit the template arguments used in the specialization.
704 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
705 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000706 if (TemplateSpecializationTypeLoc TSTLoc =
707 TL.getAs<TemplateSpecializationTypeLoc>()) {
708 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
709 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000710 return true;
711 }
712 }
713
714 if (ShouldVisitBody && VisitCXXRecordDecl(D))
715 return true;
716
717 return false;
718}
719
720bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
721 ClassTemplatePartialSpecializationDecl *D) {
722 // FIXME: Visit the "outer" template parameter lists on the TagDecl
723 // before visiting these template parameters.
724 if (VisitTemplateParameters(D->getTemplateParameters()))
725 return true;
726
727 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000728 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
729 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
730 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000731 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
732 return true;
733
734 return VisitCXXRecordDecl(D);
735}
736
737bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
738 // Visit the default argument.
739 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
740 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
741 if (Visit(DefArg->getTypeLoc()))
742 return true;
743
744 return false;
745}
746
747bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
748 if (Expr *Init = D->getInitExpr())
749 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
750 return false;
751}
752
753bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000754 unsigned NumParamList = DD->getNumTemplateParameterLists();
755 for (unsigned i = 0; i < NumParamList; i++) {
756 TemplateParameterList* Params = DD->getTemplateParameterList(i);
757 if (VisitTemplateParameters(Params))
758 return true;
759 }
760
Guy Benyei11169dd2012-12-18 14:30:41 +0000761 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
762 if (Visit(TSInfo->getTypeLoc()))
763 return true;
764
765 // Visit the nested-name-specifier, if present.
766 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
767 if (VisitNestedNameSpecifierLoc(QualifierLoc))
768 return true;
769
770 return false;
771}
772
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000773/// \brief Compare two base or member initializers based on their source order.
774static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
775 CXXCtorInitializer *const *Y) {
776 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
777}
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000780 unsigned NumParamList = ND->getNumTemplateParameterLists();
781 for (unsigned i = 0; i < NumParamList; i++) {
782 TemplateParameterList* Params = ND->getTemplateParameterList(i);
783 if (VisitTemplateParameters(Params))
784 return true;
785 }
786
Guy Benyei11169dd2012-12-18 14:30:41 +0000787 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
788 // Visit the function declaration's syntactic components in the order
789 // written. This requires a bit of work.
790 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000791 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000792
793 // If we have a function declared directly (without the use of a typedef),
794 // visit just the return type. Otherwise, just visit the function's type
795 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000796 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000797 (!FTL && Visit(TL)))
798 return true;
799
800 // Visit the nested-name-specifier, if present.
801 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
802 if (VisitNestedNameSpecifierLoc(QualifierLoc))
803 return true;
804
805 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000806 if (!isa<CXXDestructorDecl>(ND))
807 if (VisitDeclarationNameInfo(ND->getNameInfo()))
808 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000809
810 // FIXME: Visit explicitly-specified template arguments!
811
812 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000813 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000814 return true;
815
Bill Wendling44426052012-12-20 19:22:21 +0000816 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 }
818
819 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
820 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
821 // Find the initializers that were written in the source.
822 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000823 for (auto *I : Constructor->inits()) {
824 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 continue;
826
Aaron Ballman0ad78302014-03-13 17:34:31 +0000827 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 }
829
830 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000831 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
832 &CompareCXXCtorInitializers);
833
Guy Benyei11169dd2012-12-18 14:30:41 +0000834 // Visit the initializers in source order
835 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
836 CXXCtorInitializer *Init = WrittenInits[I];
837 if (Init->isAnyMemberInitializer()) {
838 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
839 Init->getMemberLocation(), TU)))
840 return true;
841 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
842 if (Visit(TInfo->getTypeLoc()))
843 return true;
844 }
845
846 // Visit the initializer value.
847 if (Expr *Initializer = Init->getInit())
848 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
849 return true;
850 }
851 }
852
853 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
854 return true;
855 }
856
857 return false;
858}
859
860bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
861 if (VisitDeclaratorDecl(D))
862 return true;
863
864 if (Expr *BitWidth = D->getBitWidth())
865 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
866
867 return false;
868}
869
870bool CursorVisitor::VisitVarDecl(VarDecl *D) {
871 if (VisitDeclaratorDecl(D))
872 return true;
873
874 if (Expr *Init = D->getInit())
875 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
876
877 return false;
878}
879
880bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
881 if (VisitDeclaratorDecl(D))
882 return true;
883
884 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
885 if (Expr *DefArg = D->getDefaultArgument())
886 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
887
888 return false;
889}
890
891bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitFunctionDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
901 // FIXME: Visit the "outer" template parameter lists on the TagDecl
902 // before visiting these template parameters.
903 if (VisitTemplateParameters(D->getTemplateParameters()))
904 return true;
905
906 return VisitCXXRecordDecl(D->getTemplatedDecl());
907}
908
909bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
910 if (VisitTemplateParameters(D->getTemplateParameters()))
911 return true;
912
913 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
914 VisitTemplateArgumentLoc(D->getDefaultArgument()))
915 return true;
916
917 return false;
918}
919
Douglas Gregor9bda6cf2015-07-07 03:58:14 +0000920bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
921 // Visit the bound, if it's explicit.
922 if (D->hasExplicitBound()) {
923 if (auto TInfo = D->getTypeSourceInfo()) {
924 if (Visit(TInfo->getTypeLoc()))
925 return true;
926 }
927 }
928
929 return false;
930}
931
Guy Benyei11169dd2012-12-18 14:30:41 +0000932bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000933 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000934 if (Visit(TSInfo->getTypeLoc()))
935 return true;
936
Aaron Ballman43b68be2014-03-07 17:50:17 +0000937 for (const auto *P : ND->params()) {
938 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000939 return true;
940 }
941
942 if (ND->isThisDeclarationADefinition() &&
943 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
944 return true;
945
946 return false;
947}
948
949template <typename DeclIt>
950static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
951 SourceManager &SM, SourceLocation EndLoc,
952 SmallVectorImpl<Decl *> &Decls) {
953 DeclIt next = *DI_current;
954 while (++next != DE_current) {
955 Decl *D_next = *next;
956 if (!D_next)
957 break;
958 SourceLocation L = D_next->getLocStart();
959 if (!L.isValid())
960 break;
961 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
962 *DI_current = next;
963 Decls.push_back(D_next);
964 continue;
965 }
966 break;
967 }
968}
969
Guy Benyei11169dd2012-12-18 14:30:41 +0000970bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
971 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
972 // an @implementation can lexically contain Decls that are not properly
973 // nested in the AST. When we identify such cases, we need to retrofit
974 // this nesting here.
975 if (!DI_current && !FileDI_current)
976 return VisitDeclContext(D);
977
978 // Scan the Decls that immediately come after the container
979 // in the current DeclContext. If any fall within the
980 // container's lexical region, stash them into a vector
981 // for later processing.
982 SmallVector<Decl *, 24> DeclsInContainer;
983 SourceLocation EndLoc = D->getSourceRange().getEnd();
984 SourceManager &SM = AU->getSourceManager();
985 if (EndLoc.isValid()) {
986 if (DI_current) {
987 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
988 DeclsInContainer);
989 } else {
990 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
991 DeclsInContainer);
992 }
993 }
994
995 // The common case.
996 if (DeclsInContainer.empty())
997 return VisitDeclContext(D);
998
999 // Get all the Decls in the DeclContext, and sort them with the
1000 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +00001001 for (auto *SubDecl : D->decls()) {
1002 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
1003 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +00001005 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 }
1007
1008 // Now sort the Decls so that they appear in lexical order.
1009 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +00001010 [&SM](Decl *A, Decl *B) {
1011 SourceLocation L_A = A->getLocStart();
1012 SourceLocation L_B = B->getLocStart();
1013 assert(L_A.isValid() && L_B.isValid());
1014 return SM.isBeforeInTranslationUnit(L_A, L_B);
1015 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001016
1017 // Now visit the decls.
1018 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1019 E = DeclsInContainer.end(); I != E; ++I) {
1020 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001021 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001022 if (!V.hasValue())
1023 continue;
1024 if (!V.getValue())
1025 return false;
1026 if (Visit(Cursor, true))
1027 return true;
1028 }
1029 return false;
1030}
1031
1032bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1033 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1034 TU)))
1035 return true;
1036
Douglas Gregore9d95f12015-07-07 03:57:35 +00001037 if (VisitObjCTypeParamList(ND->getTypeParamList()))
1038 return true;
1039
Guy Benyei11169dd2012-12-18 14:30:41 +00001040 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1041 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1042 E = ND->protocol_end(); I != E; ++I, ++PL)
1043 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1044 return true;
1045
1046 return VisitObjCContainerDecl(ND);
1047}
1048
1049bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1050 if (!PID->isThisDeclarationADefinition())
1051 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1052
1053 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1054 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1055 E = PID->protocol_end(); I != E; ++I, ++PL)
1056 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1057 return true;
1058
1059 return VisitObjCContainerDecl(PID);
1060}
1061
1062bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1063 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1064 return true;
1065
1066 // FIXME: This implements a workaround with @property declarations also being
1067 // installed in the DeclContext for the @interface. Eventually this code
1068 // should be removed.
1069 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1070 if (!CDecl || !CDecl->IsClassExtension())
1071 return false;
1072
1073 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1074 if (!ID)
1075 return false;
1076
1077 IdentifierInfo *PropertyId = PD->getIdentifier();
1078 ObjCPropertyDecl *prevDecl =
1079 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1080
1081 if (!prevDecl)
1082 return false;
1083
1084 // Visit synthesized methods since they will be skipped when visiting
1085 // the @interface.
1086 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1087 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1088 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1089 return true;
1090
1091 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1092 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1093 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1094 return true;
1095
1096 return false;
1097}
1098
Douglas Gregore9d95f12015-07-07 03:57:35 +00001099bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
1100 if (!typeParamList)
1101 return false;
1102
1103 for (auto *typeParam : *typeParamList) {
1104 // Visit the type parameter.
1105 if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
1106 return true;
Douglas Gregore9d95f12015-07-07 03:57:35 +00001107 }
1108
1109 return false;
1110}
1111
Guy Benyei11169dd2012-12-18 14:30:41 +00001112bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1113 if (!D->isThisDeclarationADefinition()) {
1114 // Forward declaration is treated like a reference.
1115 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1116 }
1117
Douglas Gregore9d95f12015-07-07 03:57:35 +00001118 // Objective-C type parameters.
1119 if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
1120 return true;
1121
Guy Benyei11169dd2012-12-18 14:30:41 +00001122 // Issue callbacks for super class.
1123 if (D->getSuperClass() &&
1124 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1125 D->getSuperClassLoc(),
1126 TU)))
1127 return true;
1128
Douglas Gregore9d95f12015-07-07 03:57:35 +00001129 if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
1130 if (Visit(SuperClassTInfo->getTypeLoc()))
1131 return true;
1132
Guy Benyei11169dd2012-12-18 14:30:41 +00001133 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1134 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1135 E = D->protocol_end(); I != E; ++I, ++PL)
1136 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1137 return true;
1138
1139 return VisitObjCContainerDecl(D);
1140}
1141
1142bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1143 return VisitObjCContainerDecl(D);
1144}
1145
1146bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1147 // 'ID' could be null when dealing with invalid code.
1148 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1149 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1150 return true;
1151
1152 return VisitObjCImplDecl(D);
1153}
1154
1155bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1156#if 0
1157 // Issue callbacks for super class.
1158 // FIXME: No source location information!
1159 if (D->getSuperClass() &&
1160 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1161 D->getSuperClassLoc(),
1162 TU)))
1163 return true;
1164#endif
1165
1166 return VisitObjCImplDecl(D);
1167}
1168
1169bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1170 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1171 if (PD->isIvarNameSpecified())
1172 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1173
1174 return false;
1175}
1176
1177bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1178 return VisitDeclContext(D);
1179}
1180
1181bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1182 // Visit nested-name-specifier.
1183 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1185 return true;
1186
1187 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1188 D->getTargetNameLoc(), TU));
1189}
1190
1191bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1192 // Visit nested-name-specifier.
1193 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1194 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1195 return true;
1196 }
1197
1198 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1199 return true;
1200
1201 return VisitDeclarationNameInfo(D->getNameInfo());
1202}
1203
1204bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1205 // Visit nested-name-specifier.
1206 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1207 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1208 return true;
1209
1210 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1211 D->getIdentLocation(), TU));
1212}
1213
1214bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1215 // Visit nested-name-specifier.
1216 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1217 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1218 return true;
1219 }
1220
1221 return VisitDeclarationNameInfo(D->getNameInfo());
1222}
1223
1224bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1225 UnresolvedUsingTypenameDecl *D) {
1226 // Visit nested-name-specifier.
1227 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1228 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1229 return true;
1230
1231 return false;
1232}
1233
1234bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1235 switch (Name.getName().getNameKind()) {
1236 case clang::DeclarationName::Identifier:
1237 case clang::DeclarationName::CXXLiteralOperatorName:
1238 case clang::DeclarationName::CXXOperatorName:
1239 case clang::DeclarationName::CXXUsingDirective:
1240 return false;
1241
1242 case clang::DeclarationName::CXXConstructorName:
1243 case clang::DeclarationName::CXXDestructorName:
1244 case clang::DeclarationName::CXXConversionFunctionName:
1245 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1246 return Visit(TSInfo->getTypeLoc());
1247 return false;
1248
1249 case clang::DeclarationName::ObjCZeroArgSelector:
1250 case clang::DeclarationName::ObjCOneArgSelector:
1251 case clang::DeclarationName::ObjCMultiArgSelector:
1252 // FIXME: Per-identifier location info?
1253 return false;
1254 }
1255
1256 llvm_unreachable("Invalid DeclarationName::Kind!");
1257}
1258
1259bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1260 SourceRange Range) {
1261 // FIXME: This whole routine is a hack to work around the lack of proper
1262 // source information in nested-name-specifiers (PR5791). Since we do have
1263 // a beginning source location, we can visit the first component of the
1264 // nested-name-specifier, if it's a single-token component.
1265 if (!NNS)
1266 return false;
1267
1268 // Get the first component in the nested-name-specifier.
1269 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1270 NNS = Prefix;
1271
1272 switch (NNS->getKind()) {
1273 case NestedNameSpecifier::Namespace:
1274 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1275 TU));
1276
1277 case NestedNameSpecifier::NamespaceAlias:
1278 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1279 Range.getBegin(), TU));
1280
1281 case NestedNameSpecifier::TypeSpec: {
1282 // If the type has a form where we know that the beginning of the source
1283 // range matches up with a reference cursor. Visit the appropriate reference
1284 // cursor.
1285 const Type *T = NNS->getAsType();
1286 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1287 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1288 if (const TagType *Tag = dyn_cast<TagType>(T))
1289 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1290 if (const TemplateSpecializationType *TST
1291 = dyn_cast<TemplateSpecializationType>(T))
1292 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1293 break;
1294 }
1295
1296 case NestedNameSpecifier::TypeSpecWithTemplate:
1297 case NestedNameSpecifier::Global:
1298 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001299 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001300 break;
1301 }
1302
1303 return false;
1304}
1305
1306bool
1307CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1308 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1309 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1310 Qualifiers.push_back(Qualifier);
1311
1312 while (!Qualifiers.empty()) {
1313 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1314 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1315 switch (NNS->getKind()) {
1316 case NestedNameSpecifier::Namespace:
1317 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1318 Q.getLocalBeginLoc(),
1319 TU)))
1320 return true;
1321
1322 break;
1323
1324 case NestedNameSpecifier::NamespaceAlias:
1325 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1326 Q.getLocalBeginLoc(),
1327 TU)))
1328 return true;
1329
1330 break;
1331
1332 case NestedNameSpecifier::TypeSpec:
1333 case NestedNameSpecifier::TypeSpecWithTemplate:
1334 if (Visit(Q.getTypeLoc()))
1335 return true;
1336
1337 break;
1338
1339 case NestedNameSpecifier::Global:
1340 case NestedNameSpecifier::Identifier:
Nikola Smiljanic67860242014-09-26 00:28:20 +00001341 case NestedNameSpecifier::Super:
Guy Benyei11169dd2012-12-18 14:30:41 +00001342 break;
1343 }
1344 }
1345
1346 return false;
1347}
1348
1349bool CursorVisitor::VisitTemplateParameters(
1350 const TemplateParameterList *Params) {
1351 if (!Params)
1352 return false;
1353
1354 for (TemplateParameterList::const_iterator P = Params->begin(),
1355 PEnd = Params->end();
1356 P != PEnd; ++P) {
1357 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1358 return true;
1359 }
1360
1361 return false;
1362}
1363
1364bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1365 switch (Name.getKind()) {
1366 case TemplateName::Template:
1367 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1368
1369 case TemplateName::OverloadedTemplate:
1370 // Visit the overloaded template set.
1371 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1372 return true;
1373
1374 return false;
1375
1376 case TemplateName::DependentTemplate:
1377 // FIXME: Visit nested-name-specifier.
1378 return false;
1379
1380 case TemplateName::QualifiedTemplate:
1381 // FIXME: Visit nested-name-specifier.
1382 return Visit(MakeCursorTemplateRef(
1383 Name.getAsQualifiedTemplateName()->getDecl(),
1384 Loc, TU));
1385
1386 case TemplateName::SubstTemplateTemplateParm:
1387 return Visit(MakeCursorTemplateRef(
1388 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1389 Loc, TU));
1390
1391 case TemplateName::SubstTemplateTemplateParmPack:
1392 return Visit(MakeCursorTemplateRef(
1393 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1394 Loc, TU));
1395 }
1396
1397 llvm_unreachable("Invalid TemplateName::Kind!");
1398}
1399
1400bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1401 switch (TAL.getArgument().getKind()) {
1402 case TemplateArgument::Null:
1403 case TemplateArgument::Integral:
1404 case TemplateArgument::Pack:
1405 return false;
1406
1407 case TemplateArgument::Type:
1408 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1409 return Visit(TSInfo->getTypeLoc());
1410 return false;
1411
1412 case TemplateArgument::Declaration:
1413 if (Expr *E = TAL.getSourceDeclExpression())
1414 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1415 return false;
1416
1417 case TemplateArgument::NullPtr:
1418 if (Expr *E = TAL.getSourceNullPtrExpression())
1419 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1420 return false;
1421
1422 case TemplateArgument::Expression:
1423 if (Expr *E = TAL.getSourceExpression())
1424 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1425 return false;
1426
1427 case TemplateArgument::Template:
1428 case TemplateArgument::TemplateExpansion:
1429 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1430 return true;
1431
1432 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1433 TAL.getTemplateNameLoc());
1434 }
1435
1436 llvm_unreachable("Invalid TemplateArgument::Kind!");
1437}
1438
1439bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1440 return VisitDeclContext(D);
1441}
1442
1443bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1444 return Visit(TL.getUnqualifiedLoc());
1445}
1446
1447bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1448 ASTContext &Context = AU->getASTContext();
1449
1450 // Some builtin types (such as Objective-C's "id", "sel", and
1451 // "Class") have associated declarations. Create cursors for those.
1452 QualType VisitType;
1453 switch (TL.getTypePtr()->getKind()) {
1454
1455 case BuiltinType::Void:
1456 case BuiltinType::NullPtr:
1457 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001458 case BuiltinType::OCLImage1d:
1459 case BuiltinType::OCLImage1dArray:
1460 case BuiltinType::OCLImage1dBuffer:
1461 case BuiltinType::OCLImage2d:
1462 case BuiltinType::OCLImage2dArray:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001463 case BuiltinType::OCLImage2dDepth:
1464 case BuiltinType::OCLImage2dArrayDepth:
1465 case BuiltinType::OCLImage2dMSAA:
1466 case BuiltinType::OCLImage2dArrayMSAA:
1467 case BuiltinType::OCLImage2dMSAADepth:
1468 case BuiltinType::OCLImage2dArrayMSAADepth:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001469 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001470 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001471 case BuiltinType::OCLEvent:
Alexey Bader9c8453f2015-09-15 11:18:52 +00001472 case BuiltinType::OCLClkEvent:
1473 case BuiltinType::OCLQueue:
1474 case BuiltinType::OCLNDRange:
1475 case BuiltinType::OCLReserveID:
Guy Benyei11169dd2012-12-18 14:30:41 +00001476#define BUILTIN_TYPE(Id, SingletonId)
1477#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1478#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1479#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1480#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1481#include "clang/AST/BuiltinTypes.def"
1482 break;
1483
1484 case BuiltinType::ObjCId:
1485 VisitType = Context.getObjCIdType();
1486 break;
1487
1488 case BuiltinType::ObjCClass:
1489 VisitType = Context.getObjCClassType();
1490 break;
1491
1492 case BuiltinType::ObjCSel:
1493 VisitType = Context.getObjCSelType();
1494 break;
1495 }
1496
1497 if (!VisitType.isNull()) {
1498 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1499 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1500 TU));
1501 }
1502
1503 return false;
1504}
1505
1506bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1507 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1508}
1509
1510bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1511 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1512}
1513
1514bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1515 if (TL.isDefinition())
1516 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1517
1518 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1519}
1520
1521bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1522 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1523}
1524
1525bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1526 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1527 return true;
1528
1529 return false;
1530}
1531
1532bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1533 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1534 return true;
1535
Douglas Gregore9d95f12015-07-07 03:57:35 +00001536 for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
1537 if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
1538 return true;
1539 }
1540
Guy Benyei11169dd2012-12-18 14:30:41 +00001541 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1542 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1543 TU)))
1544 return true;
1545 }
1546
1547 return false;
1548}
1549
1550bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1551 return Visit(TL.getPointeeLoc());
1552}
1553
1554bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1555 return Visit(TL.getInnerLoc());
1556}
1557
1558bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1559 return Visit(TL.getPointeeLoc());
1560}
1561
1562bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1563 return Visit(TL.getPointeeLoc());
1564}
1565
1566bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1567 return Visit(TL.getPointeeLoc());
1568}
1569
1570bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1571 return Visit(TL.getPointeeLoc());
1572}
1573
1574bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1575 return Visit(TL.getPointeeLoc());
1576}
1577
1578bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1579 return Visit(TL.getModifiedLoc());
1580}
1581
1582bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1583 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001584 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001585 return true;
1586
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001587 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1588 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001589 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1590 return true;
1591
1592 return false;
1593}
1594
1595bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1596 if (Visit(TL.getElementLoc()))
1597 return true;
1598
1599 if (Expr *Size = TL.getSizeExpr())
1600 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1601
1602 return false;
1603}
1604
Reid Kleckner8a365022013-06-24 17:51:48 +00001605bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1606 return Visit(TL.getOriginalLoc());
1607}
1608
Reid Kleckner0503a872013-12-05 01:23:43 +00001609bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1610 return Visit(TL.getOriginalLoc());
1611}
1612
Guy Benyei11169dd2012-12-18 14:30:41 +00001613bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1614 TemplateSpecializationTypeLoc TL) {
1615 // Visit the template name.
1616 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1617 TL.getTemplateNameLoc()))
1618 return true;
1619
1620 // Visit the template arguments.
1621 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1622 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1623 return true;
1624
1625 return false;
1626}
1627
1628bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1629 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1630}
1631
1632bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1633 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1634 return Visit(TSInfo->getTypeLoc());
1635
1636 return false;
1637}
1638
1639bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1640 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1641 return Visit(TSInfo->getTypeLoc());
1642
1643 return false;
1644}
1645
1646bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1647 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1648 return true;
1649
1650 return false;
1651}
1652
1653bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1654 DependentTemplateSpecializationTypeLoc TL) {
1655 // Visit the nested-name-specifier, if there is one.
1656 if (TL.getQualifierLoc() &&
1657 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1658 return true;
1659
1660 // Visit the template arguments.
1661 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1662 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1663 return true;
1664
1665 return false;
1666}
1667
1668bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1669 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1670 return true;
1671
1672 return Visit(TL.getNamedTypeLoc());
1673}
1674
1675bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1676 return Visit(TL.getPatternLoc());
1677}
1678
1679bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1680 if (Expr *E = TL.getUnderlyingExpr())
1681 return Visit(MakeCXCursor(E, StmtParent, TU));
1682
1683 return false;
1684}
1685
1686bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1687 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1688}
1689
1690bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1691 return Visit(TL.getValueLoc());
1692}
1693
1694#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1695bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1696 return Visit##PARENT##Loc(TL); \
1697}
1698
1699DEFAULT_TYPELOC_IMPL(Complex, Type)
1700DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1701DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1702DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1703DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1704DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1705DEFAULT_TYPELOC_IMPL(Vector, Type)
1706DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1707DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1708DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1709DEFAULT_TYPELOC_IMPL(Record, TagType)
1710DEFAULT_TYPELOC_IMPL(Enum, TagType)
1711DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1712DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1713DEFAULT_TYPELOC_IMPL(Auto, Type)
1714
1715bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1716 // Visit the nested-name-specifier, if present.
1717 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1718 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1719 return true;
1720
1721 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001722 for (const auto &I : D->bases()) {
1723 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001724 return true;
1725 }
1726 }
1727
1728 return VisitTagDecl(D);
1729}
1730
1731bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001732 for (const auto *I : D->attrs())
1733 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001734 return true;
1735
1736 return false;
1737}
1738
1739//===----------------------------------------------------------------------===//
1740// Data-recursive visitor methods.
1741//===----------------------------------------------------------------------===//
1742
1743namespace {
1744#define DEF_JOB(NAME, DATA, KIND)\
1745class NAME : public VisitorJob {\
1746public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 NAME(const DATA *d, CXCursor parent) : \
1748 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001749 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001750 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001751};
1752
1753DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1754DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1755DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1756DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1757DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1758 ExplicitTemplateArgsVisitKind)
1759DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1760DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1761DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1762#undef DEF_JOB
1763
1764class DeclVisit : public VisitorJob {
1765public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001767 VisitorJob(parent, VisitorJob::DeclVisitKind,
Craig Topper69186e72014-06-08 08:38:04 +00001768 D, isFirst ? (void*) 1 : (void*) nullptr) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == DeclVisitKind;
1771 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001772 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Dmitri Gribenkoe5423a72015-03-23 19:23:50 +00001773 bool isFirst() const { return data[1] != nullptr; }
Guy Benyei11169dd2012-12-18 14:30:41 +00001774};
1775class TypeLocVisit : public VisitorJob {
1776public:
1777 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1778 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1779 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1780
1781 static bool classof(const VisitorJob *VJ) {
1782 return VJ->getKind() == TypeLocVisitKind;
1783 }
1784
1785 TypeLoc get() const {
1786 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001787 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001788 }
1789};
1790
1791class LabelRefVisit : public VisitorJob {
1792public:
1793 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1794 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1795 labelLoc.getPtrEncoding()) {}
1796
1797 static bool classof(const VisitorJob *VJ) {
1798 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1799 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 const LabelDecl *get() const {
1801 return static_cast<const LabelDecl *>(data[0]);
1802 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 SourceLocation getLoc() const {
1804 return SourceLocation::getFromPtrEncoding(data[1]); }
1805};
1806
1807class NestedNameSpecifierLocVisit : public VisitorJob {
1808public:
1809 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1810 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1811 Qualifier.getNestedNameSpecifier(),
1812 Qualifier.getOpaqueData()) { }
1813
1814 static bool classof(const VisitorJob *VJ) {
1815 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1816 }
1817
1818 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001819 return NestedNameSpecifierLoc(
1820 const_cast<NestedNameSpecifier *>(
1821 static_cast<const NestedNameSpecifier *>(data[0])),
1822 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001823 }
1824};
1825
1826class DeclarationNameInfoVisit : public VisitorJob {
1827public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001828 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001829 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001830 static bool classof(const VisitorJob *VJ) {
1831 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1832 }
1833 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001834 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001835 switch (S->getStmtClass()) {
1836 default:
1837 llvm_unreachable("Unhandled Stmt");
1838 case clang::Stmt::MSDependentExistsStmtClass:
1839 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1840 case Stmt::CXXDependentScopeMemberExprClass:
1841 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1842 case Stmt::DependentScopeDeclRefExprClass:
1843 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001844 case Stmt::OMPCriticalDirectiveClass:
1845 return cast<OMPCriticalDirective>(S)->getDirectiveName();
Guy Benyei11169dd2012-12-18 14:30:41 +00001846 }
1847 }
1848};
1849class MemberRefVisit : public VisitorJob {
1850public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001851 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001852 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1853 L.getPtrEncoding()) {}
1854 static bool classof(const VisitorJob *VJ) {
1855 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1856 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857 const FieldDecl *get() const {
1858 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001859 }
1860 SourceLocation getLoc() const {
1861 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1862 }
1863};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001865 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 VisitorWorkList &WL;
1867 CXCursor Parent;
1868public:
1869 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1870 : WL(wl), Parent(parent) {}
1871
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1873 void VisitBlockExpr(const BlockExpr *B);
1874 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1875 void VisitCompoundStmt(const CompoundStmt *S);
1876 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1877 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1878 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1879 void VisitCXXNewExpr(const CXXNewExpr *E);
1880 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1881 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1882 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1883 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1884 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1885 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1886 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1887 void VisitCXXCatchStmt(const CXXCatchStmt *S);
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00001888 void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889 void VisitDeclRefExpr(const DeclRefExpr *D);
1890 void VisitDeclStmt(const DeclStmt *S);
1891 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1892 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1893 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1894 void VisitForStmt(const ForStmt *FS);
1895 void VisitGotoStmt(const GotoStmt *GS);
1896 void VisitIfStmt(const IfStmt *If);
1897 void VisitInitListExpr(const InitListExpr *IE);
1898 void VisitMemberExpr(const MemberExpr *M);
1899 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1900 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1901 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1902 void VisitOverloadExpr(const OverloadExpr *E);
1903 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1904 void VisitStmt(const Stmt *S);
1905 void VisitSwitchStmt(const SwitchStmt *S);
1906 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001907 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1908 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1909 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1910 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1911 void VisitVAArgExpr(const VAArgExpr *E);
1912 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1913 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1914 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1915 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001916 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
Alexander Musman3aaab662014-08-19 11:27:13 +00001917 void VisitOMPLoopDirective(const OMPLoopDirective *D);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001918 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001919 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00001920 void VisitOMPForDirective(const OMPForDirective *D);
Alexander Musmanf82886e2014-09-18 05:12:34 +00001921 void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00001922 void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
Alexey Bataev1e0498a2014-06-26 08:21:58 +00001923 void VisitOMPSectionDirective(const OMPSectionDirective *D);
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00001924 void VisitOMPSingleDirective(const OMPSingleDirective *D);
Alexander Musman80c22892014-07-17 08:54:58 +00001925 void VisitOMPMasterDirective(const OMPMasterDirective *D);
Alexander Musmand9ed09f2014-07-21 09:42:05 +00001926 void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00001927 void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
Alexander Musmane4e893b2014-09-23 09:33:00 +00001928 void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00001929 void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00001930 void VisitOMPTaskDirective(const OMPTaskDirective *D);
Alexey Bataev68446b72014-07-18 07:47:19 +00001931 void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00001932 void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
Alexey Bataev2df347a2014-07-18 10:17:07 +00001933 void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00001934 void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
Alexey Bataev6d4ed052015-07-01 06:57:41 +00001935 void
1936 VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
Alexey Bataev80909872015-07-02 11:25:17 +00001937 void VisitOMPCancelDirective(const OMPCancelDirective *D);
Alexey Bataev6125da92014-07-21 11:26:11 +00001938 void VisitOMPFlushDirective(const OMPFlushDirective *D);
Alexey Bataev9fb6e642014-07-22 06:45:04 +00001939 void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
Alexey Bataev0162e452014-07-22 10:10:35 +00001940 void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
Alexey Bataev0bd520b2014-09-19 08:19:49 +00001941 void VisitOMPTargetDirective(const OMPTargetDirective *D);
Michael Wong65f367f2015-07-21 13:44:28 +00001942 void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
Alexey Bataev13314bf2014-10-09 04:18:56 +00001943 void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001944
Guy Benyei11169dd2012-12-18 14:30:41 +00001945private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001946 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001947 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1948 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001949 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1950 void AddStmt(const Stmt *S);
1951 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001952 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001953 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001954 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001955};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00001956} // end anonyous namespace
Guy Benyei11169dd2012-12-18 14:30:41 +00001957
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001958void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001959 // 'S' should always be non-null, since it comes from the
1960 // statement we are visiting.
1961 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1962}
1963
1964void
1965EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1966 if (Qualifier)
1967 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1968}
1969
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001970void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001971 if (S)
1972 WL.push_back(StmtVisit(S, Parent));
1973}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001975 if (D)
1976 WL.push_back(DeclVisit(D, Parent, isFirst));
1977}
1978void EnqueueVisitor::
1979 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1980 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001982}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001983void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 if (D)
1985 WL.push_back(MemberRefVisit(D, L, Parent));
1986}
1987void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1988 if (TI)
1989 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1990 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001991void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001992 unsigned size = WL.size();
Benjamin Kramer642f1732015-07-02 21:03:14 +00001993 for (const Stmt *SubStmt : S->children()) {
1994 AddStmt(SubStmt);
Guy Benyei11169dd2012-12-18 14:30:41 +00001995 }
1996 if (size == WL.size())
1997 return;
1998 // Now reverse the entries we just added. This will match the DFS
1999 // ordering performed by the worklist.
2000 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2001 std::reverse(I, E);
2002}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002003namespace {
2004class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
2005 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00002006 /// \brief Process clauses with list of variables.
2007 template <typename T>
2008 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002009public:
2010 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
2011#define OPENMP_CLAUSE(Name, Class) \
2012 void Visit##Class(const Class *C);
2013#include "clang/Basic/OpenMPKinds.def"
2014};
2015
Alexey Bataevaadd52e2014-02-13 05:29:23 +00002016void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
2017 Visitor->AddStmt(C->getCondition());
2018}
2019
Alexey Bataev3778b602014-07-17 07:32:53 +00002020void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
2021 Visitor->AddStmt(C->getCondition());
2022}
2023
Alexey Bataev568a8332014-03-06 06:15:19 +00002024void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
2025 Visitor->AddStmt(C->getNumThreads());
2026}
2027
Alexey Bataev62c87d22014-03-21 04:51:18 +00002028void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
2029 Visitor->AddStmt(C->getSafelen());
2030}
2031
Alexey Bataev66b15b52015-08-21 11:14:16 +00002032void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
2033 Visitor->AddStmt(C->getSimdlen());
2034}
2035
Alexander Musman8bd31e62014-05-27 15:12:19 +00002036void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
2037 Visitor->AddStmt(C->getNumForLoops());
2038}
2039
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002040void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00002041
Alexey Bataevbcbadb62014-05-06 06:04:14 +00002042void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
2043
Alexey Bataev56dafe82014-06-20 07:16:17 +00002044void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
2045 Visitor->AddStmt(C->getChunkSize());
Alexey Bataev040d5402015-05-12 08:35:28 +00002046 Visitor->AddStmt(C->getHelperChunkSize());
Alexey Bataev56dafe82014-06-20 07:16:17 +00002047}
2048
Alexey Bataev10e775f2015-07-30 11:36:16 +00002049void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
2050 Visitor->AddStmt(C->getNumForLoops());
2051}
Alexey Bataev142e1fc2014-06-20 09:44:06 +00002052
Alexey Bataev236070f2014-06-20 11:19:47 +00002053void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}
2054
Alexey Bataev7aea99a2014-07-17 12:19:31 +00002055void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}
2056
Alexey Bataev74ba3a52014-07-17 12:47:03 +00002057void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}
2058
Alexey Bataevf98b00c2014-07-23 02:27:21 +00002059void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}
2060
Alexey Bataevdea47612014-07-23 07:46:59 +00002061void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}
2062
Alexey Bataev67a4f222014-07-23 10:25:33 +00002063void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}
2064
Alexey Bataev459dec02014-07-24 06:46:57 +00002065void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}
2066
Alexey Bataev82bad8b2014-07-24 08:55:34 +00002067void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
2068
Alexey Bataev346265e2015-09-25 10:37:12 +00002069void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
2070
Alexey Bataevd14d1e62015-09-28 06:39:35 +00002071void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
2072
Michael Wonge710d542015-08-07 16:16:36 +00002073void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
2074 Visitor->AddStmt(C->getDevice());
2075}
2076
Alexey Bataev756c1962013-09-24 03:17:45 +00002077template<typename T>
2078void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Alexey Bataev03b340a2014-10-21 03:16:40 +00002079 for (const auto *I : Node->varlists()) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00002080 Visitor->AddStmt(I);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002081 }
Alexey Bataev756c1962013-09-24 03:17:45 +00002082}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002083
2084void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002085 VisitOMPClauseList(C);
Alexey Bataev03b340a2014-10-21 03:16:40 +00002086 for (const auto *E : C->private_copies()) {
2087 Visitor->AddStmt(E);
2088 }
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002089}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00002090void OMPClauseEnqueue::VisitOMPFirstprivateClause(
2091 const OMPFirstprivateClause *C) {
2092 VisitOMPClauseList(C);
2093}
Alexander Musman1bb328c2014-06-04 13:06:39 +00002094void OMPClauseEnqueue::VisitOMPLastprivateClause(
2095 const OMPLastprivateClause *C) {
2096 VisitOMPClauseList(C);
Alexey Bataev38e89532015-04-16 04:54:05 +00002097 for (auto *E : C->private_copies()) {
2098 Visitor->AddStmt(E);
2099 }
2100 for (auto *E : C->source_exprs()) {
2101 Visitor->AddStmt(E);
2102 }
2103 for (auto *E : C->destination_exprs()) {
2104 Visitor->AddStmt(E);
2105 }
2106 for (auto *E : C->assignment_ops()) {
2107 Visitor->AddStmt(E);
2108 }
Alexander Musman1bb328c2014-06-04 13:06:39 +00002109}
Alexey Bataev758e55e2013-09-06 18:03:48 +00002110void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00002111 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00002112}
Alexey Bataevc5e02582014-06-16 07:08:35 +00002113void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
2114 VisitOMPClauseList(C);
Alexey Bataev794ba0d2015-04-10 10:43:45 +00002115 for (auto *E : C->lhs_exprs()) {
2116 Visitor->AddStmt(E);
2117 }
2118 for (auto *E : C->rhs_exprs()) {
2119 Visitor->AddStmt(E);
2120 }
2121 for (auto *E : C->reduction_ops()) {
2122 Visitor->AddStmt(E);
2123 }
Alexey Bataevc5e02582014-06-16 07:08:35 +00002124}
Alexander Musman8dba6642014-04-22 13:09:42 +00002125void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
2126 VisitOMPClauseList(C);
Alexey Bataevbd9fec12015-08-18 06:47:21 +00002127 for (const auto *E : C->privates()) {
2128 Visitor->AddStmt(E);
2129 }
Alexander Musman3276a272015-03-21 10:12:56 +00002130 for (const auto *E : C->inits()) {
2131 Visitor->AddStmt(E);
2132 }
2133 for (const auto *E : C->updates()) {
2134 Visitor->AddStmt(E);
2135 }
2136 for (const auto *E : C->finals()) {
2137 Visitor->AddStmt(E);
2138 }
Alexander Musman8dba6642014-04-22 13:09:42 +00002139 Visitor->AddStmt(C->getStep());
Alexander Musman3276a272015-03-21 10:12:56 +00002140 Visitor->AddStmt(C->getCalcStep());
Alexander Musman8dba6642014-04-22 13:09:42 +00002141}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00002142void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
2143 VisitOMPClauseList(C);
2144 Visitor->AddStmt(C->getAlignment());
2145}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002146void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
2147 VisitOMPClauseList(C);
Alexey Bataevf56f98c2015-04-16 05:39:01 +00002148 for (auto *E : C->source_exprs()) {
2149 Visitor->AddStmt(E);
2150 }
2151 for (auto *E : C->destination_exprs()) {
2152 Visitor->AddStmt(E);
2153 }
2154 for (auto *E : C->assignment_ops()) {
2155 Visitor->AddStmt(E);
2156 }
Alexey Bataevd48bcd82014-03-31 03:36:38 +00002157}
Alexey Bataevbae9a792014-06-27 10:37:06 +00002158void
2159OMPClauseEnqueue::VisitOMPCopyprivateClause(const OMPCopyprivateClause *C) {
2160 VisitOMPClauseList(C);
Alexey Bataeva63048e2015-03-23 06:18:07 +00002161 for (auto *E : C->source_exprs()) {
2162 Visitor->AddStmt(E);
2163 }
2164 for (auto *E : C->destination_exprs()) {
2165 Visitor->AddStmt(E);
2166 }
2167 for (auto *E : C->assignment_ops()) {
2168 Visitor->AddStmt(E);
2169 }
Alexey Bataevbae9a792014-06-27 10:37:06 +00002170}
Alexey Bataev6125da92014-07-21 11:26:11 +00002171void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
2172 VisitOMPClauseList(C);
2173}
Alexey Bataev1c2cfbc2015-06-23 14:25:19 +00002174void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
2175 VisitOMPClauseList(C);
2176}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002177}
Alexey Bataev756c1962013-09-24 03:17:45 +00002178
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002179void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
2180 unsigned size = WL.size();
2181 OMPClauseEnqueue Visitor(this);
2182 Visitor.Visit(S);
2183 if (size == WL.size())
2184 return;
2185 // Now reverse the entries we just added. This will match the DFS
2186 // ordering performed by the worklist.
2187 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2188 std::reverse(I, E);
2189}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
2192}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 AddDecl(B->getBlockDecl());
2195}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 EnqueueChildren(E);
2198 AddTypeLoc(E->getTypeSourceInfo());
2199}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
Pete Cooper57d3f142015-07-30 17:22:52 +00002201 for (auto &I : llvm::reverse(S->body()))
2202 AddStmt(I);
Guy Benyei11169dd2012-12-18 14:30:41 +00002203}
2204void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddStmt(S->getSubStmt());
2207 AddDeclarationNameInfo(S);
2208 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2209 AddNestedNameSpecifierLoc(QualifierLoc);
2210}
2211
2212void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2215 AddDeclarationNameInfo(E);
2216 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2217 AddNestedNameSpecifierLoc(QualifierLoc);
2218 if (!E->isImplicitAccess())
2219 AddStmt(E->getBase());
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 // Enqueue the initializer , if any.
2223 AddStmt(E->getInitializer());
2224 // Enqueue the array size, if any.
2225 AddStmt(E->getArraySize());
2226 // Enqueue the allocated type.
2227 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2228 // Enqueue the placement arguments.
2229 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2230 AddStmt(E->getPlacementArg(I-1));
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2234 AddStmt(CE->getArg(I-1));
2235 AddStmt(CE->getCallee());
2236 AddStmt(CE->getArg(0));
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2239 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 // Visit the name of the type being destroyed.
2241 AddTypeLoc(E->getDestroyedTypeInfo());
2242 // Visit the scope type that looks disturbingly like the nested-name-specifier
2243 // but isn't.
2244 AddTypeLoc(E->getScopeTypeInfo());
2245 // Visit the nested-name-specifier.
2246 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2247 AddNestedNameSpecifierLoc(QualifierLoc);
2248 // Visit base expression.
2249 AddStmt(E->getBase());
2250}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2252 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002253 AddTypeLoc(E->getTypeSourceInfo());
2254}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2256 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 EnqueueChildren(E);
2258 AddTypeLoc(E->getTypeSourceInfo());
2259}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 EnqueueChildren(E);
2262 if (E->isTypeOperand())
2263 AddTypeLoc(E->getTypeOperandSourceInfo());
2264}
2265
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002266void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2267 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002268 EnqueueChildren(E);
2269 AddTypeLoc(E->getTypeSourceInfo());
2270}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002271void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002272 EnqueueChildren(E);
2273 if (E->isTypeOperand())
2274 AddTypeLoc(E->getTypeOperandSourceInfo());
2275}
2276
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002277void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002278 EnqueueChildren(S);
2279 AddDecl(S->getExceptionDecl());
2280}
2281
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002282void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002283 AddStmt(S->getBody());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002284 AddStmt(S->getRangeInit());
Argyrios Kyrtzidiscde70692014-11-13 09:50:19 +00002285 AddDecl(S->getLoopVariable());
Argyrios Kyrtzidis99891242014-11-13 09:03:21 +00002286}
2287
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002288void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002289 if (DR->hasExplicitTemplateArgs()) {
2290 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2291 }
2292 WL.push_back(DeclRefExprParts(DR, Parent));
2293}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002294void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2295 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002296 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2297 AddDeclarationNameInfo(E);
2298 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2299}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002300void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002301 unsigned size = WL.size();
2302 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002303 for (const auto *D : S->decls()) {
2304 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002305 isFirst = false;
2306 }
2307 if (size == WL.size())
2308 return;
2309 // Now reverse the entries we just added. This will match the DFS
2310 // ordering performed by the worklist.
2311 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2312 std::reverse(I, E);
2313}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002316 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002317 D = E->designators_rbegin(), DEnd = E->designators_rend();
2318 D != DEnd; ++D) {
2319 if (D->isFieldDesignator()) {
2320 if (FieldDecl *Field = D->getField())
2321 AddMemberRef(Field, D->getFieldLoc());
2322 continue;
2323 }
2324 if (D->isArrayDesignator()) {
2325 AddStmt(E->getArrayIndex(*D));
2326 continue;
2327 }
2328 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2329 AddStmt(E->getArrayRangeEnd(*D));
2330 AddStmt(E->getArrayRangeStart(*D));
2331 }
2332}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 EnqueueChildren(E);
2335 AddTypeLoc(E->getTypeInfoAsWritten());
2336}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002337void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002338 AddStmt(FS->getBody());
2339 AddStmt(FS->getInc());
2340 AddStmt(FS->getCond());
2341 AddDecl(FS->getConditionVariable());
2342 AddStmt(FS->getInit());
2343}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002344void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002345 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2346}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002347void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002348 AddStmt(If->getElse());
2349 AddStmt(If->getThen());
2350 AddStmt(If->getCond());
2351 AddDecl(If->getConditionVariable());
2352}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002353void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002354 // We care about the syntactic form of the initializer list, only.
2355 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2356 IE = Syntactic;
2357 EnqueueChildren(IE);
2358}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002359void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002360 WL.push_back(MemberExprParts(M, Parent));
2361
2362 // If the base of the member access expression is an implicit 'this', don't
2363 // visit it.
2364 // FIXME: If we ever want to show these implicit accesses, this will be
2365 // unfortunate. However, clang_getCursor() relies on this behavior.
Argyrios Kyrtzidis58d0e7a2015-03-13 04:40:07 +00002366 if (M->isImplicitAccess())
2367 return;
2368
2369 // Ignore base anonymous struct/union fields, otherwise they will shadow the
2370 // real field that that we are interested in.
2371 if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
2372 if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
2373 if (FD->isAnonymousStructOrUnion()) {
2374 AddStmt(SubME->getBase());
2375 return;
2376 }
2377 }
2378 }
2379
2380 AddStmt(M->getBase());
Guy Benyei11169dd2012-12-18 14:30:41 +00002381}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002382void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002383 AddTypeLoc(E->getEncodedTypeSourceInfo());
2384}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002385void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002386 EnqueueChildren(M);
2387 AddTypeLoc(M->getClassReceiverTypeInfo());
2388}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002389void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002390 // Visit the components of the offsetof expression.
2391 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2392 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2393 const OffsetOfNode &Node = E->getComponent(I-1);
2394 switch (Node.getKind()) {
2395 case OffsetOfNode::Array:
2396 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2397 break;
2398 case OffsetOfNode::Field:
2399 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2400 break;
2401 case OffsetOfNode::Identifier:
2402 case OffsetOfNode::Base:
2403 continue;
2404 }
2405 }
2406 // Visit the type into which we're computing the offset.
2407 AddTypeLoc(E->getTypeSourceInfo());
2408}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002409void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002410 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2411 WL.push_back(OverloadExprParts(E, Parent));
2412}
2413void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002414 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002415 EnqueueChildren(E);
2416 if (E->isArgumentType())
2417 AddTypeLoc(E->getArgumentTypeInfo());
2418}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002419void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002420 EnqueueChildren(S);
2421}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002422void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002423 AddStmt(S->getBody());
2424 AddStmt(S->getCond());
2425 AddDecl(S->getConditionVariable());
2426}
2427
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002428void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002429 AddStmt(W->getBody());
2430 AddStmt(W->getCond());
2431 AddDecl(W->getConditionVariable());
2432}
2433
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002434void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002435 for (unsigned I = E->getNumArgs(); I > 0; --I)
2436 AddTypeLoc(E->getArg(I-1));
2437}
2438
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002439void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002440 AddTypeLoc(E->getQueriedTypeSourceInfo());
2441}
2442
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002443void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002444 EnqueueChildren(E);
2445}
2446
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002447void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002448 VisitOverloadExpr(U);
2449 if (!U->isImplicitAccess())
2450 AddStmt(U->getBase());
2451}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002452void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002453 AddStmt(E->getSubExpr());
2454 AddTypeLoc(E->getWrittenTypeInfo());
2455}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002456void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002457 WL.push_back(SizeOfPackExprParts(E, Parent));
2458}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002459void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 // If the opaque value has a source expression, just transparently
2461 // visit that. This is useful for (e.g.) pseudo-object expressions.
2462 if (Expr *SourceExpr = E->getSourceExpr())
2463 return Visit(SourceExpr);
2464}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002465void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002466 AddStmt(E->getBody());
2467 WL.push_back(LambdaExprParts(E, Parent));
2468}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002469void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002470 // Treat the expression like its syntactic form.
2471 Visit(E->getSyntacticForm());
2472}
2473
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002474void EnqueueVisitor::VisitOMPExecutableDirective(
2475 const OMPExecutableDirective *D) {
2476 EnqueueChildren(D);
2477 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2478 E = D->clauses().end();
2479 I != E; ++I)
2480 EnqueueChildren(*I);
2481}
2482
Alexander Musman3aaab662014-08-19 11:27:13 +00002483void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
2484 VisitOMPExecutableDirective(D);
2485}
2486
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002487void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2488 VisitOMPExecutableDirective(D);
2489}
2490
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002491void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002492 VisitOMPLoopDirective(D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002493}
2494
Alexey Bataevf29276e2014-06-18 04:14:57 +00002495void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002496 VisitOMPLoopDirective(D);
Alexey Bataevf29276e2014-06-18 04:14:57 +00002497}
2498
Alexander Musmanf82886e2014-09-18 05:12:34 +00002499void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
2500 VisitOMPLoopDirective(D);
2501}
2502
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00002503void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
2504 VisitOMPExecutableDirective(D);
2505}
2506
Alexey Bataev1e0498a2014-06-26 08:21:58 +00002507void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
2508 VisitOMPExecutableDirective(D);
2509}
2510
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00002511void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
2512 VisitOMPExecutableDirective(D);
2513}
2514
Alexander Musman80c22892014-07-17 08:54:58 +00002515void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
2516 VisitOMPExecutableDirective(D);
2517}
2518
Alexander Musmand9ed09f2014-07-21 09:42:05 +00002519void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
2520 VisitOMPExecutableDirective(D);
2521 AddDeclarationNameInfo(D);
2522}
2523
Alexey Bataev4acb8592014-07-07 13:01:15 +00002524void
2525EnqueueVisitor::VisitOMPParallelForDirective(const OMPParallelForDirective *D) {
Alexander Musman3aaab662014-08-19 11:27:13 +00002526 VisitOMPLoopDirective(D);
Alexey Bataev4acb8592014-07-07 13:01:15 +00002527}
2528
Alexander Musmane4e893b2014-09-23 09:33:00 +00002529void EnqueueVisitor::VisitOMPParallelForSimdDirective(
2530 const OMPParallelForSimdDirective *D) {
2531 VisitOMPLoopDirective(D);
2532}
2533
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00002534void EnqueueVisitor::VisitOMPParallelSectionsDirective(
2535 const OMPParallelSectionsDirective *D) {
2536 VisitOMPExecutableDirective(D);
2537}
2538
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00002539void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
2540 VisitOMPExecutableDirective(D);
2541}
2542
Alexey Bataev68446b72014-07-18 07:47:19 +00002543void
2544EnqueueVisitor::VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D) {
2545 VisitOMPExecutableDirective(D);
2546}
2547
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00002548void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
2549 VisitOMPExecutableDirective(D);
2550}
2551
Alexey Bataev2df347a2014-07-18 10:17:07 +00002552void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
2553 VisitOMPExecutableDirective(D);
2554}
2555
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00002556void EnqueueVisitor::VisitOMPTaskgroupDirective(
2557 const OMPTaskgroupDirective *D) {
2558 VisitOMPExecutableDirective(D);
2559}
2560
Alexey Bataev6125da92014-07-21 11:26:11 +00002561void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
2562 VisitOMPExecutableDirective(D);
2563}
2564
Alexey Bataev9fb6e642014-07-22 06:45:04 +00002565void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
2566 VisitOMPExecutableDirective(D);
2567}
2568
Alexey Bataev0162e452014-07-22 10:10:35 +00002569void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
2570 VisitOMPExecutableDirective(D);
2571}
2572
Alexey Bataev0bd520b2014-09-19 08:19:49 +00002573void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
2574 VisitOMPExecutableDirective(D);
2575}
2576
Michael Wong65f367f2015-07-21 13:44:28 +00002577void EnqueueVisitor::VisitOMPTargetDataDirective(const
2578 OMPTargetDataDirective *D) {
2579 VisitOMPExecutableDirective(D);
2580}
2581
Alexey Bataev13314bf2014-10-09 04:18:56 +00002582void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
2583 VisitOMPExecutableDirective(D);
2584}
2585
Alexey Bataev6d4ed052015-07-01 06:57:41 +00002586void EnqueueVisitor::VisitOMPCancellationPointDirective(
2587 const OMPCancellationPointDirective *D) {
2588 VisitOMPExecutableDirective(D);
2589}
2590
Alexey Bataev80909872015-07-02 11:25:17 +00002591void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
2592 VisitOMPExecutableDirective(D);
2593}
2594
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002595void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002596 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2597}
2598
2599bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2600 if (RegionOfInterest.isValid()) {
2601 SourceRange Range = getRawCursorExtent(C);
2602 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2603 return false;
2604 }
2605 return true;
2606}
2607
2608bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2609 while (!WL.empty()) {
2610 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002611 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002612
2613 // Set the Parent field, then back to its old value once we're done.
2614 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2615
2616 switch (LI.getKind()) {
2617 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002618 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002619 if (!D)
2620 continue;
2621
2622 // For now, perform default visitation for Decls.
2623 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2624 cast<DeclVisit>(&LI)->isFirst())))
2625 return true;
2626
2627 continue;
2628 }
2629 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2630 const ASTTemplateArgumentListInfo *ArgList =
2631 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2632 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2633 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2634 Arg != ArgEnd; ++Arg) {
2635 if (VisitTemplateArgumentLoc(*Arg))
2636 return true;
2637 }
2638 continue;
2639 }
2640 case VisitorJob::TypeLocVisitKind: {
2641 // Perform default visitation for TypeLocs.
2642 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2643 return true;
2644 continue;
2645 }
2646 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002647 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002648 if (LabelStmt *stmt = LS->getStmt()) {
2649 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2650 TU))) {
2651 return true;
2652 }
2653 }
2654 continue;
2655 }
2656
2657 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2658 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2659 if (VisitNestedNameSpecifierLoc(V->get()))
2660 return true;
2661 continue;
2662 }
2663
2664 case VisitorJob::DeclarationNameInfoVisitKind: {
2665 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2666 ->get()))
2667 return true;
2668 continue;
2669 }
2670 case VisitorJob::MemberRefVisitKind: {
2671 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2672 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2673 return true;
2674 continue;
2675 }
2676 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002677 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002678 if (!S)
2679 continue;
2680
2681 // Update the current cursor.
2682 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2683 if (!IsInRegionOfInterest(Cursor))
2684 continue;
2685 switch (Visitor(Cursor, Parent, ClientData)) {
2686 case CXChildVisit_Break: return true;
2687 case CXChildVisit_Continue: break;
2688 case CXChildVisit_Recurse:
2689 if (PostChildrenVisitor)
Craig Topper69186e72014-06-08 08:38:04 +00002690 WL.push_back(PostChildrenVisit(nullptr, Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +00002691 EnqueueWorkList(WL, S);
2692 break;
2693 }
2694 continue;
2695 }
2696 case VisitorJob::MemberExprPartsKind: {
2697 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002698 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002699
2700 // Visit the nested-name-specifier
2701 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2702 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2703 return true;
2704
2705 // Visit the declaration name.
2706 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2707 return true;
2708
2709 // Visit the explicitly-specified template arguments, if any.
2710 if (M->hasExplicitTemplateArgs()) {
2711 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2712 *ArgEnd = Arg + M->getNumTemplateArgs();
2713 Arg != ArgEnd; ++Arg) {
2714 if (VisitTemplateArgumentLoc(*Arg))
2715 return true;
2716 }
2717 }
2718 continue;
2719 }
2720 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002721 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002722 // Visit nested-name-specifier, if present.
2723 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2724 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2725 return true;
2726 // Visit declaration name.
2727 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2728 return true;
2729 continue;
2730 }
2731 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002732 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002733 // Visit the nested-name-specifier.
2734 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2735 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2736 return true;
2737 // Visit the declaration name.
2738 if (VisitDeclarationNameInfo(O->getNameInfo()))
2739 return true;
2740 // Visit the overloaded declaration reference.
2741 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2742 return true;
2743 continue;
2744 }
2745 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002746 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002747 NamedDecl *Pack = E->getPack();
2748 if (isa<TemplateTypeParmDecl>(Pack)) {
2749 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2750 E->getPackLoc(), TU)))
2751 return true;
2752
2753 continue;
2754 }
2755
2756 if (isa<TemplateTemplateParmDecl>(Pack)) {
2757 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2758 E->getPackLoc(), TU)))
2759 return true;
2760
2761 continue;
2762 }
2763
2764 // Non-type template parameter packs and function parameter packs are
2765 // treated like DeclRefExpr cursors.
2766 continue;
2767 }
2768
2769 case VisitorJob::LambdaExprPartsKind: {
2770 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002771 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002772 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2773 CEnd = E->explicit_capture_end();
2774 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002775 // FIXME: Lambda init-captures.
2776 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002777 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002778
Guy Benyei11169dd2012-12-18 14:30:41 +00002779 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2780 C->getLocation(),
2781 TU)))
2782 return true;
2783 }
2784
2785 // Visit parameters and return type, if present.
2786 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2787 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2788 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2789 // Visit the whole type.
2790 if (Visit(TL))
2791 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002792 } else if (FunctionProtoTypeLoc Proto =
2793 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002794 if (E->hasExplicitParameters()) {
2795 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002796 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2797 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002798 return true;
2799 } else {
2800 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002801 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002802 return true;
2803 }
2804 }
2805 }
2806 break;
2807 }
2808
2809 case VisitorJob::PostChildrenVisitKind:
2810 if (PostChildrenVisitor(Parent, ClientData))
2811 return true;
2812 break;
2813 }
2814 }
2815 return false;
2816}
2817
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002818bool CursorVisitor::Visit(const Stmt *S) {
Craig Topper69186e72014-06-08 08:38:04 +00002819 VisitorWorkList *WL = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00002820 if (!WorkListFreeList.empty()) {
2821 WL = WorkListFreeList.back();
2822 WL->clear();
2823 WorkListFreeList.pop_back();
2824 }
2825 else {
2826 WL = new VisitorWorkList();
2827 WorkListCache.push_back(WL);
2828 }
2829 EnqueueWorkList(*WL, S);
2830 bool result = RunVisitorWorkList(*WL);
2831 WorkListFreeList.push_back(WL);
2832 return result;
2833}
2834
2835namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002836typedef SmallVector<SourceRange, 4> RefNamePieces;
Craig Topper69186e72014-06-08 08:38:04 +00002837RefNamePieces
2838buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2839 const DeclarationNameInfo &NI, const SourceRange &QLoc,
2840 const ASTTemplateArgumentListInfo *TemplateArgs = nullptr) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002841 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2842 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2843 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2844
2845 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2846
2847 RefNamePieces Pieces;
2848
2849 if (WantQualifier && QLoc.isValid())
2850 Pieces.push_back(QLoc);
2851
2852 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2853 Pieces.push_back(NI.getLoc());
2854
2855 if (WantTemplateArgs && TemplateArgs)
2856 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2857 TemplateArgs->RAngleLoc));
2858
2859 if (Kind == DeclarationName::CXXOperatorName) {
2860 Pieces.push_back(SourceLocation::getFromRawEncoding(
2861 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2862 Pieces.push_back(SourceLocation::getFromRawEncoding(
2863 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2864 }
2865
2866 if (WantSinglePiece) {
2867 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2868 Pieces.clear();
2869 Pieces.push_back(R);
2870 }
2871
2872 return Pieces;
2873}
Alexander Kornienkoab9db512015-06-22 23:07:51 +00002874}
Guy Benyei11169dd2012-12-18 14:30:41 +00002875
2876//===----------------------------------------------------------------------===//
2877// Misc. API hooks.
2878//===----------------------------------------------------------------------===//
2879
Chad Rosier05c71aa2013-03-27 18:28:23 +00002880static void fatal_error_handler(void *user_data, const std::string& reason,
2881 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002882 // Write the result out to stderr avoiding errs() because raw_ostreams can
2883 // call report_fatal_error.
2884 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2885 ::abort();
2886}
2887
Chandler Carruth66660742014-06-27 16:37:27 +00002888namespace {
2889struct RegisterFatalErrorHandler {
2890 RegisterFatalErrorHandler() {
2891 llvm::install_fatal_error_handler(fatal_error_handler, nullptr);
2892 }
2893};
2894}
2895
2896static llvm::ManagedStatic<RegisterFatalErrorHandler> RegisterFatalErrorHandlerOnce;
2897
Guy Benyei11169dd2012-12-18 14:30:41 +00002898extern "C" {
2899CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2900 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002901 // We use crash recovery to make some of our APIs more reliable, implicitly
2902 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002903 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2904 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002905
Chandler Carruth66660742014-06-27 16:37:27 +00002906 // Look through the managed static to trigger construction of the managed
2907 // static which registers our fatal error handler. This ensures it is only
2908 // registered once.
2909 (void)*RegisterFatalErrorHandlerOnce;
Guy Benyei11169dd2012-12-18 14:30:41 +00002910
Adrian Prantlbc068582015-07-08 01:00:30 +00002911 // Initialize targets for clang module support.
2912 llvm::InitializeAllTargets();
2913 llvm::InitializeAllTargetMCs();
2914 llvm::InitializeAllAsmPrinters();
2915 llvm::InitializeAllAsmParsers();
2916
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002917 CIndexer *CIdxr = new CIndexer();
2918
Guy Benyei11169dd2012-12-18 14:30:41 +00002919 if (excludeDeclarationsFromPCH)
2920 CIdxr->setOnlyLocalDecls();
2921 if (displayDiagnostics)
2922 CIdxr->setDisplayDiagnostics();
2923
2924 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2925 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2926 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2927 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2928 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2929 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2930
2931 return CIdxr;
2932}
2933
2934void clang_disposeIndex(CXIndex CIdx) {
2935 if (CIdx)
2936 delete static_cast<CIndexer *>(CIdx);
2937}
2938
2939void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2940 if (CIdx)
2941 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2942}
2943
2944unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2945 if (CIdx)
2946 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2947 return 0;
2948}
2949
2950void clang_toggleCrashRecovery(unsigned isEnabled) {
2951 if (isEnabled)
2952 llvm::CrashRecoveryContext::Enable();
2953 else
2954 llvm::CrashRecoveryContext::Disable();
2955}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002956
Guy Benyei11169dd2012-12-18 14:30:41 +00002957CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2958 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002959 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002960 enum CXErrorCode Result =
2961 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002962 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002963 assert((TU && Result == CXError_Success) ||
2964 (!TU && Result != CXError_Success));
2965 return TU;
2966}
2967
2968enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2969 const char *ast_filename,
2970 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002971 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00002972 *out_TU = nullptr;
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002973
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002974 if (!CIdx || !ast_filename || !out_TU)
2975 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002976
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002977 LOG_FUNC_SECTION {
2978 *Log << ast_filename;
2979 }
2980
Guy Benyei11169dd2012-12-18 14:30:41 +00002981 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2982 FileSystemOptions FileSystemOpts;
2983
Justin Bognerd512c1e2014-10-15 00:33:06 +00002984 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
2985 CompilerInstance::createDiagnostics(new DiagnosticOptions());
David Blaikie6f7382d2014-08-10 19:08:04 +00002986 std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
Adrian Prantlfb2398d2015-07-17 01:19:54 +00002987 ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(), Diags,
Adrian Prantl6b21ab22015-08-27 19:46:20 +00002988 FileSystemOpts, /*UseDebugInfo=*/false,
2989 CXXIdx->getOnlyLocalDecls(), None,
David Blaikie6f7382d2014-08-10 19:08:04 +00002990 /*CaptureDiagnostics=*/true,
2991 /*AllowPCHWithCompilerErrors=*/true,
2992 /*UserFilesAreVolatile=*/true);
2993 *out_TU = MakeCXTranslationUnit(CXXIdx, AU.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002994 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002995}
2996
2997unsigned clang_defaultEditingTranslationUnitOptions() {
2998 return CXTranslationUnit_PrecompiledPreamble |
2999 CXTranslationUnit_CacheCompletionResults;
3000}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003001
Guy Benyei11169dd2012-12-18 14:30:41 +00003002CXTranslationUnit
3003clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
3004 const char *source_filename,
3005 int num_command_line_args,
3006 const char * const *command_line_args,
3007 unsigned num_unsaved_files,
3008 struct CXUnsavedFile *unsaved_files) {
3009 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
3010 return clang_parseTranslationUnit(CIdx, source_filename,
3011 command_line_args, num_command_line_args,
3012 unsaved_files, num_unsaved_files,
3013 Options);
3014}
3015
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003016static CXErrorCode
3017clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
3018 const char *const *command_line_args,
3019 int num_command_line_args,
3020 ArrayRef<CXUnsavedFile> unsaved_files,
3021 unsigned options, CXTranslationUnit *out_TU) {
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003022 // Set up the initial return values.
3023 if (out_TU)
Craig Topper69186e72014-06-08 08:38:04 +00003024 *out_TU = nullptr;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003025
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003026 // Check arguments.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003027 if (!CIdx || !out_TU)
3028 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003029
Guy Benyei11169dd2012-12-18 14:30:41 +00003030 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
3031
3032 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3033 setThreadBackgroundPriority();
3034
3035 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
3036 // FIXME: Add a flag for modules.
3037 TranslationUnitKind TUKind
3038 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00003039 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00003040 = options & CXTranslationUnit_CacheCompletionResults;
3041 bool IncludeBriefCommentsInCodeCompletion
3042 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
3043 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
3044 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
3045
3046 // Configure the diagnostics.
3047 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00003048 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00003049
3050 // Recover resources if we crash before exiting this function.
3051 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
3052 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
Alp Tokerf994cef2014-07-05 03:08:06 +00003053 DiagCleanup(Diags.get());
Guy Benyei11169dd2012-12-18 14:30:41 +00003054
Ahmed Charlesb8984322014-03-07 20:03:18 +00003055 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3056 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003057
3058 // Recover resources if we crash before exiting this function.
3059 llvm::CrashRecoveryContextCleanupRegistrar<
3060 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3061
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003062 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003063 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003064 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003065 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003066 }
3067
Ahmed Charlesb8984322014-03-07 20:03:18 +00003068 std::unique_ptr<std::vector<const char *>> Args(
3069 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00003070
3071 // Recover resources if we crash before exiting this method.
3072 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
3073 ArgsCleanup(Args.get());
3074
3075 // Since the Clang C library is primarily used by batch tools dealing with
3076 // (often very broken) source code, where spell-checking can have a
3077 // significant negative impact on performance (particularly when
3078 // precompiled headers are involved), we disable it by default.
3079 // Only do this if we haven't found a spell-checking-related argument.
3080 bool FoundSpellCheckingArgument = false;
3081 for (int I = 0; I != num_command_line_args; ++I) {
3082 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
3083 strcmp(command_line_args[I], "-fspell-checking") == 0) {
3084 FoundSpellCheckingArgument = true;
3085 break;
3086 }
3087 }
3088 if (!FoundSpellCheckingArgument)
3089 Args->push_back("-fno-spell-checking");
3090
3091 Args->insert(Args->end(), command_line_args,
3092 command_line_args + num_command_line_args);
3093
3094 // The 'source_filename' argument is optional. If the caller does not
3095 // specify it then it is assumed that the source file is specified
3096 // in the actual argument list.
3097 // Put the source file after command_line_args otherwise if '-x' flag is
3098 // present it will be unused.
3099 if (source_filename)
3100 Args->push_back(source_filename);
3101
3102 // Do we need the detailed preprocessing record?
3103 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
3104 Args->push_back("-Xclang");
3105 Args->push_back("-detailed-preprocessing-record");
3106 }
3107
3108 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00003109 std::unique_ptr<ASTUnit> ErrUnit;
3110 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003111 Args->data(), Args->data() + Args->size(),
3112 CXXIdx->getPCHContainerOperations(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00003113 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
3114 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
3115 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
3116 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
3117 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
3118 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00003119
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003120 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003121 if (!Unit && !ErrUnit)
3122 return CXError_ASTReadError;
Artem Belevich0ff05cd2015-07-13 23:27:56 +00003123
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 if (NumErrors != Diags->getClient()->getNumErrors()) {
3125 // Make sure to check that 'Unit' is non-NULL.
3126 if (CXXIdx->getDisplayDiagnostics())
3127 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
3128 }
3129
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003130 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
3131 return CXError_ASTReadError;
3132
3133 *out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
3134 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003135}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003136
3137CXTranslationUnit
3138clang_parseTranslationUnit(CXIndex CIdx,
3139 const char *source_filename,
3140 const char *const *command_line_args,
3141 int num_command_line_args,
3142 struct CXUnsavedFile *unsaved_files,
3143 unsigned num_unsaved_files,
3144 unsigned options) {
3145 CXTranslationUnit TU;
3146 enum CXErrorCode Result = clang_parseTranslationUnit2(
3147 CIdx, source_filename, command_line_args, num_command_line_args,
3148 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00003149 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00003150 assert((TU && Result == CXError_Success) ||
3151 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003152 return TU;
3153}
3154
3155enum CXErrorCode clang_parseTranslationUnit2(
3156 CXIndex CIdx,
3157 const char *source_filename,
3158 const char *const *command_line_args,
3159 int num_command_line_args,
3160 struct CXUnsavedFile *unsaved_files,
3161 unsigned num_unsaved_files,
3162 unsigned options,
3163 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003164 LOG_FUNC_SECTION {
3165 *Log << source_filename << ": ";
3166 for (int i = 0; i != num_command_line_args; ++i)
3167 *Log << command_line_args[i] << " ";
3168 }
3169
Alp Toker9d85b182014-07-07 01:23:14 +00003170 if (num_unsaved_files && !unsaved_files)
3171 return CXError_InvalidArguments;
3172
Alp Toker5c532982014-07-07 22:42:03 +00003173 CXErrorCode result = CXError_Failure;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003174 auto ParseTranslationUnitImpl = [=, &result] {
3175 result = clang_parseTranslationUnit_Impl(
3176 CIdx, source_filename, command_line_args, num_command_line_args,
3177 llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
3178 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 llvm::CrashRecoveryContext CRC;
3180
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003181 if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 fprintf(stderr, "libclang: crash detected during parsing: {\n");
3183 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
3184 fprintf(stderr, " 'command_line_args' : [");
3185 for (int i = 0; i != num_command_line_args; ++i) {
3186 if (i)
3187 fprintf(stderr, ", ");
3188 fprintf(stderr, "'%s'", command_line_args[i]);
3189 }
3190 fprintf(stderr, "],\n");
3191 fprintf(stderr, " 'unsaved_files' : [");
3192 for (unsigned i = 0; i != num_unsaved_files; ++i) {
3193 if (i)
3194 fprintf(stderr, ", ");
3195 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
3196 unsaved_files[i].Length);
3197 }
3198 fprintf(stderr, "],\n");
3199 fprintf(stderr, " 'options' : %d,\n", options);
3200 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003201
3202 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003204 if (CXTranslationUnit *TU = out_TU)
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003205 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 }
Alp Toker5c532982014-07-07 22:42:03 +00003207
3208 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003209}
3210
3211unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
3212 return CXSaveTranslationUnit_None;
3213}
3214
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003215static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
3216 const char *FileName,
3217 unsigned options) {
3218 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
3220 setThreadBackgroundPriority();
3221
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003222 bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
3223 return hadError ? CXSaveError_Unknown : CXSaveError_None;
Guy Benyei11169dd2012-12-18 14:30:41 +00003224}
3225
3226int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
3227 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003228 LOG_FUNC_SECTION {
3229 *Log << TU << ' ' << FileName;
3230 }
3231
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003232 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003233 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003234 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003235 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003236
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003237 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003238 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3239 if (!CXXUnit->hasSema())
3240 return CXSaveError_InvalidTU;
3241
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003242 CXSaveError result;
3243 auto SaveTranslationUnitImpl = [=, &result]() {
3244 result = clang_saveTranslationUnit_Impl(TU, FileName, options);
3245 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003246
3247 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
3248 getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003249 SaveTranslationUnitImpl();
Guy Benyei11169dd2012-12-18 14:30:41 +00003250
3251 if (getenv("LIBCLANG_RESOURCE_USAGE"))
3252 PrintLibclangResourceUsage(TU);
3253
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003254 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003255 }
3256
3257 // We have an AST that has invalid nodes due to compiler errors.
3258 // Use a crash recovery thread for protection.
3259
3260 llvm::CrashRecoveryContext CRC;
3261
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003262 if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
3264 fprintf(stderr, " 'filename' : '%s'\n", FileName);
3265 fprintf(stderr, " 'options' : %d,\n", options);
3266 fprintf(stderr, "}\n");
3267
3268 return CXSaveError_Unknown;
3269
3270 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
3271 PrintLibclangResourceUsage(TU);
3272 }
3273
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003274 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003275}
3276
3277void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
3278 if (CTUnit) {
3279 // If the translation unit has been marked as unsafe to free, just discard
3280 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003281 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
3282 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 return;
3284
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003285 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00003286 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
3288 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00003289 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 delete CTUnit;
3291 }
3292}
3293
3294unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
3295 return CXReparse_None;
3296}
3297
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003298static CXErrorCode
3299clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
3300 ArrayRef<CXUnsavedFile> unsaved_files,
3301 unsigned options) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003302 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003303 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003304 LOG_BAD_TU(TU);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003305 return CXError_InvalidArguments;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003306 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003307
3308 // Reset the associated diagnostics.
3309 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
Craig Topper69186e72014-06-08 08:38:04 +00003310 TU->Diagnostics = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003311
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003312 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3314 setThreadBackgroundPriority();
3315
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003316 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003318
3319 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3320 new std::vector<ASTUnit::RemappedFile>());
3321
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 // Recover resources if we crash before exiting this function.
3323 llvm::CrashRecoveryContextCleanupRegistrar<
3324 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
Alp Toker9d85b182014-07-07 01:23:14 +00003325
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003326 for (auto &UF : unsaved_files) {
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003327 std::unique_ptr<llvm::MemoryBuffer> MB =
Alp Toker9d85b182014-07-07 01:23:14 +00003328 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
Rafael Espindolad87f8d72014-08-27 20:03:29 +00003329 RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003331
Adrian Prantlbb165fb2015-06-20 18:53:08 +00003332 if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
3333 *RemappedFiles.get()))
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003334 return CXError_Success;
3335 if (isASTReadError(CXXUnit))
3336 return CXError_ASTReadError;
3337 return CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338}
3339
3340int clang_reparseTranslationUnit(CXTranslationUnit TU,
3341 unsigned num_unsaved_files,
3342 struct CXUnsavedFile *unsaved_files,
3343 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003344 LOG_FUNC_SECTION {
3345 *Log << TU;
3346 }
3347
Alp Toker9d85b182014-07-07 01:23:14 +00003348 if (num_unsaved_files && !unsaved_files)
3349 return CXError_InvalidArguments;
3350
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003351 CXErrorCode result;
3352 auto ReparseTranslationUnitImpl = [=, &result]() {
3353 result = clang_reparseTranslationUnit_Impl(
3354 TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
3355 };
Guy Benyei11169dd2012-12-18 14:30:41 +00003356
3357 if (getenv("LIBCLANG_NOTHREADS")) {
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003358 ReparseTranslationUnitImpl();
Alp Toker5c532982014-07-07 22:42:03 +00003359 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 }
3361
3362 llvm::CrashRecoveryContext CRC;
3363
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00003364 if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003366 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003367 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3369 PrintLibclangResourceUsage(TU);
3370
Alp Toker5c532982014-07-07 22:42:03 +00003371 return result;
Guy Benyei11169dd2012-12-18 14:30:41 +00003372}
3373
3374
3375CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003376 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003377 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003378 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003379 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003380
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003381 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003382 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003383}
3384
3385CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003386 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003387 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003388 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003389 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003390
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003391 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3393}
3394
3395} // end: extern "C"
3396
3397//===----------------------------------------------------------------------===//
3398// CXFile Operations.
3399//===----------------------------------------------------------------------===//
3400
3401extern "C" {
3402CXString clang_getFileName(CXFile SFile) {
3403 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003404 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003405
3406 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003407 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003408}
3409
3410time_t clang_getFileTime(CXFile SFile) {
3411 if (!SFile)
3412 return 0;
3413
3414 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3415 return FEnt->getModificationTime();
3416}
3417
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003418CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003419 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003420 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00003421 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003422 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003423
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003424 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003425
3426 FileManager &FMgr = CXXUnit->getFileManager();
3427 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3428}
3429
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003430unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3431 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003432 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003433 LOG_BAD_TU(TU);
3434 return 0;
3435 }
3436
3437 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 return 0;
3439
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003440 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 FileEntry *FEnt = static_cast<FileEntry *>(file);
3442 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3443 .isFileMultipleIncludeGuarded(FEnt);
3444}
3445
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003446int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3447 if (!file || !outID)
3448 return 1;
3449
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003450 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003451 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3452 outID->data[0] = ID.getDevice();
3453 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003454 outID->data[2] = FEnt->getModificationTime();
3455 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003456}
3457
Argyrios Kyrtzidisac3997e2014-08-16 00:26:19 +00003458int clang_File_isEqual(CXFile file1, CXFile file2) {
3459 if (file1 == file2)
3460 return true;
3461
3462 if (!file1 || !file2)
3463 return false;
3464
3465 FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
3466 FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
3467 return FEnt1->getUniqueID() == FEnt2->getUniqueID();
3468}
3469
Guy Benyei11169dd2012-12-18 14:30:41 +00003470} // end: extern "C"
3471
3472//===----------------------------------------------------------------------===//
3473// CXCursor Operations.
3474//===----------------------------------------------------------------------===//
3475
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003476static const Decl *getDeclFromExpr(const Stmt *E) {
3477 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 return getDeclFromExpr(CE->getSubExpr());
3479
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003480 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003482 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003484 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003486 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 if (PRE->isExplicitProperty())
3488 return PRE->getExplicitProperty();
3489 // It could be messaging both getter and setter as in:
3490 // ++myobj.myprop;
3491 // in which case prefer to associate the setter since it is less obvious
3492 // from inspecting the source that the setter is going to get called.
3493 if (PRE->isMessagingSetter())
3494 return PRE->getImplicitPropertySetter();
3495 return PRE->getImplicitPropertyGetter();
3496 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003497 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 if (Expr *Src = OVE->getSourceExpr())
3501 return getDeclFromExpr(Src);
3502
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003503 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003505 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 if (!CE->isElidable())
3507 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003508 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 return OME->getMethodDecl();
3510
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003511 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003513 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003514 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3515 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003516 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3518 isa<ParmVarDecl>(SizeOfPack->getPack()))
3519 return SizeOfPack->getPack();
Craig Topper69186e72014-06-08 08:38:04 +00003520
3521 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00003522}
3523
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003524static SourceLocation getLocationFromExpr(const Expr *E) {
3525 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003526 return getLocationFromExpr(CE->getSubExpr());
3527
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003528 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003529 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003530 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003532 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003534 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003536 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003538 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 return PropRef->getLocation();
3540
3541 return E->getLocStart();
3542}
3543
3544extern "C" {
3545
3546unsigned clang_visitChildren(CXCursor parent,
3547 CXCursorVisitor visitor,
3548 CXClientData client_data) {
3549 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3550 /*VisitPreprocessorLast=*/false);
3551 return CursorVis.VisitChildren(parent);
3552}
3553
3554#ifndef __has_feature
3555#define __has_feature(x) 0
3556#endif
3557#if __has_feature(blocks)
3558typedef enum CXChildVisitResult
3559 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3560
3561static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3562 CXClientData client_data) {
3563 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3564 return block(cursor, parent);
3565}
3566#else
3567// If we are compiled with a compiler that doesn't have native blocks support,
3568// define and call the block manually, so the
3569typedef struct _CXChildVisitResult
3570{
3571 void *isa;
3572 int flags;
3573 int reserved;
3574 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3575 CXCursor);
3576} *CXCursorVisitorBlock;
3577
3578static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3579 CXClientData client_data) {
3580 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3581 return block->invoke(block, cursor, parent);
3582}
3583#endif
3584
3585
3586unsigned clang_visitChildrenWithBlock(CXCursor parent,
3587 CXCursorVisitorBlock block) {
3588 return clang_visitChildren(parent, visitWithBlock, block);
3589}
3590
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003591static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003593 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003594
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003595 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003597 if (const ObjCPropertyImplDecl *PropImpl =
3598 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003600 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003601
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003602 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003604 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003605
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003606 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 }
3608
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003609 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003610 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003611
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003612 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3614 // and returns different names. NamedDecl returns the class name and
3615 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003616 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003617
3618 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003619 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003620
3621 SmallString<1024> S;
3622 llvm::raw_svector_ostream os(S);
3623 ND->printName(os);
3624
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003625 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003626}
3627
3628CXString clang_getCursorSpelling(CXCursor C) {
3629 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003630 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003631
3632 if (clang_isReference(C.kind)) {
3633 switch (C.kind) {
3634 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003635 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 }
3638 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003639 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 }
3642 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003643 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 }
3647 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003648 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003649 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 }
3651 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003652 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 assert(Type && "Missing type decl");
3654
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003655 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 getAsString());
3657 }
3658 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003659 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 assert(Template && "Missing template decl");
3661
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003662 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 }
3664
3665 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003666 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 assert(NS && "Missing namespace decl");
3668
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003669 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 }
3671
3672 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003673 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 assert(Field && "Missing member decl");
3675
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003676 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 }
3678
3679 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003680 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 assert(Label && "Missing label");
3682
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 }
3685
3686 case CXCursor_OverloadedDeclRef: {
3687 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003688 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3689 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003690 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003691 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003693 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003694 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 OverloadedTemplateStorage *Ovl
3696 = Storage.get<OverloadedTemplateStorage*>();
3697 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003698 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003699 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 }
3701
3702 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003703 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 assert(Var && "Missing variable decl");
3705
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003706 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 }
3708
3709 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 }
3712 }
3713
3714 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003715 const Expr *E = getCursorExpr(C);
3716
3717 if (C.kind == CXCursor_ObjCStringLiteral ||
3718 C.kind == CXCursor_StringLiteral) {
3719 const StringLiteral *SLit;
3720 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3721 SLit = OSL->getString();
3722 } else {
3723 SLit = cast<StringLiteral>(E);
3724 }
3725 SmallString<256> Buf;
3726 llvm::raw_svector_ostream OS(Buf);
3727 SLit->outputString(OS);
3728 return cxstring::createDup(OS.str());
3729 }
3730
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003731 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 if (D)
3733 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003734 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 }
3736
3737 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003738 const Stmt *S = getCursorStmt(C);
3739 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003741
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003742 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 }
3744
3745 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 ->getNameStart());
3748
3749 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 ->getNameStart());
3752
3753 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003754 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003755
3756 if (clang_isDeclaration(C.kind))
3757 return getDeclSpelling(getCursorDecl(C));
3758
3759 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003760 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003761 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 }
3763
3764 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003765 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003766 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 }
3768
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003769 if (C.kind == CXCursor_PackedAttr) {
3770 return cxstring::createRef("packed");
3771 }
3772
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00003773 if (C.kind == CXCursor_VisibilityAttr) {
3774 const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
3775 switch (AA->getVisibility()) {
3776 case VisibilityAttr::VisibilityType::Default:
3777 return cxstring::createRef("default");
3778 case VisibilityAttr::VisibilityType::Hidden:
3779 return cxstring::createRef("hidden");
3780 case VisibilityAttr::VisibilityType::Protected:
3781 return cxstring::createRef("protected");
3782 }
3783 llvm_unreachable("unknown visibility type");
3784 }
3785
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003786 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003787}
3788
3789CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3790 unsigned pieceIndex,
3791 unsigned options) {
3792 if (clang_Cursor_isNull(C))
3793 return clang_getNullRange();
3794
3795 ASTContext &Ctx = getCursorContext(C);
3796
3797 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003798 const Stmt *S = getCursorStmt(C);
3799 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 if (pieceIndex > 0)
3801 return clang_getNullRange();
3802 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3803 }
3804
3805 return clang_getNullRange();
3806 }
3807
3808 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003809 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3811 if (pieceIndex >= ME->getNumSelectorLocs())
3812 return clang_getNullRange();
3813 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3814 }
3815 }
3816
3817 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3818 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003819 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3821 if (pieceIndex >= MD->getNumSelectorLocs())
3822 return clang_getNullRange();
3823 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3824 }
3825 }
3826
3827 if (C.kind == CXCursor_ObjCCategoryDecl ||
3828 C.kind == CXCursor_ObjCCategoryImplDecl) {
3829 if (pieceIndex > 0)
3830 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003831 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3833 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003834 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3836 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3837 }
3838
3839 if (C.kind == CXCursor_ModuleImportDecl) {
3840 if (pieceIndex > 0)
3841 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003842 if (const ImportDecl *ImportD =
3843 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3845 if (!Locs.empty())
3846 return cxloc::translateSourceRange(Ctx,
3847 SourceRange(Locs.front(), Locs.back()));
3848 }
3849 return clang_getNullRange();
3850 }
3851
Argyrios Kyrtzidisa2a1e532014-08-26 20:23:26 +00003852 if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
3853 C.kind == CXCursor_ConversionFunction) {
3854 if (pieceIndex > 0)
3855 return clang_getNullRange();
3856 if (const FunctionDecl *FD =
3857 dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
3858 DeclarationNameInfo FunctionName = FD->getNameInfo();
3859 return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
3860 }
3861 return clang_getNullRange();
3862 }
3863
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 // FIXME: A CXCursor_InclusionDirective should give the location of the
3865 // filename, but we don't keep track of this.
3866
3867 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3868 // but we don't keep track of this.
3869
3870 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3871 // but we don't keep track of this.
3872
3873 // Default handling, give the location of the cursor.
3874
3875 if (pieceIndex > 0)
3876 return clang_getNullRange();
3877
3878 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3879 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3880 return cxloc::translateSourceRange(Ctx, Loc);
3881}
3882
Eli Bendersky44a206f2014-07-31 18:04:56 +00003883CXString clang_Cursor_getMangling(CXCursor C) {
3884 if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
3885 return cxstring::createEmpty();
3886
Eli Bendersky44a206f2014-07-31 18:04:56 +00003887 // Mangling only works for functions and variables.
Eli Bendersky79759592014-08-01 15:01:10 +00003888 const Decl *D = getCursorDecl(C);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003889 if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
3890 return cxstring::createEmpty();
3891
Eli Bendersky79759592014-08-01 15:01:10 +00003892 // First apply frontend mangling.
Eli Bendersky44a206f2014-07-31 18:04:56 +00003893 const NamedDecl *ND = cast<NamedDecl>(D);
Eli Bendersky79759592014-08-01 15:01:10 +00003894 ASTContext &Ctx = ND->getASTContext();
3895 std::unique_ptr<MangleContext> MC(Ctx.createMangleContext());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003896
Eli Bendersky79759592014-08-01 15:01:10 +00003897 std::string FrontendBuf;
3898 llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
3899 MC->mangleName(ND, FrontendBufOS);
Eli Bendersky44a206f2014-07-31 18:04:56 +00003900
Eli Bendersky79759592014-08-01 15:01:10 +00003901 // Now apply backend mangling.
3902 std::unique_ptr<llvm::DataLayout> DL(
Eric Christopher964a5f32015-08-05 23:48:05 +00003903 new llvm::DataLayout(Ctx.getTargetInfo().getDataLayoutString()));
Eli Bendersky79759592014-08-01 15:01:10 +00003904
3905 std::string FinalBuf;
3906 llvm::raw_string_ostream FinalBufOS(FinalBuf);
Rafael Espindolab633d202015-06-23 13:59:36 +00003907 llvm::Mangler::getNameWithPrefix(FinalBufOS, llvm::Twine(FrontendBufOS.str()),
3908 *DL);
Eli Bendersky79759592014-08-01 15:01:10 +00003909
3910 return cxstring::createDup(FinalBufOS.str());
Eli Bendersky44a206f2014-07-31 18:04:56 +00003911}
3912
Guy Benyei11169dd2012-12-18 14:30:41 +00003913CXString clang_getCursorDisplayName(CXCursor C) {
3914 if (!clang_isDeclaration(C.kind))
3915 return clang_getCursorSpelling(C);
3916
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003917 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003919 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003920
3921 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003922 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 D = FunTmpl->getTemplatedDecl();
3924
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003925 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 SmallString<64> Str;
3927 llvm::raw_svector_ostream OS(Str);
3928 OS << *Function;
3929 if (Function->getPrimaryTemplate())
3930 OS << "<>";
3931 OS << "(";
3932 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3933 if (I)
3934 OS << ", ";
3935 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3936 }
3937
3938 if (Function->isVariadic()) {
3939 if (Function->getNumParams())
3940 OS << ", ";
3941 OS << "...";
3942 }
3943 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003944 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003945 }
3946
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003947 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 SmallString<64> Str;
3949 llvm::raw_svector_ostream OS(Str);
3950 OS << *ClassTemplate;
3951 OS << "<";
3952 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3953 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3954 if (I)
3955 OS << ", ";
3956
3957 NamedDecl *Param = Params->getParam(I);
3958 if (Param->getIdentifier()) {
3959 OS << Param->getIdentifier()->getName();
3960 continue;
3961 }
3962
3963 // There is no parameter name, which makes this tricky. Try to come up
3964 // with something useful that isn't too long.
3965 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3966 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3967 else if (NonTypeTemplateParmDecl *NTTP
3968 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3969 OS << NTTP->getType().getAsString(Policy);
3970 else
3971 OS << "template<...> class";
3972 }
3973
3974 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003975 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 }
3977
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003978 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3980 // If the type was explicitly written, use that.
3981 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003982 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003983
Benjamin Kramer9170e912013-02-22 15:46:01 +00003984 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 llvm::raw_svector_ostream OS(Str);
3986 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003987 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 ClassSpec->getTemplateArgs().data(),
3989 ClassSpec->getTemplateArgs().size(),
3990 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003991 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 }
3993
3994 return clang_getCursorSpelling(C);
3995}
3996
3997CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3998 switch (Kind) {
3999 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004000 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004002 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004004 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004006 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004008 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004010 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004012 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004013 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004014 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004015 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004016 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004018 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004019 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004020 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004022 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004023 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004024 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004026 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004027 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004028 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004030 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004032 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004034 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004036 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004038 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004040 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004042 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004044 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004046 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004048 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004050 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004052 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004054 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004056 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004058 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004060 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004062 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004064 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004065 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004066 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004068 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004070 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004072 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004074 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004076 return cxstring::createRef("ArraySubscriptExpr");
Alexey Bataev1a3320e2015-08-25 14:24:04 +00004077 case CXCursor_OMPArraySectionExpr:
4078 return cxstring::createRef("OMPArraySectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004080 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004082 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004084 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004086 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004088 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004090 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004092 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004093 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004094 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004096 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004097 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004098 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004100 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004102 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004103 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004104 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004106 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004108 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004110 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004112 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004114 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004116 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004118 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004120 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004122 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004124 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004126 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004128 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00004129 case CXCursor_ObjCSelfExpr:
4130 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004131 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004132 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004133 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004134 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004136 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004137 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004138 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004140 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004141 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004142 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004143 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004144 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004145 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004146 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004147 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004148 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004149 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004150 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004151 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004152 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004153 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004154 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004155 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004156 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004157 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004158 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004159 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004160 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004161 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004162 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004163 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004164 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004166 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004167 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004168 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004169 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004170 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004172 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004174 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004175 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004176 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004178 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004180 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004182 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004184 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004186 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004188 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004190 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004192 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004194 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004196 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004198 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004200 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004202 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004204 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004206 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004208 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004210 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004212 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004214 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004216 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004218 return cxstring::createRef("SEHFinallyStmt");
Nico Weber9b982072014-07-07 00:12:30 +00004219 case CXCursor_SEHLeaveStmt:
4220 return cxstring::createRef("SEHLeaveStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004222 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004224 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004226 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004228 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004230 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004232 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004234 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004236 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004238 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004240 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004241 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004242 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004243 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004244 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004245 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004246 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004247 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004248 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004249 case CXCursor_PackedAttr:
4250 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00004251 case CXCursor_PureAttr:
4252 return cxstring::createRef("attribute(pure)");
4253 case CXCursor_ConstAttr:
4254 return cxstring::createRef("attribute(const)");
4255 case CXCursor_NoDuplicateAttr:
4256 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00004257 case CXCursor_CUDAConstantAttr:
4258 return cxstring::createRef("attribute(constant)");
4259 case CXCursor_CUDADeviceAttr:
4260 return cxstring::createRef("attribute(device)");
4261 case CXCursor_CUDAGlobalAttr:
4262 return cxstring::createRef("attribute(global)");
4263 case CXCursor_CUDAHostAttr:
4264 return cxstring::createRef("attribute(host)");
Eli Bendersky9b071472014-08-08 14:59:00 +00004265 case CXCursor_CUDASharedAttr:
4266 return cxstring::createRef("attribute(shared)");
Saleem Abdulrasool79c69712015-09-05 18:53:43 +00004267 case CXCursor_VisibilityAttr:
4268 return cxstring::createRef("attribute(visibility)");
Guy Benyei11169dd2012-12-18 14:30:41 +00004269 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004270 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004272 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004274 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004276 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004278 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004280 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004282 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004284 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004286 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004288 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004290 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004292 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004294 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004296 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004298 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004300 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004302 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004304 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004306 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00004307 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004308 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004310 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004312 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004314 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004316 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00004317 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00004318 return cxstring::createRef("OMPParallelDirective");
4319 case CXCursor_OMPSimdDirective:
4320 return cxstring::createRef("OMPSimdDirective");
Alexey Bataevf29276e2014-06-18 04:14:57 +00004321 case CXCursor_OMPForDirective:
4322 return cxstring::createRef("OMPForDirective");
Alexander Musmanf82886e2014-09-18 05:12:34 +00004323 case CXCursor_OMPForSimdDirective:
4324 return cxstring::createRef("OMPForSimdDirective");
Alexey Bataevd3f8dd22014-06-25 11:44:49 +00004325 case CXCursor_OMPSectionsDirective:
4326 return cxstring::createRef("OMPSectionsDirective");
Alexey Bataev1e0498a2014-06-26 08:21:58 +00004327 case CXCursor_OMPSectionDirective:
4328 return cxstring::createRef("OMPSectionDirective");
Alexey Bataevd1e40fb2014-06-26 12:05:45 +00004329 case CXCursor_OMPSingleDirective:
4330 return cxstring::createRef("OMPSingleDirective");
Alexander Musman80c22892014-07-17 08:54:58 +00004331 case CXCursor_OMPMasterDirective:
4332 return cxstring::createRef("OMPMasterDirective");
Alexander Musmand9ed09f2014-07-21 09:42:05 +00004333 case CXCursor_OMPCriticalDirective:
4334 return cxstring::createRef("OMPCriticalDirective");
Alexey Bataev4acb8592014-07-07 13:01:15 +00004335 case CXCursor_OMPParallelForDirective:
4336 return cxstring::createRef("OMPParallelForDirective");
Alexander Musmane4e893b2014-09-23 09:33:00 +00004337 case CXCursor_OMPParallelForSimdDirective:
4338 return cxstring::createRef("OMPParallelForSimdDirective");
Alexey Bataev84d0b3e2014-07-08 08:12:03 +00004339 case CXCursor_OMPParallelSectionsDirective:
4340 return cxstring::createRef("OMPParallelSectionsDirective");
Alexey Bataev9c2e8ee2014-07-11 11:25:16 +00004341 case CXCursor_OMPTaskDirective:
4342 return cxstring::createRef("OMPTaskDirective");
Alexey Bataev68446b72014-07-18 07:47:19 +00004343 case CXCursor_OMPTaskyieldDirective:
4344 return cxstring::createRef("OMPTaskyieldDirective");
Alexey Bataev4d1dfea2014-07-18 09:11:51 +00004345 case CXCursor_OMPBarrierDirective:
4346 return cxstring::createRef("OMPBarrierDirective");
Alexey Bataev2df347a2014-07-18 10:17:07 +00004347 case CXCursor_OMPTaskwaitDirective:
4348 return cxstring::createRef("OMPTaskwaitDirective");
Alexey Bataevc30dd2d2015-06-18 12:14:09 +00004349 case CXCursor_OMPTaskgroupDirective:
4350 return cxstring::createRef("OMPTaskgroupDirective");
Alexey Bataev6125da92014-07-21 11:26:11 +00004351 case CXCursor_OMPFlushDirective:
4352 return cxstring::createRef("OMPFlushDirective");
Alexey Bataev9fb6e642014-07-22 06:45:04 +00004353 case CXCursor_OMPOrderedDirective:
4354 return cxstring::createRef("OMPOrderedDirective");
Alexey Bataev0162e452014-07-22 10:10:35 +00004355 case CXCursor_OMPAtomicDirective:
4356 return cxstring::createRef("OMPAtomicDirective");
Alexey Bataev0bd520b2014-09-19 08:19:49 +00004357 case CXCursor_OMPTargetDirective:
4358 return cxstring::createRef("OMPTargetDirective");
Michael Wong65f367f2015-07-21 13:44:28 +00004359 case CXCursor_OMPTargetDataDirective:
4360 return cxstring::createRef("OMPTargetDataDirective");
Alexey Bataev13314bf2014-10-09 04:18:56 +00004361 case CXCursor_OMPTeamsDirective:
4362 return cxstring::createRef("OMPTeamsDirective");
Alexey Bataev6d4ed052015-07-01 06:57:41 +00004363 case CXCursor_OMPCancellationPointDirective:
4364 return cxstring::createRef("OMPCancellationPointDirective");
Alexey Bataev80909872015-07-02 11:25:17 +00004365 case CXCursor_OMPCancelDirective:
4366 return cxstring::createRef("OMPCancelDirective");
Francisco Lopes da Silva975a9f62015-01-21 16:24:11 +00004367 case CXCursor_OverloadCandidate:
4368 return cxstring::createRef("OverloadCandidate");
Guy Benyei11169dd2012-12-18 14:30:41 +00004369 }
4370
4371 llvm_unreachable("Unhandled CXCursorKind");
4372}
4373
4374struct GetCursorData {
4375 SourceLocation TokenBeginLoc;
4376 bool PointsAtMacroArgExpansion;
4377 bool VisitedObjCPropertyImplDecl;
4378 SourceLocation VisitedDeclaratorDeclStartLoc;
4379 CXCursor &BestCursor;
4380
4381 GetCursorData(SourceManager &SM,
4382 SourceLocation tokenBegin, CXCursor &outputCursor)
4383 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
4384 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
4385 VisitedObjCPropertyImplDecl = false;
4386 }
4387};
4388
4389static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
4390 CXCursor parent,
4391 CXClientData client_data) {
4392 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
4393 CXCursor *BestCursor = &Data->BestCursor;
4394
4395 // If we point inside a macro argument we should provide info of what the
4396 // token is so use the actual cursor, don't replace it with a macro expansion
4397 // cursor.
4398 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
4399 return CXChildVisit_Recurse;
4400
4401 if (clang_isDeclaration(cursor.kind)) {
4402 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004403 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00004404 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
4405 if (MD->isImplicit())
4406 return CXChildVisit_Break;
4407
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004408 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00004409 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
4410 // Check that when we have multiple @class references in the same line,
4411 // that later ones do not override the previous ones.
4412 // If we have:
4413 // @class Foo, Bar;
4414 // source ranges for both start at '@', so 'Bar' will end up overriding
4415 // 'Foo' even though the cursor location was at 'Foo'.
4416 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
4417 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004418 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
4420 if (PrevID != ID &&
4421 !PrevID->isThisDeclarationADefinition() &&
4422 !ID->isThisDeclarationADefinition())
4423 return CXChildVisit_Break;
4424 }
4425
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004426 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004427 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4428 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4429 // Check that when we have multiple declarators in the same line,
4430 // that later ones do not override the previous ones.
4431 // If we have:
4432 // int Foo, Bar;
4433 // source ranges for both start at 'int', so 'Bar' will end up overriding
4434 // 'Foo' even though the cursor location was at 'Foo'.
4435 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4436 return CXChildVisit_Break;
4437 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4438
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004439 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4441 (void)PropImp;
4442 // Check that when we have multiple @synthesize in the same line,
4443 // that later ones do not override the previous ones.
4444 // If we have:
4445 // @synthesize Foo, Bar;
4446 // source ranges for both start at '@', so 'Bar' will end up overriding
4447 // 'Foo' even though the cursor location was at 'Foo'.
4448 if (Data->VisitedObjCPropertyImplDecl)
4449 return CXChildVisit_Break;
4450 Data->VisitedObjCPropertyImplDecl = true;
4451 }
4452 }
4453
4454 if (clang_isExpression(cursor.kind) &&
4455 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004456 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 // Avoid having the cursor of an expression replace the declaration cursor
4458 // when the expression source range overlaps the declaration range.
4459 // This can happen for C++ constructor expressions whose range generally
4460 // include the variable declaration, e.g.:
4461 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4462 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4463 D->getLocation() == Data->TokenBeginLoc)
4464 return CXChildVisit_Break;
4465 }
4466 }
4467
4468 // If our current best cursor is the construction of a temporary object,
4469 // don't replace that cursor with a type reference, because we want
4470 // clang_getCursor() to point at the constructor.
4471 if (clang_isExpression(BestCursor->kind) &&
4472 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4473 cursor.kind == CXCursor_TypeRef) {
4474 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4475 // as having the actual point on the type reference.
4476 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4477 return CXChildVisit_Recurse;
4478 }
Douglas Gregore9d95f12015-07-07 03:57:35 +00004479
4480 // If we already have an Objective-C superclass reference, don't
4481 // update it further.
4482 if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
4483 return CXChildVisit_Break;
4484
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 *BestCursor = cursor;
4486 return CXChildVisit_Recurse;
4487}
4488
4489CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004490 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004491 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004493 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004494
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004495 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4497
4498 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4499 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4500
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004501 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 CXFile SearchFile;
4503 unsigned SearchLine, SearchColumn;
4504 CXFile ResultFile;
4505 unsigned ResultLine, ResultColumn;
4506 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4507 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4508 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
Craig Topper69186e72014-06-08 08:38:04 +00004509
4510 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
4511 nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004512 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Craig Topper69186e72014-06-08 08:38:04 +00004513 &ResultColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 SearchFileName = clang_getFileName(SearchFile);
4515 ResultFileName = clang_getFileName(ResultFile);
4516 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4517 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004518 *Log << llvm::format("(%s:%d:%d) = %s",
4519 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4520 clang_getCString(KindSpelling))
4521 << llvm::format("(%s:%d:%d):%s%s",
4522 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4523 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 clang_disposeString(SearchFileName);
4525 clang_disposeString(ResultFileName);
4526 clang_disposeString(KindSpelling);
4527 clang_disposeString(USR);
4528
4529 CXCursor Definition = clang_getCursorDefinition(Result);
4530 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4531 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4532 CXString DefinitionKindSpelling
4533 = clang_getCursorKindSpelling(Definition.kind);
4534 CXFile DefinitionFile;
4535 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004536 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Craig Topper69186e72014-06-08 08:38:04 +00004537 &DefinitionLine, &DefinitionColumn, nullptr);
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004539 *Log << llvm::format(" -> %s(%s:%d:%d)",
4540 clang_getCString(DefinitionKindSpelling),
4541 clang_getCString(DefinitionFileName),
4542 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 clang_disposeString(DefinitionFileName);
4544 clang_disposeString(DefinitionKindSpelling);
4545 }
4546 }
4547
4548 return Result;
4549}
4550
4551CXCursor clang_getNullCursor(void) {
4552 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4553}
4554
4555unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004556 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4557 // can't set consistently. For example, when visiting a DeclStmt we will set
4558 // it but we don't set it on the result of clang_getCursorDefinition for
4559 // a reference of the same declaration.
4560 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4561 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4562 // to provide that kind of info.
4563 if (clang_isDeclaration(X.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004564 X.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004565 if (clang_isDeclaration(Y.kind))
Craig Topper69186e72014-06-08 08:38:04 +00004566 Y.data[1] = nullptr;
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004567
Guy Benyei11169dd2012-12-18 14:30:41 +00004568 return X == Y;
4569}
4570
4571unsigned clang_hashCursor(CXCursor C) {
4572 unsigned Index = 0;
4573 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4574 Index = 1;
4575
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004576 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 std::make_pair(C.kind, C.data[Index]));
4578}
4579
4580unsigned clang_isInvalid(enum CXCursorKind K) {
4581 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4582}
4583
4584unsigned clang_isDeclaration(enum CXCursorKind K) {
4585 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4586 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4587}
4588
4589unsigned clang_isReference(enum CXCursorKind K) {
4590 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4591}
4592
4593unsigned clang_isExpression(enum CXCursorKind K) {
4594 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4595}
4596
4597unsigned clang_isStatement(enum CXCursorKind K) {
4598 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4599}
4600
4601unsigned clang_isAttribute(enum CXCursorKind K) {
4602 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4603}
4604
4605unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4606 return K == CXCursor_TranslationUnit;
4607}
4608
4609unsigned clang_isPreprocessing(enum CXCursorKind K) {
4610 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4611}
4612
4613unsigned clang_isUnexposed(enum CXCursorKind K) {
4614 switch (K) {
4615 case CXCursor_UnexposedDecl:
4616 case CXCursor_UnexposedExpr:
4617 case CXCursor_UnexposedStmt:
4618 case CXCursor_UnexposedAttr:
4619 return true;
4620 default:
4621 return false;
4622 }
4623}
4624
4625CXCursorKind clang_getCursorKind(CXCursor C) {
4626 return C.kind;
4627}
4628
4629CXSourceLocation clang_getCursorLocation(CXCursor C) {
4630 if (clang_isReference(C.kind)) {
4631 switch (C.kind) {
4632 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004633 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 = getCursorObjCSuperClassRef(C);
4635 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4636 }
4637
4638 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004639 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004640 = getCursorObjCProtocolRef(C);
4641 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4642 }
4643
4644 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004645 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 = getCursorObjCClassRef(C);
4647 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4648 }
4649
4650 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004651 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4653 }
4654
4655 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004656 std::pair<const TemplateDecl *, SourceLocation> P =
4657 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4659 }
4660
4661 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004662 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4664 }
4665
4666 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004667 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4669 }
4670
4671 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004672 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4674 }
4675
4676 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004677 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 if (!BaseSpec)
4679 return clang_getNullLocation();
4680
4681 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4682 return cxloc::translateSourceLocation(getCursorContext(C),
4683 TSInfo->getTypeLoc().getBeginLoc());
4684
4685 return cxloc::translateSourceLocation(getCursorContext(C),
4686 BaseSpec->getLocStart());
4687 }
4688
4689 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004690 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4692 }
4693
4694 case CXCursor_OverloadedDeclRef:
4695 return cxloc::translateSourceLocation(getCursorContext(C),
4696 getCursorOverloadedDeclRef(C).second);
4697
4698 default:
4699 // FIXME: Need a way to enumerate all non-reference cases.
4700 llvm_unreachable("Missed a reference kind");
4701 }
4702 }
4703
4704 if (clang_isExpression(C.kind))
4705 return cxloc::translateSourceLocation(getCursorContext(C),
4706 getLocationFromExpr(getCursorExpr(C)));
4707
4708 if (clang_isStatement(C.kind))
4709 return cxloc::translateSourceLocation(getCursorContext(C),
4710 getCursorStmt(C)->getLocStart());
4711
4712 if (C.kind == CXCursor_PreprocessingDirective) {
4713 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4714 return cxloc::translateSourceLocation(getCursorContext(C), L);
4715 }
4716
4717 if (C.kind == CXCursor_MacroExpansion) {
4718 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004719 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 return cxloc::translateSourceLocation(getCursorContext(C), L);
4721 }
4722
4723 if (C.kind == CXCursor_MacroDefinition) {
4724 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4725 return cxloc::translateSourceLocation(getCursorContext(C), L);
4726 }
4727
4728 if (C.kind == CXCursor_InclusionDirective) {
4729 SourceLocation L
4730 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4731 return cxloc::translateSourceLocation(getCursorContext(C), L);
4732 }
4733
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004734 if (clang_isAttribute(C.kind)) {
4735 SourceLocation L
4736 = cxcursor::getCursorAttr(C)->getLocation();
4737 return cxloc::translateSourceLocation(getCursorContext(C), L);
4738 }
4739
Guy Benyei11169dd2012-12-18 14:30:41 +00004740 if (!clang_isDeclaration(C.kind))
4741 return clang_getNullLocation();
4742
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004743 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 if (!D)
4745 return clang_getNullLocation();
4746
4747 SourceLocation Loc = D->getLocation();
4748 // FIXME: Multiple variables declared in a single declaration
4749 // currently lack the information needed to correctly determine their
4750 // ranges when accounting for the type-specifier. We use context
4751 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4752 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004753 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 if (!cxcursor::isFirstInDeclGroup(C))
4755 Loc = VD->getLocation();
4756 }
4757
4758 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004759 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 Loc = MD->getSelectorStartLoc();
4761
4762 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4763}
4764
4765} // end extern "C"
4766
4767CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4768 assert(TU);
4769
4770 // Guard against an invalid SourceLocation, or we may assert in one
4771 // of the following calls.
4772 if (SLoc.isInvalid())
4773 return clang_getNullCursor();
4774
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004775 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004776
4777 // Translate the given source location to make it point at the beginning of
4778 // the token under the cursor.
4779 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4780 CXXUnit->getASTContext().getLangOpts());
4781
4782 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4783 if (SLoc.isValid()) {
4784 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4785 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4786 /*VisitPreprocessorLast=*/true,
4787 /*VisitIncludedEntities=*/false,
4788 SourceLocation(SLoc));
4789 CursorVis.visitFileRegion();
4790 }
4791
4792 return Result;
4793}
4794
4795static SourceRange getRawCursorExtent(CXCursor C) {
4796 if (clang_isReference(C.kind)) {
4797 switch (C.kind) {
4798 case CXCursor_ObjCSuperClassRef:
4799 return getCursorObjCSuperClassRef(C).second;
4800
4801 case CXCursor_ObjCProtocolRef:
4802 return getCursorObjCProtocolRef(C).second;
4803
4804 case CXCursor_ObjCClassRef:
4805 return getCursorObjCClassRef(C).second;
4806
4807 case CXCursor_TypeRef:
4808 return getCursorTypeRef(C).second;
4809
4810 case CXCursor_TemplateRef:
4811 return getCursorTemplateRef(C).second;
4812
4813 case CXCursor_NamespaceRef:
4814 return getCursorNamespaceRef(C).second;
4815
4816 case CXCursor_MemberRef:
4817 return getCursorMemberRef(C).second;
4818
4819 case CXCursor_CXXBaseSpecifier:
4820 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4821
4822 case CXCursor_LabelRef:
4823 return getCursorLabelRef(C).second;
4824
4825 case CXCursor_OverloadedDeclRef:
4826 return getCursorOverloadedDeclRef(C).second;
4827
4828 case CXCursor_VariableRef:
4829 return getCursorVariableRef(C).second;
4830
4831 default:
4832 // FIXME: Need a way to enumerate all non-reference cases.
4833 llvm_unreachable("Missed a reference kind");
4834 }
4835 }
4836
4837 if (clang_isExpression(C.kind))
4838 return getCursorExpr(C)->getSourceRange();
4839
4840 if (clang_isStatement(C.kind))
4841 return getCursorStmt(C)->getSourceRange();
4842
4843 if (clang_isAttribute(C.kind))
4844 return getCursorAttr(C)->getRange();
4845
4846 if (C.kind == CXCursor_PreprocessingDirective)
4847 return cxcursor::getCursorPreprocessingDirective(C);
4848
4849 if (C.kind == CXCursor_MacroExpansion) {
4850 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004851 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004852 return TU->mapRangeFromPreamble(Range);
4853 }
4854
4855 if (C.kind == CXCursor_MacroDefinition) {
4856 ASTUnit *TU = getCursorASTUnit(C);
4857 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4858 return TU->mapRangeFromPreamble(Range);
4859 }
4860
4861 if (C.kind == CXCursor_InclusionDirective) {
4862 ASTUnit *TU = getCursorASTUnit(C);
4863 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4864 return TU->mapRangeFromPreamble(Range);
4865 }
4866
4867 if (C.kind == CXCursor_TranslationUnit) {
4868 ASTUnit *TU = getCursorASTUnit(C);
4869 FileID MainID = TU->getSourceManager().getMainFileID();
4870 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4871 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4872 return SourceRange(Start, End);
4873 }
4874
4875 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004876 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 if (!D)
4878 return SourceRange();
4879
4880 SourceRange R = D->getSourceRange();
4881 // FIXME: Multiple variables declared in a single declaration
4882 // currently lack the information needed to correctly determine their
4883 // ranges when accounting for the type-specifier. We use context
4884 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4885 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004886 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 if (!cxcursor::isFirstInDeclGroup(C))
4888 R.setBegin(VD->getLocation());
4889 }
4890 return R;
4891 }
4892 return SourceRange();
4893}
4894
4895/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4896/// the decl-specifier-seq for declarations.
4897static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4898 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004899 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004900 if (!D)
4901 return SourceRange();
4902
4903 SourceRange R = D->getSourceRange();
4904
4905 // Adjust the start of the location for declarations preceded by
4906 // declaration specifiers.
4907 SourceLocation StartLoc;
4908 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4909 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4910 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004911 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4913 StartLoc = TI->getTypeLoc().getLocStart();
4914 }
4915
4916 if (StartLoc.isValid() && R.getBegin().isValid() &&
4917 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4918 R.setBegin(StartLoc);
4919
4920 // FIXME: Multiple variables declared in a single declaration
4921 // currently lack the information needed to correctly determine their
4922 // ranges when accounting for the type-specifier. We use context
4923 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4924 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004925 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 if (!cxcursor::isFirstInDeclGroup(C))
4927 R.setBegin(VD->getLocation());
4928 }
4929
4930 return R;
4931 }
4932
4933 return getRawCursorExtent(C);
4934}
4935
4936extern "C" {
4937
4938CXSourceRange clang_getCursorExtent(CXCursor C) {
4939 SourceRange R = getRawCursorExtent(C);
4940 if (R.isInvalid())
4941 return clang_getNullRange();
4942
4943 return cxloc::translateSourceRange(getCursorContext(C), R);
4944}
4945
4946CXCursor clang_getCursorReferenced(CXCursor C) {
4947 if (clang_isInvalid(C.kind))
4948 return clang_getNullCursor();
4949
4950 CXTranslationUnit tu = getCursorTU(C);
4951 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004952 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 if (!D)
4954 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004955 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004956 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004957 if (const ObjCPropertyImplDecl *PropImpl =
4958 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004959 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4960 return MakeCXCursor(Property, tu);
4961
4962 return C;
4963 }
4964
4965 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004966 const Expr *E = getCursorExpr(C);
4967 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004968 if (D) {
4969 CXCursor declCursor = MakeCXCursor(D, tu);
4970 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4971 declCursor);
4972 return declCursor;
4973 }
4974
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004975 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004976 return MakeCursorOverloadedDeclRef(Ovl, tu);
4977
4978 return clang_getNullCursor();
4979 }
4980
4981 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004982 const Stmt *S = getCursorStmt(C);
4983 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004984 if (LabelDecl *label = Goto->getLabel())
4985 if (LabelStmt *labelS = label->getStmt())
4986 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4987
4988 return clang_getNullCursor();
4989 }
Richard Smith66a81862015-05-04 02:25:31 +00004990
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 if (C.kind == CXCursor_MacroExpansion) {
Richard Smith66a81862015-05-04 02:25:31 +00004992 if (const MacroDefinitionRecord *Def =
4993 getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 return MakeMacroDefinitionCursor(Def, tu);
4995 }
4996
4997 if (!clang_isReference(C.kind))
4998 return clang_getNullCursor();
4999
5000 switch (C.kind) {
5001 case CXCursor_ObjCSuperClassRef:
5002 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
5003
5004 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005005 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
5006 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 return MakeCXCursor(Def, tu);
5008
5009 return MakeCXCursor(Prot, tu);
5010 }
5011
5012 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005013 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
5014 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005015 return MakeCXCursor(Def, tu);
5016
5017 return MakeCXCursor(Class, tu);
5018 }
5019
5020 case CXCursor_TypeRef:
5021 return MakeCXCursor(getCursorTypeRef(C).first, tu );
5022
5023 case CXCursor_TemplateRef:
5024 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
5025
5026 case CXCursor_NamespaceRef:
5027 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
5028
5029 case CXCursor_MemberRef:
5030 return MakeCXCursor(getCursorMemberRef(C).first, tu );
5031
5032 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00005033 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005034 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
5035 tu ));
5036 }
5037
5038 case CXCursor_LabelRef:
5039 // FIXME: We end up faking the "parent" declaration here because we
5040 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005041 return MakeCXCursor(getCursorLabelRef(C).first,
5042 cxtu::getASTUnit(tu)->getASTContext()
5043 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00005044 tu);
5045
5046 case CXCursor_OverloadedDeclRef:
5047 return C;
5048
5049 case CXCursor_VariableRef:
5050 return MakeCXCursor(getCursorVariableRef(C).first, tu);
5051
5052 default:
5053 // We would prefer to enumerate all non-reference cursor kinds here.
5054 llvm_unreachable("Unhandled reference cursor kind");
5055 }
5056}
5057
5058CXCursor clang_getCursorDefinition(CXCursor C) {
5059 if (clang_isInvalid(C.kind))
5060 return clang_getNullCursor();
5061
5062 CXTranslationUnit TU = getCursorTU(C);
5063
5064 bool WasReference = false;
5065 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
5066 C = clang_getCursorReferenced(C);
5067 WasReference = true;
5068 }
5069
5070 if (C.kind == CXCursor_MacroExpansion)
5071 return clang_getCursorReferenced(C);
5072
5073 if (!clang_isDeclaration(C.kind))
5074 return clang_getNullCursor();
5075
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005076 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00005077 if (!D)
5078 return clang_getNullCursor();
5079
5080 switch (D->getKind()) {
5081 // Declaration kinds that don't really separate the notions of
5082 // declaration and definition.
5083 case Decl::Namespace:
5084 case Decl::Typedef:
5085 case Decl::TypeAlias:
5086 case Decl::TypeAliasTemplate:
5087 case Decl::TemplateTypeParm:
5088 case Decl::EnumConstant:
5089 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00005090 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005091 case Decl::IndirectField:
5092 case Decl::ObjCIvar:
5093 case Decl::ObjCAtDefsField:
5094 case Decl::ImplicitParam:
5095 case Decl::ParmVar:
5096 case Decl::NonTypeTemplateParm:
5097 case Decl::TemplateTemplateParm:
5098 case Decl::ObjCCategoryImpl:
5099 case Decl::ObjCImplementation:
5100 case Decl::AccessSpec:
5101 case Decl::LinkageSpec:
5102 case Decl::ObjCPropertyImpl:
5103 case Decl::FileScopeAsm:
5104 case Decl::StaticAssert:
5105 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00005106 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00005107 case Decl::Label: // FIXME: Is this right??
5108 case Decl::ClassScopeFunctionSpecialization:
5109 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00005110 case Decl::OMPThreadPrivate:
Douglas Gregor85f3f952015-07-07 03:57:15 +00005111 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00005112 return C;
5113
5114 // Declaration kinds that don't make any sense here, but are
5115 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00005116 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00005117 case Decl::TranslationUnit:
Richard Smithf19e1272015-03-07 00:04:49 +00005118 case Decl::ExternCContext:
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 break;
5120
5121 // Declaration kinds for which the definition is not resolvable.
5122 case Decl::UnresolvedUsingTypename:
5123 case Decl::UnresolvedUsingValue:
5124 break;
5125
5126 case Decl::UsingDirective:
5127 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
5128 TU);
5129
5130 case Decl::NamespaceAlias:
5131 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
5132
5133 case Decl::Enum:
5134 case Decl::Record:
5135 case Decl::CXXRecord:
5136 case Decl::ClassTemplateSpecialization:
5137 case Decl::ClassTemplatePartialSpecialization:
5138 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
5139 return MakeCXCursor(Def, TU);
5140 return clang_getNullCursor();
5141
5142 case Decl::Function:
5143 case Decl::CXXMethod:
5144 case Decl::CXXConstructor:
5145 case Decl::CXXDestructor:
5146 case Decl::CXXConversion: {
Craig Topper69186e72014-06-08 08:38:04 +00005147 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005148 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00005149 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005150 return clang_getNullCursor();
5151 }
5152
Larisse Voufo39a1e502013-08-06 01:03:05 +00005153 case Decl::Var:
5154 case Decl::VarTemplateSpecialization:
5155 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00005156 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005157 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005158 return MakeCXCursor(Def, TU);
5159 return clang_getNullCursor();
5160 }
5161
5162 case Decl::FunctionTemplate: {
Craig Topper69186e72014-06-08 08:38:04 +00005163 const FunctionDecl *Def = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
5165 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
5166 return clang_getNullCursor();
5167 }
5168
5169 case Decl::ClassTemplate: {
5170 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
5171 ->getDefinition())
5172 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
5173 TU);
5174 return clang_getNullCursor();
5175 }
5176
Larisse Voufo39a1e502013-08-06 01:03:05 +00005177 case Decl::VarTemplate: {
5178 if (VarDecl *Def =
5179 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
5180 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
5181 return clang_getNullCursor();
5182 }
5183
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 case Decl::Using:
5185 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
5186 D->getLocation(), TU);
5187
5188 case Decl::UsingShadow:
5189 return clang_getCursorDefinition(
5190 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
5191 TU));
5192
5193 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005194 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005195 if (Method->isThisDeclarationADefinition())
5196 return C;
5197
5198 // Dig out the method definition in the associated
5199 // @implementation, if we have it.
5200 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005201 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
5203 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
5204 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
5205 Method->isInstanceMethod()))
5206 if (Def->isThisDeclarationADefinition())
5207 return MakeCXCursor(Def, TU);
5208
5209 return clang_getNullCursor();
5210 }
5211
5212 case Decl::ObjCCategory:
5213 if (ObjCCategoryImplDecl *Impl
5214 = cast<ObjCCategoryDecl>(D)->getImplementation())
5215 return MakeCXCursor(Impl, TU);
5216 return clang_getNullCursor();
5217
5218 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005219 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 return MakeCXCursor(Def, TU);
5221 return clang_getNullCursor();
5222
5223 case Decl::ObjCInterface: {
5224 // There are two notions of a "definition" for an Objective-C
5225 // class: the interface and its implementation. When we resolved a
5226 // reference to an Objective-C class, produce the @interface as
5227 // the definition; when we were provided with the interface,
5228 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005229 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005231 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 return MakeCXCursor(Def, TU);
5233 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
5234 return MakeCXCursor(Impl, TU);
5235 return clang_getNullCursor();
5236 }
5237
5238 case Decl::ObjCProperty:
5239 // FIXME: We don't really know where to find the
5240 // ObjCPropertyImplDecls that implement this property.
5241 return clang_getNullCursor();
5242
5243 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005244 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00005245 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005246 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00005247 return MakeCXCursor(Def, TU);
5248
5249 return clang_getNullCursor();
5250
5251 case Decl::Friend:
5252 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
5253 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5254 return clang_getNullCursor();
5255
5256 case Decl::FriendTemplate:
5257 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
5258 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
5259 return clang_getNullCursor();
5260 }
5261
5262 return clang_getNullCursor();
5263}
5264
5265unsigned clang_isCursorDefinition(CXCursor C) {
5266 if (!clang_isDeclaration(C.kind))
5267 return 0;
5268
5269 return clang_getCursorDefinition(C) == C;
5270}
5271
5272CXCursor clang_getCanonicalCursor(CXCursor C) {
5273 if (!clang_isDeclaration(C.kind))
5274 return C;
5275
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005276 if (const Decl *D = getCursorDecl(C)) {
5277 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
5279 return MakeCXCursor(CatD, getCursorTU(C));
5280
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005281 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
5282 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00005283 return MakeCXCursor(IFD, getCursorTU(C));
5284
5285 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
5286 }
5287
5288 return C;
5289}
5290
5291int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
5292 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
5293}
5294
5295unsigned clang_getNumOverloadedDecls(CXCursor C) {
5296 if (C.kind != CXCursor_OverloadedDeclRef)
5297 return 0;
5298
5299 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005300 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005301 return E->getNumDecls();
5302
5303 if (OverloadedTemplateStorage *S
5304 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5305 return S->size();
5306
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005307 const Decl *D = Storage.get<const Decl *>();
5308 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00005309 return Using->shadow_size();
5310
5311 return 0;
5312}
5313
5314CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
5315 if (cursor.kind != CXCursor_OverloadedDeclRef)
5316 return clang_getNullCursor();
5317
5318 if (index >= clang_getNumOverloadedDecls(cursor))
5319 return clang_getNullCursor();
5320
5321 CXTranslationUnit TU = getCursorTU(cursor);
5322 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005323 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 return MakeCXCursor(E->decls_begin()[index], TU);
5325
5326 if (OverloadedTemplateStorage *S
5327 = Storage.dyn_cast<OverloadedTemplateStorage*>())
5328 return MakeCXCursor(S->begin()[index], TU);
5329
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005330 const Decl *D = Storage.get<const Decl *>();
5331 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 // FIXME: This is, unfortunately, linear time.
5333 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
5334 std::advance(Pos, index);
5335 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
5336 }
5337
5338 return clang_getNullCursor();
5339}
5340
5341void clang_getDefinitionSpellingAndExtent(CXCursor C,
5342 const char **startBuf,
5343 const char **endBuf,
5344 unsigned *startLine,
5345 unsigned *startColumn,
5346 unsigned *endLine,
5347 unsigned *endColumn) {
5348 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005349 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
5351
5352 SourceManager &SM = FD->getASTContext().getSourceManager();
5353 *startBuf = SM.getCharacterData(Body->getLBracLoc());
5354 *endBuf = SM.getCharacterData(Body->getRBracLoc());
5355 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
5356 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
5357 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
5358 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
5359}
5360
5361
5362CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
5363 unsigned PieceIndex) {
5364 RefNamePieces Pieces;
5365
5366 switch (C.kind) {
5367 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005368 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005369 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
5370 E->getQualifierLoc().getSourceRange());
5371 break;
5372
5373 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005374 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00005375 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
5376 E->getQualifierLoc().getSourceRange(),
5377 E->getOptionalExplicitTemplateArgs());
5378 break;
5379
5380 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005381 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00005382 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005383 const Expr *Callee = OCE->getCallee();
5384 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005385 Callee = ICE->getSubExpr();
5386
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005387 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00005388 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
5389 DRE->getQualifierLoc().getSourceRange());
5390 }
5391 break;
5392
5393 default:
5394 break;
5395 }
5396
5397 if (Pieces.empty()) {
5398 if (PieceIndex == 0)
5399 return clang_getCursorExtent(C);
5400 } else if (PieceIndex < Pieces.size()) {
5401 SourceRange R = Pieces[PieceIndex];
5402 if (R.isValid())
5403 return cxloc::translateSourceRange(getCursorContext(C), R);
5404 }
5405
5406 return clang_getNullRange();
5407}
5408
5409void clang_enableStackTraces(void) {
5410 llvm::sys::PrintStackTraceOnErrorSignal();
5411}
5412
5413void clang_executeOnThread(void (*fn)(void*), void *user_data,
5414 unsigned stack_size) {
5415 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
5416}
5417
5418} // end: extern "C"
5419
5420//===----------------------------------------------------------------------===//
5421// Token-based Operations.
5422//===----------------------------------------------------------------------===//
5423
5424/* CXToken layout:
5425 * int_data[0]: a CXTokenKind
5426 * int_data[1]: starting token location
5427 * int_data[2]: token length
5428 * int_data[3]: reserved
5429 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
5430 * otherwise unused.
5431 */
5432extern "C" {
5433
5434CXTokenKind clang_getTokenKind(CXToken CXTok) {
5435 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5436}
5437
5438CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5439 switch (clang_getTokenKind(CXTok)) {
5440 case CXToken_Identifier:
5441 case CXToken_Keyword:
5442 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005443 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 ->getNameStart());
5445
5446 case CXToken_Literal: {
5447 // We have stashed the starting pointer in the ptr_data field. Use it.
5448 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005449 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005450 }
5451
5452 case CXToken_Punctuation:
5453 case CXToken_Comment:
5454 break;
5455 }
5456
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005457 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005458 LOG_BAD_TU(TU);
5459 return cxstring::createEmpty();
5460 }
5461
Guy Benyei11169dd2012-12-18 14:30:41 +00005462 // We have to find the starting buffer pointer the hard way, by
5463 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005464 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005466 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005467
5468 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5469 std::pair<FileID, unsigned> LocInfo
5470 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5471 bool Invalid = false;
5472 StringRef Buffer
5473 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5474 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005475 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005476
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005477 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005478}
5479
5480CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005481 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005482 LOG_BAD_TU(TU);
5483 return clang_getNullLocation();
5484 }
5485
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005486 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 if (!CXXUnit)
5488 return clang_getNullLocation();
5489
5490 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5491 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5492}
5493
5494CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005495 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005496 LOG_BAD_TU(TU);
5497 return clang_getNullRange();
5498 }
5499
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005500 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005501 if (!CXXUnit)
5502 return clang_getNullRange();
5503
5504 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5505 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5506}
5507
5508static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5509 SmallVectorImpl<CXToken> &CXTokens) {
5510 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5511 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005512 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005513 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005514 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005515
5516 // Cannot tokenize across files.
5517 if (BeginLocInfo.first != EndLocInfo.first)
5518 return;
5519
5520 // Create a lexer
5521 bool Invalid = false;
5522 StringRef Buffer
5523 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5524 if (Invalid)
5525 return;
5526
5527 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5528 CXXUnit->getASTContext().getLangOpts(),
5529 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5530 Lex.SetCommentRetentionState(true);
5531
5532 // Lex tokens until we hit the end of the range.
5533 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5534 Token Tok;
5535 bool previousWasAt = false;
5536 do {
5537 // Lex the next token
5538 Lex.LexFromRawLexer(Tok);
5539 if (Tok.is(tok::eof))
5540 break;
5541
5542 // Initialize the CXToken.
5543 CXToken CXTok;
5544
5545 // - Common fields
5546 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5547 CXTok.int_data[2] = Tok.getLength();
5548 CXTok.int_data[3] = 0;
5549
5550 // - Kind-specific fields
5551 if (Tok.isLiteral()) {
5552 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005553 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005554 } else if (Tok.is(tok::raw_identifier)) {
5555 // Lookup the identifier to determine whether we have a keyword.
5556 IdentifierInfo *II
5557 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5558
5559 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5560 CXTok.int_data[0] = CXToken_Keyword;
5561 }
5562 else {
5563 CXTok.int_data[0] = Tok.is(tok::identifier)
5564 ? CXToken_Identifier
5565 : CXToken_Keyword;
5566 }
5567 CXTok.ptr_data = II;
5568 } else if (Tok.is(tok::comment)) {
5569 CXTok.int_data[0] = CXToken_Comment;
Craig Topper69186e72014-06-08 08:38:04 +00005570 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005571 } else {
5572 CXTok.int_data[0] = CXToken_Punctuation;
Craig Topper69186e72014-06-08 08:38:04 +00005573 CXTok.ptr_data = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005574 }
5575 CXTokens.push_back(CXTok);
5576 previousWasAt = Tok.is(tok::at);
5577 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5578}
5579
5580void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5581 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005582 LOG_FUNC_SECTION {
5583 *Log << TU << ' ' << Range;
5584 }
5585
Guy Benyei11169dd2012-12-18 14:30:41 +00005586 if (Tokens)
Craig Topper69186e72014-06-08 08:38:04 +00005587 *Tokens = nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00005588 if (NumTokens)
5589 *NumTokens = 0;
5590
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005591 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005592 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005593 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005594 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005595
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005596 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005597 if (!CXXUnit || !Tokens || !NumTokens)
5598 return;
5599
5600 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5601
5602 SourceRange R = cxloc::translateCXSourceRange(Range);
5603 if (R.isInvalid())
5604 return;
5605
5606 SmallVector<CXToken, 32> CXTokens;
5607 getTokens(CXXUnit, R, CXTokens);
5608
5609 if (CXTokens.empty())
5610 return;
5611
5612 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5613 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5614 *NumTokens = CXTokens.size();
5615}
5616
5617void clang_disposeTokens(CXTranslationUnit TU,
5618 CXToken *Tokens, unsigned NumTokens) {
5619 free(Tokens);
5620}
5621
5622} // end: extern "C"
5623
5624//===----------------------------------------------------------------------===//
5625// Token annotation APIs.
5626//===----------------------------------------------------------------------===//
5627
Guy Benyei11169dd2012-12-18 14:30:41 +00005628static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5629 CXCursor parent,
5630 CXClientData client_data);
5631static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5632 CXClientData client_data);
5633
5634namespace {
5635class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005636 CXToken *Tokens;
5637 CXCursor *Cursors;
5638 unsigned NumTokens;
5639 unsigned TokIdx;
5640 unsigned PreprocessingTokIdx;
5641 CursorVisitor AnnotateVis;
5642 SourceManager &SrcMgr;
5643 bool HasContextSensitiveKeywords;
5644
5645 struct PostChildrenInfo {
5646 CXCursor Cursor;
5647 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005648 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005649 unsigned BeforeChildrenTokenIdx;
5650 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005651 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005652
5653 CXToken &getTok(unsigned Idx) {
5654 assert(Idx < NumTokens);
5655 return Tokens[Idx];
5656 }
5657 const CXToken &getTok(unsigned Idx) const {
5658 assert(Idx < NumTokens);
5659 return Tokens[Idx];
5660 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005661 bool MoreTokens() const { return TokIdx < NumTokens; }
5662 unsigned NextToken() const { return TokIdx; }
5663 void AdvanceToken() { ++TokIdx; }
5664 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005665 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005666 }
5667 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005668 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005669 }
5670 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005671 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005672 }
5673
5674 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005675 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 SourceRange);
5677
5678public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005679 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005680 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005681 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005682 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005683 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005684 AnnotateTokensVisitor, this,
5685 /*VisitPreprocessorLast=*/true,
5686 /*VisitIncludedEntities=*/false,
5687 RegionOfInterest,
5688 /*VisitDeclsOnly=*/false,
5689 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005690 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 HasContextSensitiveKeywords(false) { }
5692
5693 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5694 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5695 bool postVisitChildren(CXCursor cursor);
5696 void AnnotateTokens();
5697
5698 /// \brief Determine whether the annotator saw any cursors that have
5699 /// context-sensitive keywords.
5700 bool hasContextSensitiveKeywords() const {
5701 return HasContextSensitiveKeywords;
5702 }
5703
5704 ~AnnotateTokensWorker() {
5705 assert(PostChildrenInfos.empty());
5706 }
5707};
Alexander Kornienkoab9db512015-06-22 23:07:51 +00005708}
Guy Benyei11169dd2012-12-18 14:30:41 +00005709
5710void AnnotateTokensWorker::AnnotateTokens() {
5711 // Walk the AST within the region of interest, annotating tokens
5712 // along the way.
5713 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005714}
Guy Benyei11169dd2012-12-18 14:30:41 +00005715
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005716static inline void updateCursorAnnotation(CXCursor &Cursor,
5717 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005718 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005719 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005720 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005721}
5722
5723/// \brief It annotates and advances tokens with a cursor until the comparison
5724//// between the cursor location and the source range is the same as
5725/// \arg compResult.
5726///
5727/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5728/// Pass RangeOverlap to annotate tokens inside a range.
5729void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5730 RangeComparisonResult compResult,
5731 SourceRange range) {
5732 while (MoreTokens()) {
5733 const unsigned I = NextToken();
5734 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005735 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5736 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005737
5738 SourceLocation TokLoc = GetTokenLoc(I);
5739 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005740 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 AdvanceToken();
5742 continue;
5743 }
5744 break;
5745 }
5746}
5747
5748/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005749/// \returns true if it advanced beyond all macro tokens, false otherwise.
5750bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005751 CXCursor updateC,
5752 RangeComparisonResult compResult,
5753 SourceRange range) {
5754 assert(MoreTokens());
5755 assert(isFunctionMacroToken(NextToken()) &&
5756 "Should be called only for macro arg tokens");
5757
5758 // This works differently than annotateAndAdvanceTokens; because expanded
5759 // macro arguments can have arbitrary translation-unit source order, we do not
5760 // advance the token index one by one until a token fails the range test.
5761 // We only advance once past all of the macro arg tokens if all of them
5762 // pass the range test. If one of them fails we keep the token index pointing
5763 // at the start of the macro arg tokens so that the failing token will be
5764 // annotated by a subsequent annotation try.
5765
5766 bool atLeastOneCompFail = false;
5767
5768 unsigned I = NextToken();
5769 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5770 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5771 if (TokLoc.isFileID())
5772 continue; // not macro arg token, it's parens or comma.
5773 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5774 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5775 Cursors[I] = updateC;
5776 } else
5777 atLeastOneCompFail = true;
5778 }
5779
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005780 if (atLeastOneCompFail)
5781 return false;
5782
5783 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5784 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005785}
5786
5787enum CXChildVisitResult
5788AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005789 SourceRange cursorRange = getRawCursorExtent(cursor);
5790 if (cursorRange.isInvalid())
5791 return CXChildVisit_Recurse;
5792
5793 if (!HasContextSensitiveKeywords) {
5794 // Objective-C properties can have context-sensitive keywords.
5795 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005796 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005797 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5798 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5799 }
5800 // Objective-C methods can have context-sensitive keywords.
5801 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5802 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005803 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005804 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5805 if (Method->getObjCDeclQualifier())
5806 HasContextSensitiveKeywords = true;
5807 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005808 for (const auto *P : Method->params()) {
5809 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005810 HasContextSensitiveKeywords = true;
5811 break;
5812 }
5813 }
5814 }
5815 }
5816 }
5817 // C++ methods can have context-sensitive keywords.
5818 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005819 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005820 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5821 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5822 HasContextSensitiveKeywords = true;
5823 }
5824 }
5825 // C++ classes can have context-sensitive keywords.
5826 else if (cursor.kind == CXCursor_StructDecl ||
5827 cursor.kind == CXCursor_ClassDecl ||
5828 cursor.kind == CXCursor_ClassTemplate ||
5829 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005830 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005831 if (D->hasAttr<FinalAttr>())
5832 HasContextSensitiveKeywords = true;
5833 }
5834 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005835
5836 // Don't override a property annotation with its getter/setter method.
5837 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5838 parent.kind == CXCursor_ObjCPropertyDecl)
5839 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005840
5841 if (clang_isPreprocessing(cursor.kind)) {
5842 // Items in the preprocessing record are kept separate from items in
5843 // declarations, so we keep a separate token index.
5844 unsigned SavedTokIdx = TokIdx;
5845 TokIdx = PreprocessingTokIdx;
5846
5847 // Skip tokens up until we catch up to the beginning of the preprocessing
5848 // entry.
5849 while (MoreTokens()) {
5850 const unsigned I = NextToken();
5851 SourceLocation TokLoc = GetTokenLoc(I);
5852 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5853 case RangeBefore:
5854 AdvanceToken();
5855 continue;
5856 case RangeAfter:
5857 case RangeOverlap:
5858 break;
5859 }
5860 break;
5861 }
5862
5863 // Look at all of the tokens within this range.
5864 while (MoreTokens()) {
5865 const unsigned I = NextToken();
5866 SourceLocation TokLoc = GetTokenLoc(I);
5867 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5868 case RangeBefore:
5869 llvm_unreachable("Infeasible");
5870 case RangeAfter:
5871 break;
5872 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005873 // For macro expansions, just note where the beginning of the macro
5874 // expansion occurs.
5875 if (cursor.kind == CXCursor_MacroExpansion) {
5876 if (TokLoc == cursorRange.getBegin())
5877 Cursors[I] = cursor;
5878 AdvanceToken();
5879 break;
5880 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005881 // We may have already annotated macro names inside macro definitions.
5882 if (Cursors[I].kind != CXCursor_MacroExpansion)
5883 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005884 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 continue;
5886 }
5887 break;
5888 }
5889
5890 // Save the preprocessing token index; restore the non-preprocessing
5891 // token index.
5892 PreprocessingTokIdx = TokIdx;
5893 TokIdx = SavedTokIdx;
5894 return CXChildVisit_Recurse;
5895 }
5896
5897 if (cursorRange.isInvalid())
5898 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005899
5900 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005902 const enum CXCursorKind K = clang_getCursorKind(parent);
5903 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005904 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5905 // Attributes are annotated out-of-order, skip tokens until we reach it.
5906 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005907 ? clang_getNullCursor() : parent;
5908
5909 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5910
5911 // Avoid having the cursor of an expression "overwrite" the annotation of the
5912 // variable declaration that it belongs to.
5913 // This can happen for C++ constructor expressions whose range generally
5914 // include the variable declaration, e.g.:
5915 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005916 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005917 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005918 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005919 const unsigned I = NextToken();
5920 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5921 E->getLocStart() == D->getLocation() &&
5922 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005923 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005924 AdvanceToken();
5925 }
5926 }
5927 }
5928
5929 // Before recursing into the children keep some state that we are going
5930 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5931 // extra work after the child nodes are visited.
5932 // Note that we don't call VisitChildren here to avoid traversing statements
5933 // code-recursively which can blow the stack.
5934
5935 PostChildrenInfo Info;
5936 Info.Cursor = cursor;
5937 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005938 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005939 Info.BeforeChildrenTokenIdx = NextToken();
5940 PostChildrenInfos.push_back(Info);
5941
5942 return CXChildVisit_Recurse;
5943}
5944
5945bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5946 if (PostChildrenInfos.empty())
5947 return false;
5948 const PostChildrenInfo &Info = PostChildrenInfos.back();
5949 if (!clang_equalCursors(Info.Cursor, cursor))
5950 return false;
5951
5952 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5953 const unsigned AfterChildren = NextToken();
5954 SourceRange cursorRange = Info.CursorRange;
5955
5956 // Scan the tokens that are at the end of the cursor, but are not captured
5957 // but the child cursors.
5958 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5959
5960 // Scan the tokens that are at the beginning of the cursor, but are not
5961 // capture by the child cursors.
5962 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5963 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5964 break;
5965
5966 Cursors[I] = cursor;
5967 }
5968
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005969 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5970 // encountered the attribute cursor.
5971 if (clang_isAttribute(cursor.kind))
5972 TokIdx = Info.BeforeReachingCursorIdx;
5973
Guy Benyei11169dd2012-12-18 14:30:41 +00005974 PostChildrenInfos.pop_back();
5975 return false;
5976}
5977
5978static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5979 CXCursor parent,
5980 CXClientData client_data) {
5981 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5982}
5983
5984static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5985 CXClientData client_data) {
5986 return static_cast<AnnotateTokensWorker*>(client_data)->
5987 postVisitChildren(cursor);
5988}
5989
5990namespace {
5991
5992/// \brief Uses the macro expansions in the preprocessing record to find
5993/// and mark tokens that are macro arguments. This info is used by the
5994/// AnnotateTokensWorker.
5995class MarkMacroArgTokensVisitor {
5996 SourceManager &SM;
5997 CXToken *Tokens;
5998 unsigned NumTokens;
5999 unsigned CurIdx;
6000
6001public:
6002 MarkMacroArgTokensVisitor(SourceManager &SM,
6003 CXToken *tokens, unsigned numTokens)
6004 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
6005
6006 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
6007 if (cursor.kind != CXCursor_MacroExpansion)
6008 return CXChildVisit_Continue;
6009
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006010 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 if (macroRange.getBegin() == macroRange.getEnd())
6012 return CXChildVisit_Continue; // it's not a function macro.
6013
6014 for (; CurIdx < NumTokens; ++CurIdx) {
6015 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
6016 macroRange.getBegin()))
6017 break;
6018 }
6019
6020 if (CurIdx == NumTokens)
6021 return CXChildVisit_Break;
6022
6023 for (; CurIdx < NumTokens; ++CurIdx) {
6024 SourceLocation tokLoc = getTokenLoc(CurIdx);
6025 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
6026 break;
6027
6028 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
6029 }
6030
6031 if (CurIdx == NumTokens)
6032 return CXChildVisit_Break;
6033
6034 return CXChildVisit_Continue;
6035 }
6036
6037private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006038 CXToken &getTok(unsigned Idx) {
6039 assert(Idx < NumTokens);
6040 return Tokens[Idx];
6041 }
6042 const CXToken &getTok(unsigned Idx) const {
6043 assert(Idx < NumTokens);
6044 return Tokens[Idx];
6045 }
6046
Guy Benyei11169dd2012-12-18 14:30:41 +00006047 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006048 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006049 }
6050
6051 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
6052 // The third field is reserved and currently not used. Use it here
6053 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00006054 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00006055 }
6056};
6057
6058} // end anonymous namespace
6059
6060static CXChildVisitResult
6061MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
6062 CXClientData client_data) {
6063 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
6064 parent);
6065}
6066
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006067/// \brief Used by \c annotatePreprocessorTokens.
6068/// \returns true if lexing was finished, false otherwise.
6069static bool lexNext(Lexer &Lex, Token &Tok,
6070 unsigned &NextIdx, unsigned NumTokens) {
6071 if (NextIdx >= NumTokens)
6072 return true;
6073
6074 ++NextIdx;
6075 Lex.LexFromRawLexer(Tok);
6076 if (Tok.is(tok::eof))
6077 return true;
6078
6079 return false;
6080}
6081
Guy Benyei11169dd2012-12-18 14:30:41 +00006082static void annotatePreprocessorTokens(CXTranslationUnit TU,
6083 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006084 CXCursor *Cursors,
6085 CXToken *Tokens,
6086 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006087 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006088
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006089 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 SourceManager &SourceMgr = CXXUnit->getSourceManager();
6091 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006092 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00006093 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006094 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00006095
6096 if (BeginLocInfo.first != EndLocInfo.first)
6097 return;
6098
6099 StringRef Buffer;
6100 bool Invalid = false;
6101 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
6102 if (Buffer.empty() || Invalid)
6103 return;
6104
6105 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
6106 CXXUnit->getASTContext().getLangOpts(),
6107 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
6108 Buffer.end());
6109 Lex.SetCommentRetentionState(true);
6110
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006111 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006112 // Lex tokens in raw mode until we hit the end of the range, to avoid
6113 // entering #includes or expanding macros.
6114 while (true) {
6115 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006116 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6117 break;
6118 unsigned TokIdx = NextIdx-1;
6119 assert(Tok.getLocation() ==
6120 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00006121
6122 reprocess:
6123 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006124 // We have found a preprocessing directive. Annotate the tokens
6125 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 //
6127 // FIXME: Some simple tests here could identify macro definitions and
6128 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006129
6130 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006131 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6132 break;
6133
Craig Topper69186e72014-06-08 08:38:04 +00006134 MacroInfo *MI = nullptr;
Alp Toker2d57cea2014-05-17 04:53:25 +00006135 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006136 if (lexNext(Lex, Tok, NextIdx, NumTokens))
6137 break;
6138
6139 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00006140 IdentifierInfo &II =
6141 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006142 SourceLocation MappedTokLoc =
6143 CXXUnit->mapLocationToPreamble(Tok.getLocation());
6144 MI = getMacroInfo(II, MappedTokLoc, TU);
6145 }
6146 }
6147
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006148 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006150 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
6151 finished = true;
6152 break;
6153 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006154 // If we are in a macro definition, check if the token was ever a
6155 // macro name and annotate it if that's the case.
6156 if (MI) {
6157 SourceLocation SaveLoc = Tok.getLocation();
6158 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
Richard Smith66a81862015-05-04 02:25:31 +00006159 MacroDefinitionRecord *MacroDef =
6160 checkForMacroInMacroDefinition(MI, Tok, TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006161 Tok.setLocation(SaveLoc);
6162 if (MacroDef)
Richard Smith66a81862015-05-04 02:25:31 +00006163 Cursors[NextIdx - 1] =
6164 MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006165 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006166 } while (!Tok.isAtStartOfLine());
6167
6168 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
6169 assert(TokIdx <= LastIdx);
6170 SourceLocation EndLoc =
6171 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
6172 CXCursor Cursor =
6173 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
6174
6175 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00006176 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006177
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006178 if (finished)
6179 break;
6180 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00006181 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006182 }
6183}
6184
6185// This gets run a separate thread to avoid stack blowout.
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006186static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
6187 CXToken *Tokens, unsigned NumTokens,
6188 CXCursor *Cursors) {
Dmitri Gribenko183436e2013-01-26 21:49:50 +00006189 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
6191 setThreadBackgroundPriority();
6192
6193 // Determine the region of interest, which contains all of the tokens.
6194 SourceRange RegionOfInterest;
6195 RegionOfInterest.setBegin(
6196 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
6197 RegionOfInterest.setEnd(
6198 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
6199 Tokens[NumTokens-1])));
6200
Guy Benyei11169dd2012-12-18 14:30:41 +00006201 // Relex the tokens within the source range to look for preprocessing
6202 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006203 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00006204
6205 // If begin location points inside a macro argument, set it to the expansion
6206 // location so we can have the full context when annotating semantically.
6207 {
6208 SourceManager &SM = CXXUnit->getSourceManager();
6209 SourceLocation Loc =
6210 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
6211 if (Loc.isMacroID())
6212 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
6213 }
6214
Guy Benyei11169dd2012-12-18 14:30:41 +00006215 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
6216 // Search and mark tokens that are macro argument expansions.
6217 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
6218 Tokens, NumTokens);
6219 CursorVisitor MacroArgMarker(TU,
6220 MarkMacroArgTokensVisitorDelegate, &Visitor,
6221 /*VisitPreprocessorLast=*/true,
6222 /*VisitIncludedEntities=*/false,
6223 RegionOfInterest);
6224 MacroArgMarker.visitPreprocessedEntitiesInRegion();
6225 }
6226
6227 // Annotate all of the source locations in the region of interest that map to
6228 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006229 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00006230
6231 // FIXME: We use a ridiculous stack size here because the data-recursion
6232 // algorithm uses a large stack frame than the non-data recursive version,
6233 // and AnnotationTokensWorker currently transforms the data-recursion
6234 // algorithm back into a traditional recursion by explicitly calling
6235 // VisitChildren(). We will need to remove this explicit recursive call.
6236 W.AnnotateTokens();
6237
6238 // If we ran into any entities that involve context-sensitive keywords,
6239 // take another pass through the tokens to mark them as such.
6240 if (W.hasContextSensitiveKeywords()) {
6241 for (unsigned I = 0; I != NumTokens; ++I) {
6242 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
6243 continue;
6244
6245 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
6246 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006247 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00006248 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
6249 if (Property->getPropertyAttributesAsWritten() != 0 &&
6250 llvm::StringSwitch<bool>(II->getName())
6251 .Case("readonly", true)
6252 .Case("assign", true)
6253 .Case("unsafe_unretained", true)
6254 .Case("readwrite", true)
6255 .Case("retain", true)
6256 .Case("copy", true)
6257 .Case("nonatomic", true)
6258 .Case("atomic", true)
6259 .Case("getter", true)
6260 .Case("setter", true)
6261 .Case("strong", true)
6262 .Case("weak", true)
6263 .Default(false))
6264 Tokens[I].int_data[0] = CXToken_Keyword;
6265 }
6266 continue;
6267 }
6268
6269 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
6270 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
6271 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
6272 if (llvm::StringSwitch<bool>(II->getName())
6273 .Case("in", true)
6274 .Case("out", true)
6275 .Case("inout", true)
6276 .Case("oneway", true)
6277 .Case("bycopy", true)
6278 .Case("byref", true)
6279 .Default(false))
6280 Tokens[I].int_data[0] = CXToken_Keyword;
6281 continue;
6282 }
6283
6284 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
6285 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
6286 Tokens[I].int_data[0] = CXToken_Keyword;
6287 continue;
6288 }
6289 }
6290 }
6291}
6292
6293extern "C" {
6294
6295void clang_annotateTokens(CXTranslationUnit TU,
6296 CXToken *Tokens, unsigned NumTokens,
6297 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006298 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006299 LOG_BAD_TU(TU);
6300 return;
6301 }
6302 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006303 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00006304 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006305 }
6306
6307 LOG_FUNC_SECTION {
6308 *Log << TU << ' ';
6309 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
6310 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
6311 *Log << clang_getRange(bloc, eloc);
6312 }
Guy Benyei11169dd2012-12-18 14:30:41 +00006313
6314 // Any token we don't specifically annotate will have a NULL cursor.
6315 CXCursor C = clang_getNullCursor();
6316 for (unsigned I = 0; I != NumTokens; ++I)
6317 Cursors[I] = C;
6318
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006319 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006320 if (!CXXUnit)
6321 return;
6322
6323 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006324
6325 auto AnnotateTokensImpl = [=]() {
6326 clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
6327 };
Guy Benyei11169dd2012-12-18 14:30:41 +00006328 llvm::CrashRecoveryContext CRC;
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00006329 if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006330 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
6331 }
6332}
6333
6334} // end: extern "C"
6335
6336//===----------------------------------------------------------------------===//
6337// Operations for querying linkage of a cursor.
6338//===----------------------------------------------------------------------===//
6339
6340extern "C" {
6341CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
6342 if (!clang_isDeclaration(cursor.kind))
6343 return CXLinkage_Invalid;
6344
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006345 const Decl *D = cxcursor::getCursorDecl(cursor);
6346 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00006347 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00006348 case NoLinkage:
6349 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00006350 case InternalLinkage: return CXLinkage_Internal;
6351 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
6352 case ExternalLinkage: return CXLinkage_External;
6353 };
6354
6355 return CXLinkage_Invalid;
6356}
6357} // end: extern "C"
6358
6359//===----------------------------------------------------------------------===//
6360// Operations for querying language of a cursor.
6361//===----------------------------------------------------------------------===//
6362
6363static CXLanguageKind getDeclLanguage(const Decl *D) {
6364 if (!D)
6365 return CXLanguage_C;
6366
6367 switch (D->getKind()) {
6368 default:
6369 break;
6370 case Decl::ImplicitParam:
6371 case Decl::ObjCAtDefsField:
6372 case Decl::ObjCCategory:
6373 case Decl::ObjCCategoryImpl:
6374 case Decl::ObjCCompatibleAlias:
6375 case Decl::ObjCImplementation:
6376 case Decl::ObjCInterface:
6377 case Decl::ObjCIvar:
6378 case Decl::ObjCMethod:
6379 case Decl::ObjCProperty:
6380 case Decl::ObjCPropertyImpl:
6381 case Decl::ObjCProtocol:
Douglas Gregor85f3f952015-07-07 03:57:15 +00006382 case Decl::ObjCTypeParam:
Guy Benyei11169dd2012-12-18 14:30:41 +00006383 return CXLanguage_ObjC;
6384 case Decl::CXXConstructor:
6385 case Decl::CXXConversion:
6386 case Decl::CXXDestructor:
6387 case Decl::CXXMethod:
6388 case Decl::CXXRecord:
6389 case Decl::ClassTemplate:
6390 case Decl::ClassTemplatePartialSpecialization:
6391 case Decl::ClassTemplateSpecialization:
6392 case Decl::Friend:
6393 case Decl::FriendTemplate:
6394 case Decl::FunctionTemplate:
6395 case Decl::LinkageSpec:
6396 case Decl::Namespace:
6397 case Decl::NamespaceAlias:
6398 case Decl::NonTypeTemplateParm:
6399 case Decl::StaticAssert:
6400 case Decl::TemplateTemplateParm:
6401 case Decl::TemplateTypeParm:
6402 case Decl::UnresolvedUsingTypename:
6403 case Decl::UnresolvedUsingValue:
6404 case Decl::Using:
6405 case Decl::UsingDirective:
6406 case Decl::UsingShadow:
6407 return CXLanguage_CPlusPlus;
6408 }
6409
6410 return CXLanguage_C;
6411}
6412
6413extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006414
6415static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
6416 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
Manuel Klimek8e3a7ed2015-09-25 17:53:16 +00006417 return CXAvailability_NotAvailable;
Guy Benyei11169dd2012-12-18 14:30:41 +00006418
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006419 switch (D->getAvailability()) {
6420 case AR_Available:
6421 case AR_NotYetIntroduced:
6422 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006423 return getCursorAvailabilityForDecl(
6424 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006425 return CXAvailability_Available;
6426
6427 case AR_Deprecated:
6428 return CXAvailability_Deprecated;
6429
6430 case AR_Unavailable:
6431 return CXAvailability_NotAvailable;
6432 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006433
6434 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006435}
6436
Guy Benyei11169dd2012-12-18 14:30:41 +00006437enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6438 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006439 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6440 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006441
6442 return CXAvailability_Available;
6443}
6444
6445static CXVersion convertVersion(VersionTuple In) {
6446 CXVersion Out = { -1, -1, -1 };
6447 if (In.empty())
6448 return Out;
6449
6450 Out.Major = In.getMajor();
6451
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006452 Optional<unsigned> Minor = In.getMinor();
6453 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006454 Out.Minor = *Minor;
6455 else
6456 return Out;
6457
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006458 Optional<unsigned> Subminor = In.getSubminor();
6459 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006460 Out.Subminor = *Subminor;
6461
6462 return Out;
6463}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006464
6465static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6466 int *always_deprecated,
6467 CXString *deprecated_message,
6468 int *always_unavailable,
6469 CXString *unavailable_message,
6470 CXPlatformAvailability *availability,
6471 int availability_size) {
6472 bool HadAvailAttr = false;
6473 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006474 for (auto A : D->attrs()) {
6475 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006476 HadAvailAttr = true;
6477 if (always_deprecated)
6478 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006479 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006480 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006481 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006482 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006483 continue;
6484 }
6485
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006486 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006487 HadAvailAttr = true;
6488 if (always_unavailable)
6489 *always_unavailable = 1;
6490 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006491 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006492 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6493 }
6494 continue;
6495 }
6496
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006497 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006498 HadAvailAttr = true;
6499 if (N < availability_size) {
6500 availability[N].Platform
6501 = cxstring::createDup(Avail->getPlatform()->getName());
6502 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6503 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6504 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6505 availability[N].Unavailable = Avail->getUnavailable();
6506 availability[N].Message = cxstring::createDup(Avail->getMessage());
6507 }
6508 ++N;
6509 }
6510 }
6511
6512 if (!HadAvailAttr)
6513 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6514 return getCursorPlatformAvailabilityForDecl(
6515 cast<Decl>(EnumConst->getDeclContext()),
6516 always_deprecated,
6517 deprecated_message,
6518 always_unavailable,
6519 unavailable_message,
6520 availability,
6521 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006522
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006523 return N;
6524}
6525
Guy Benyei11169dd2012-12-18 14:30:41 +00006526int clang_getCursorPlatformAvailability(CXCursor cursor,
6527 int *always_deprecated,
6528 CXString *deprecated_message,
6529 int *always_unavailable,
6530 CXString *unavailable_message,
6531 CXPlatformAvailability *availability,
6532 int availability_size) {
6533 if (always_deprecated)
6534 *always_deprecated = 0;
6535 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006536 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006537 if (always_unavailable)
6538 *always_unavailable = 0;
6539 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006540 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006541
Guy Benyei11169dd2012-12-18 14:30:41 +00006542 if (!clang_isDeclaration(cursor.kind))
6543 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006544
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006545 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006546 if (!D)
6547 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006548
6549 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6550 deprecated_message,
6551 always_unavailable,
6552 unavailable_message,
6553 availability,
6554 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006555}
6556
6557void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6558 clang_disposeString(availability->Platform);
6559 clang_disposeString(availability->Message);
6560}
6561
6562CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6563 if (clang_isDeclaration(cursor.kind))
6564 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6565
6566 return CXLanguage_Invalid;
6567}
6568
6569 /// \brief If the given cursor is the "templated" declaration
6570 /// descibing a class or function template, return the class or
6571 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006572static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006573 if (!D)
Craig Topper69186e72014-06-08 08:38:04 +00006574 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006575
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006576 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006577 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6578 return FunTmpl;
6579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006580 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006581 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6582 return ClassTmpl;
6583
6584 return D;
6585}
6586
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006587
6588enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
6589 StorageClass sc = SC_None;
6590 const Decl *D = getCursorDecl(C);
6591 if (D) {
6592 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
6593 sc = FD->getStorageClass();
6594 } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
6595 sc = VD->getStorageClass();
6596 } else {
6597 return CX_SC_Invalid;
6598 }
6599 } else {
6600 return CX_SC_Invalid;
6601 }
6602 switch (sc) {
6603 case SC_None:
6604 return CX_SC_None;
6605 case SC_Extern:
6606 return CX_SC_Extern;
6607 case SC_Static:
6608 return CX_SC_Static;
6609 case SC_PrivateExtern:
6610 return CX_SC_PrivateExtern;
6611 case SC_OpenCLWorkGroupLocal:
6612 return CX_SC_OpenCLWorkGroupLocal;
6613 case SC_Auto:
6614 return CX_SC_Auto;
6615 case SC_Register:
6616 return CX_SC_Register;
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006617 }
Kaelyn Takataab61e702014-10-15 18:03:26 +00006618 llvm_unreachable("Unhandled storage class!");
Argyrios Kyrtzidis4e0854f2014-10-15 17:05:31 +00006619}
6620
Guy Benyei11169dd2012-12-18 14:30:41 +00006621CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6622 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006623 if (const Decl *D = getCursorDecl(cursor)) {
6624 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006625 if (!DC)
6626 return clang_getNullCursor();
6627
6628 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6629 getCursorTU(cursor));
6630 }
6631 }
6632
6633 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006634 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006635 return MakeCXCursor(D, getCursorTU(cursor));
6636 }
6637
6638 return clang_getNullCursor();
6639}
6640
6641CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6642 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006643 if (const Decl *D = getCursorDecl(cursor)) {
6644 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006645 if (!DC)
6646 return clang_getNullCursor();
6647
6648 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6649 getCursorTU(cursor));
6650 }
6651 }
6652
6653 // FIXME: Note that we can't easily compute the lexical context of a
6654 // statement or expression, so we return nothing.
6655 return clang_getNullCursor();
6656}
6657
6658CXFile clang_getIncludedFile(CXCursor cursor) {
6659 if (cursor.kind != CXCursor_InclusionDirective)
Craig Topper69186e72014-06-08 08:38:04 +00006660 return nullptr;
6661
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006662 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006663 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006664}
6665
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006666unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6667 if (C.kind != CXCursor_ObjCPropertyDecl)
6668 return CXObjCPropertyAttr_noattr;
6669
6670 unsigned Result = CXObjCPropertyAttr_noattr;
6671 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6672 ObjCPropertyDecl::PropertyAttributeKind Attr =
6673 PD->getPropertyAttributesAsWritten();
6674
6675#define SET_CXOBJCPROP_ATTR(A) \
6676 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6677 Result |= CXObjCPropertyAttr_##A
6678 SET_CXOBJCPROP_ATTR(readonly);
6679 SET_CXOBJCPROP_ATTR(getter);
6680 SET_CXOBJCPROP_ATTR(assign);
6681 SET_CXOBJCPROP_ATTR(readwrite);
6682 SET_CXOBJCPROP_ATTR(retain);
6683 SET_CXOBJCPROP_ATTR(copy);
6684 SET_CXOBJCPROP_ATTR(nonatomic);
6685 SET_CXOBJCPROP_ATTR(setter);
6686 SET_CXOBJCPROP_ATTR(atomic);
6687 SET_CXOBJCPROP_ATTR(weak);
6688 SET_CXOBJCPROP_ATTR(strong);
6689 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6690#undef SET_CXOBJCPROP_ATTR
6691
6692 return Result;
6693}
6694
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006695unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6696 if (!clang_isDeclaration(C.kind))
6697 return CXObjCDeclQualifier_None;
6698
6699 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6700 const Decl *D = getCursorDecl(C);
6701 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6702 QT = MD->getObjCDeclQualifier();
6703 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6704 QT = PD->getObjCDeclQualifier();
6705 if (QT == Decl::OBJC_TQ_None)
6706 return CXObjCDeclQualifier_None;
6707
6708 unsigned Result = CXObjCDeclQualifier_None;
6709 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6710 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6711 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6712 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6713 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6714 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6715
6716 return Result;
6717}
6718
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006719unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6720 if (!clang_isDeclaration(C.kind))
6721 return 0;
6722
6723 const Decl *D = getCursorDecl(C);
6724 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6725 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6726 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6727 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6728
6729 return 0;
6730}
6731
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006732unsigned clang_Cursor_isVariadic(CXCursor C) {
6733 if (!clang_isDeclaration(C.kind))
6734 return 0;
6735
6736 const Decl *D = getCursorDecl(C);
6737 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6738 return FD->isVariadic();
6739 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6740 return MD->isVariadic();
6741
6742 return 0;
6743}
6744
Guy Benyei11169dd2012-12-18 14:30:41 +00006745CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6746 if (!clang_isDeclaration(C.kind))
6747 return clang_getNullRange();
6748
6749 const Decl *D = getCursorDecl(C);
6750 ASTContext &Context = getCursorContext(C);
6751 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6752 if (!RC)
6753 return clang_getNullRange();
6754
6755 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6756}
6757
6758CXString clang_Cursor_getRawCommentText(CXCursor C) {
6759 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006760 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006761
6762 const Decl *D = getCursorDecl(C);
6763 ASTContext &Context = getCursorContext(C);
6764 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6765 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6766 StringRef();
6767
6768 // Don't duplicate the string because RawText points directly into source
6769 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006770 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006771}
6772
6773CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6774 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006775 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006776
6777 const Decl *D = getCursorDecl(C);
6778 const ASTContext &Context = getCursorContext(C);
6779 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6780
6781 if (RC) {
6782 StringRef BriefText = RC->getBriefText(Context);
6783
6784 // Don't duplicate the string because RawComment ensures that this memory
6785 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006786 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006787 }
6788
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006789 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006790}
6791
Guy Benyei11169dd2012-12-18 14:30:41 +00006792CXModule clang_Cursor_getModule(CXCursor C) {
6793 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006794 if (const ImportDecl *ImportD =
6795 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006796 return ImportD->getImportedModule();
6797 }
6798
Craig Topper69186e72014-06-08 08:38:04 +00006799 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006800}
6801
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006802CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6803 if (isNotUsableTU(TU)) {
6804 LOG_BAD_TU(TU);
6805 return nullptr;
6806 }
6807 if (!File)
6808 return nullptr;
6809 FileEntry *FE = static_cast<FileEntry *>(File);
6810
6811 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6812 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6813 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6814
Richard Smithfeb54b62014-10-23 02:01:19 +00006815 return Header.getModule();
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006816}
6817
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006818CXFile clang_Module_getASTFile(CXModule CXMod) {
6819 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006820 return nullptr;
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006821 Module *Mod = static_cast<Module*>(CXMod);
6822 return const_cast<FileEntry *>(Mod->getASTFile());
6823}
6824
Guy Benyei11169dd2012-12-18 14:30:41 +00006825CXModule clang_Module_getParent(CXModule CXMod) {
6826 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006827 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006828 Module *Mod = static_cast<Module*>(CXMod);
6829 return Mod->Parent;
6830}
6831
6832CXString clang_Module_getName(CXModule CXMod) {
6833 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006834 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006835 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006836 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006837}
6838
6839CXString clang_Module_getFullName(CXModule CXMod) {
6840 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006841 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006842 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006843 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006844}
6845
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006846int clang_Module_isSystem(CXModule CXMod) {
6847 if (!CXMod)
6848 return 0;
6849 Module *Mod = static_cast<Module*>(CXMod);
6850 return Mod->IsSystem;
6851}
6852
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006853unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6854 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006855 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006856 LOG_BAD_TU(TU);
6857 return 0;
6858 }
6859 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006860 return 0;
6861 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006862 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6863 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6864 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006865}
6866
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006867CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6868 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006869 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006870 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00006871 return nullptr;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006872 }
6873 if (!CXMod)
Craig Topper69186e72014-06-08 08:38:04 +00006874 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006875 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006876 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006877
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006878 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6879 if (Index < TopHeaders.size())
6880 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006881
Craig Topper69186e72014-06-08 08:38:04 +00006882 return nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006883}
6884
6885} // end: extern "C"
6886
6887//===----------------------------------------------------------------------===//
6888// C++ AST instrospection.
6889//===----------------------------------------------------------------------===//
6890
6891extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006892unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6893 if (!clang_isDeclaration(C.kind))
6894 return 0;
6895
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006896 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006897 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006898 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006899 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6900}
6901
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006902unsigned clang_CXXMethod_isConst(CXCursor C) {
6903 if (!clang_isDeclaration(C.kind))
6904 return 0;
6905
6906 const Decl *D = cxcursor::getCursorDecl(C);
6907 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006908 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006909 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6910}
6911
Guy Benyei11169dd2012-12-18 14:30:41 +00006912unsigned clang_CXXMethod_isStatic(CXCursor C) {
6913 if (!clang_isDeclaration(C.kind))
6914 return 0;
6915
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006916 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006917 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006918 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006919 return (Method && Method->isStatic()) ? 1 : 0;
6920}
6921
6922unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6923 if (!clang_isDeclaration(C.kind))
6924 return 0;
6925
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006926 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006927 const CXXMethodDecl *Method =
Craig Topper69186e72014-06-08 08:38:04 +00006928 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
Guy Benyei11169dd2012-12-18 14:30:41 +00006929 return (Method && Method->isVirtual()) ? 1 : 0;
6930}
6931} // end: extern "C"
6932
6933//===----------------------------------------------------------------------===//
6934// Attribute introspection.
6935//===----------------------------------------------------------------------===//
6936
6937extern "C" {
6938CXType clang_getIBOutletCollectionType(CXCursor C) {
6939 if (C.kind != CXCursor_IBOutletCollectionAttr)
6940 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6941
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006942 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006943 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6944
6945 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6946}
6947} // end: extern "C"
6948
6949//===----------------------------------------------------------------------===//
6950// Inspecting memory usage.
6951//===----------------------------------------------------------------------===//
6952
6953typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6954
6955static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6956 enum CXTUResourceUsageKind k,
6957 unsigned long amount) {
6958 CXTUResourceUsageEntry entry = { k, amount };
6959 entries.push_back(entry);
6960}
6961
6962extern "C" {
6963
6964const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6965 const char *str = "";
6966 switch (kind) {
6967 case CXTUResourceUsage_AST:
6968 str = "ASTContext: expressions, declarations, and types";
6969 break;
6970 case CXTUResourceUsage_Identifiers:
6971 str = "ASTContext: identifiers";
6972 break;
6973 case CXTUResourceUsage_Selectors:
6974 str = "ASTContext: selectors";
6975 break;
6976 case CXTUResourceUsage_GlobalCompletionResults:
6977 str = "Code completion: cached global results";
6978 break;
6979 case CXTUResourceUsage_SourceManagerContentCache:
6980 str = "SourceManager: content cache allocator";
6981 break;
6982 case CXTUResourceUsage_AST_SideTables:
6983 str = "ASTContext: side tables";
6984 break;
6985 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6986 str = "SourceManager: malloc'ed memory buffers";
6987 break;
6988 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6989 str = "SourceManager: mmap'ed memory buffers";
6990 break;
6991 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6992 str = "ExternalASTSource: malloc'ed memory buffers";
6993 break;
6994 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6995 str = "ExternalASTSource: mmap'ed memory buffers";
6996 break;
6997 case CXTUResourceUsage_Preprocessor:
6998 str = "Preprocessor: malloc'ed memory";
6999 break;
7000 case CXTUResourceUsage_PreprocessingRecord:
7001 str = "Preprocessor: PreprocessingRecord";
7002 break;
7003 case CXTUResourceUsage_SourceManager_DataStructures:
7004 str = "SourceManager: data structures and tables";
7005 break;
7006 case CXTUResourceUsage_Preprocessor_HeaderSearch:
7007 str = "Preprocessor: header search tables";
7008 break;
7009 }
7010 return str;
7011}
7012
7013CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007014 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007015 LOG_BAD_TU(TU);
Craig Topper69186e72014-06-08 08:38:04 +00007016 CXTUResourceUsage usage = { (void*) nullptr, 0, nullptr };
Guy Benyei11169dd2012-12-18 14:30:41 +00007017 return usage;
7018 }
7019
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007020 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00007021 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00007022 ASTContext &astContext = astUnit->getASTContext();
7023
7024 // How much memory is used by AST nodes and types?
7025 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
7026 (unsigned long) astContext.getASTAllocatedMemory());
7027
7028 // How much memory is used by identifiers?
7029 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
7030 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
7031
7032 // How much memory is used for selectors?
7033 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
7034 (unsigned long) astContext.Selectors.getTotalMemory());
7035
7036 // How much memory is used by ASTContext's side tables?
7037 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
7038 (unsigned long) astContext.getSideTableAllocatedMemory());
7039
7040 // How much memory is used for caching global code completion results?
7041 unsigned long completionBytes = 0;
7042 if (GlobalCodeCompletionAllocator *completionAllocator =
Alp Tokerf994cef2014-07-05 03:08:06 +00007043 astUnit->getCachedCompletionAllocator().get()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00007044 completionBytes = completionAllocator->getTotalMemory();
7045 }
7046 createCXTUResourceUsageEntry(*entries,
7047 CXTUResourceUsage_GlobalCompletionResults,
7048 completionBytes);
7049
7050 // How much memory is being used by SourceManager's content cache?
7051 createCXTUResourceUsageEntry(*entries,
7052 CXTUResourceUsage_SourceManagerContentCache,
7053 (unsigned long) astContext.getSourceManager().getContentCacheSize());
7054
7055 // How much memory is being used by the MemoryBuffer's in SourceManager?
7056 const SourceManager::MemoryBufferSizes &srcBufs =
7057 astUnit->getSourceManager().getMemoryBufferSizes();
7058
7059 createCXTUResourceUsageEntry(*entries,
7060 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
7061 (unsigned long) srcBufs.malloc_bytes);
7062 createCXTUResourceUsageEntry(*entries,
7063 CXTUResourceUsage_SourceManager_Membuffer_MMap,
7064 (unsigned long) srcBufs.mmap_bytes);
7065 createCXTUResourceUsageEntry(*entries,
7066 CXTUResourceUsage_SourceManager_DataStructures,
7067 (unsigned long) astContext.getSourceManager()
7068 .getDataStructureSizes());
7069
7070 // How much memory is being used by the ExternalASTSource?
7071 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
7072 const ExternalASTSource::MemoryBufferSizes &sizes =
7073 esrc->getMemoryBufferSizes();
7074
7075 createCXTUResourceUsageEntry(*entries,
7076 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
7077 (unsigned long) sizes.malloc_bytes);
7078 createCXTUResourceUsageEntry(*entries,
7079 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
7080 (unsigned long) sizes.mmap_bytes);
7081 }
7082
7083 // How much memory is being used by the Preprocessor?
7084 Preprocessor &pp = astUnit->getPreprocessor();
7085 createCXTUResourceUsageEntry(*entries,
7086 CXTUResourceUsage_Preprocessor,
7087 pp.getTotalMemory());
7088
7089 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
7090 createCXTUResourceUsageEntry(*entries,
7091 CXTUResourceUsage_PreprocessingRecord,
7092 pRec->getTotalMemory());
7093 }
7094
7095 createCXTUResourceUsageEntry(*entries,
7096 CXTUResourceUsage_Preprocessor_HeaderSearch,
7097 pp.getHeaderSearchInfo().getTotalMemory());
Craig Topper69186e72014-06-08 08:38:04 +00007098
Guy Benyei11169dd2012-12-18 14:30:41 +00007099 CXTUResourceUsage usage = { (void*) entries.get(),
7100 (unsigned) entries->size(),
Alexander Kornienko6ee521c2015-01-23 15:36:10 +00007101 !entries->empty() ? &(*entries)[0] : nullptr };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00007102 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00007103 return usage;
7104}
7105
7106void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
7107 if (usage.data)
7108 delete (MemUsageEntries*) usage.data;
7109}
7110
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007111CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
7112 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007113 skipped->count = 0;
Craig Topper69186e72014-06-08 08:38:04 +00007114 skipped->ranges = nullptr;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007115
Dmitri Gribenko852d6222014-02-11 15:02:48 +00007116 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00007117 LOG_BAD_TU(TU);
7118 return skipped;
7119 }
7120
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007121 if (!file)
7122 return skipped;
7123
7124 ASTUnit *astUnit = cxtu::getASTUnit(TU);
7125 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
7126 if (!ppRec)
7127 return skipped;
7128
7129 ASTContext &Ctx = astUnit->getASTContext();
7130 SourceManager &sm = Ctx.getSourceManager();
7131 FileEntry *fileEntry = static_cast<FileEntry *>(file);
7132 FileID wantedFileID = sm.translateFile(fileEntry);
7133
7134 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
7135 std::vector<SourceRange> wantedRanges;
7136 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
7137 i != ei; ++i) {
7138 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
7139 wantedRanges.push_back(*i);
7140 }
7141
7142 skipped->count = wantedRanges.size();
7143 skipped->ranges = new CXSourceRange[skipped->count];
7144 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
7145 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
7146
7147 return skipped;
7148}
7149
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00007150void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
7151 if (ranges) {
7152 delete[] ranges->ranges;
7153 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00007154 }
7155}
7156
Guy Benyei11169dd2012-12-18 14:30:41 +00007157} // end extern "C"
7158
7159void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
7160 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
7161 for (unsigned I = 0; I != Usage.numEntries; ++I)
7162 fprintf(stderr, " %s: %lu\n",
7163 clang_getTUResourceUsageName(Usage.entries[I].kind),
7164 Usage.entries[I].amount);
7165
7166 clang_disposeCXTUResourceUsage(Usage);
7167}
7168
7169//===----------------------------------------------------------------------===//
7170// Misc. utility functions.
7171//===----------------------------------------------------------------------===//
7172
7173/// Default to using an 8 MB stack size on "safety" threads.
7174static unsigned SafetyStackThreadSize = 8 << 20;
7175
7176namespace clang {
7177
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007178bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
Guy Benyei11169dd2012-12-18 14:30:41 +00007179 unsigned Size) {
7180 if (!Size)
7181 Size = GetSafetyThreadStackSize();
7182 if (Size)
Benjamin Kramer11a9cd92015-07-25 20:55:44 +00007183 return CRC.RunSafelyOnThread(Fn, Size);
7184 return CRC.RunSafely(Fn);
Guy Benyei11169dd2012-12-18 14:30:41 +00007185}
7186
7187unsigned GetSafetyThreadStackSize() {
7188 return SafetyStackThreadSize;
7189}
7190
7191void SetSafetyThreadStackSize(unsigned Value) {
7192 SafetyStackThreadSize = Value;
7193}
7194
Alexander Kornienkoab9db512015-06-22 23:07:51 +00007195}
Guy Benyei11169dd2012-12-18 14:30:41 +00007196
7197void clang::setThreadBackgroundPriority() {
7198 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
7199 return;
7200
Alp Toker1a86ad22014-07-06 06:24:00 +00007201#ifdef USE_DARWIN_THREADS
Guy Benyei11169dd2012-12-18 14:30:41 +00007202 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
7203#endif
7204}
7205
7206void cxindex::printDiagsToStderr(ASTUnit *Unit) {
7207 if (!Unit)
7208 return;
7209
7210 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
7211 DEnd = Unit->stored_diag_end();
7212 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00007213 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00007214 CXString Msg = clang_formatDiagnostic(&Diag,
7215 clang_defaultDiagnosticDisplayOptions());
7216 fprintf(stderr, "%s\n", clang_getCString(Msg));
7217 clang_disposeString(Msg);
7218 }
7219#ifdef LLVM_ON_WIN32
7220 // On Windows, force a flush, since there may be multiple copies of
7221 // stderr and stdout in the file system, all with different buffers
7222 // but writing to the same device.
7223 fflush(stderr);
7224#endif
7225}
7226
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007227MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
7228 SourceLocation MacroDefLoc,
7229 CXTranslationUnit TU){
7230 if (MacroDefLoc.isInvalid() || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007231 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007232 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007233 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007234
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007235 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00007236 Preprocessor &PP = Unit->getPreprocessor();
Richard Smith20e883e2015-04-29 23:20:19 +00007237 MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007238 if (MD) {
7239 for (MacroDirective::DefInfo
7240 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
7241 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
7242 return Def.getMacroInfo();
7243 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007244 }
7245
Craig Topper69186e72014-06-08 08:38:04 +00007246 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007247}
7248
Richard Smith66a81862015-05-04 02:25:31 +00007249const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00007250 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007251 if (!MacroDef || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007252 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007253 const IdentifierInfo *II = MacroDef->getName();
7254 if (!II)
Craig Topper69186e72014-06-08 08:38:04 +00007255 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007256
7257 return getMacroInfo(*II, MacroDef->getLocation(), TU);
7258}
7259
Richard Smith66a81862015-05-04 02:25:31 +00007260MacroDefinitionRecord *
7261cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
7262 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007263 if (!MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007264 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007265 if (Tok.isNot(tok::raw_identifier))
Craig Topper69186e72014-06-08 08:38:04 +00007266 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007267
7268 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007269 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007270 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
7271 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007272 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007273
7274 // Check that the token is inside the definition and not its argument list.
7275 SourceManager &SM = Unit->getSourceManager();
7276 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
Craig Topper69186e72014-06-08 08:38:04 +00007277 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007278 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
Craig Topper69186e72014-06-08 08:38:04 +00007279 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007280
7281 Preprocessor &PP = Unit->getPreprocessor();
7282 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
7283 if (!PPRec)
Craig Topper69186e72014-06-08 08:38:04 +00007284 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007285
Alp Toker2d57cea2014-05-17 04:53:25 +00007286 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007287 if (!II.hadMacroDefinition())
Craig Topper69186e72014-06-08 08:38:04 +00007288 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007289
7290 // Check that the identifier is not one of the macro arguments.
7291 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
Craig Topper69186e72014-06-08 08:38:04 +00007292 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007293
Richard Smith20e883e2015-04-29 23:20:19 +00007294 MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00007295 if (!InnerMD)
Craig Topper69186e72014-06-08 08:38:04 +00007296 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007297
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00007298 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007299}
7300
Richard Smith66a81862015-05-04 02:25:31 +00007301MacroDefinitionRecord *
7302cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
7303 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007304 if (Loc.isInvalid() || !MI || !TU)
Craig Topper69186e72014-06-08 08:38:04 +00007305 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007306
7307 if (MI->getNumTokens() == 0)
Craig Topper69186e72014-06-08 08:38:04 +00007308 return nullptr;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007309 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007310 Preprocessor &PP = Unit->getPreprocessor();
7311 if (!PP.getPreprocessingRecord())
Craig Topper69186e72014-06-08 08:38:04 +00007312 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007313 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
7314 Token Tok;
7315 if (PP.getRawToken(Loc, Tok))
Craig Topper69186e72014-06-08 08:38:04 +00007316 return nullptr;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00007317
7318 return checkForMacroInMacroDefinition(MI, Tok, TU);
7319}
7320
Guy Benyei11169dd2012-12-18 14:30:41 +00007321extern "C" {
7322
7323CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00007324 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00007325}
7326
7327} // end: extern "C"
7328
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007329Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
7330 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00007331 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007332 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00007333 if (Unit->isMainFileAST())
7334 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007335 return *this;
7336 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00007337 } else {
7338 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007339 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007340 return *this;
7341}
7342
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00007343Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
7344 *this << FE->getName();
7345 return *this;
7346}
7347
7348Logger &cxindex::Logger::operator<<(CXCursor cursor) {
7349 CXString cursorName = clang_getCursorDisplayName(cursor);
7350 *this << cursorName << "@" << clang_getCursorLocation(cursor);
7351 clang_disposeString(cursorName);
7352 return *this;
7353}
7354
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007355Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
7356 CXFile File;
7357 unsigned Line, Column;
Craig Topper69186e72014-06-08 08:38:04 +00007358 clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007359 CXString FileName = clang_getFileName(File);
7360 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
7361 clang_disposeString(FileName);
7362 return *this;
7363}
7364
7365Logger &cxindex::Logger::operator<<(CXSourceRange range) {
7366 CXSourceLocation BLoc = clang_getRangeStart(range);
7367 CXSourceLocation ELoc = clang_getRangeEnd(range);
7368
7369 CXFile BFile;
7370 unsigned BLine, BColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007371 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007372
7373 CXFile EFile;
7374 unsigned ELine, EColumn;
Craig Topper69186e72014-06-08 08:38:04 +00007375 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007376
7377 CXString BFileName = clang_getFileName(BFile);
7378 if (BFile == EFile) {
7379 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
7380 BLine, BColumn, ELine, EColumn);
7381 } else {
7382 CXString EFileName = clang_getFileName(EFile);
7383 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
7384 BLine, BColumn)
7385 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
7386 ELine, EColumn);
7387 clang_disposeString(EFileName);
7388 }
7389 clang_disposeString(BFileName);
7390 return *this;
7391}
7392
7393Logger &cxindex::Logger::operator<<(CXString Str) {
7394 *this << clang_getCString(Str);
7395 return *this;
7396}
7397
7398Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
7399 LogOS << Fmt;
7400 return *this;
7401}
7402
Chandler Carruth37ad2582014-06-27 15:14:39 +00007403static llvm::ManagedStatic<llvm::sys::Mutex> LoggingMutex;
7404
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007405cxindex::Logger::~Logger() {
Chandler Carruth37ad2582014-06-27 15:14:39 +00007406 llvm::sys::ScopedLock L(*LoggingMutex);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007407
7408 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
7409
Dmitri Gribenkof8579502013-01-12 19:30:44 +00007410 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007411 OS << "[libclang:" << Name << ':';
7412
Alp Toker1a86ad22014-07-06 06:24:00 +00007413#ifdef USE_DARWIN_THREADS
7414 // TODO: Portability.
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007415 mach_port_t tid = pthread_mach_thread_np(pthread_self());
7416 OS << tid << ':';
7417#endif
7418
7419 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
7420 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
Yaron Keren09fb7c62015-03-10 07:33:23 +00007421 OS << Msg << '\n';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007422
7423 if (Trace) {
Zachary Turner1fe2a8d2015-03-05 19:15:09 +00007424 llvm::sys::PrintStackTrace(OS);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00007425 OS << "--------------------------------------------------\n";
7426 }
7427}